Centroid of a set of points in Python - python

I have a set of coordinates (x,y) and im trying to write a function that generates the centroid of them, so far I keep getting errors, here is the code I have so far:
def get_centroid(x,y):
centroid = (sum(x)/len(x),sum(y)/len(y))
x=[3,1,5,7,4,-2]
y=[0,-3,-3,1,5,2]
thank you for any help or suggestions.

Your approach will work, but just remember to return your result and be careful of dividing by zero with empty lists.

Related

Obtaining a vector of coordinates from a vector of indexes from a point cloud

I was tinkering around with open3d and I got to the point where I found myself having a vector made from the index of each point I got from a radius search and it looks somewhat like this:
[1500, 1497, 1509, 1503, 1499, 1555, 1557, ... , 1565]
I would like to create another vector made with the coordinates of each point in that list, knowing that I can obtain a points coordinate by doing this:
pcd.points[index]
The final result would I want to achieve would look somewhat like this:
[[0.65234375 0.84686458 2.37890625],
[0.65234375 0.83984375 2.38430572],
[0.66737998 0.83984375 2.37890625],
...
[2.00839925 2.39453125 1.88671875],
[2.00390625 2.39488506 1.88671875],
[2.00390625 2.39453125 1.88793314]]
I know this might be a basic question but I have been trying to get my head around this for a couple hours and I found myself to be blocked.
Now, if someone wants to get more context this is the code I am using right now
mesh = o3d.io.read_triangle_mesh("ModelNet10/chair/test/chair_0890.off")
pcd = o3d.geometry.TriangleMesh.sample_points_uniformly(mesh,5000)
pcd_tree = o3d.geometry.KDTreeFlann(pcd)
[k, idx, _] = pcd_tree.search_radius_vector_3d(pcd.points[1500], 2)
I would like being able to grab that vector that comes from the radius search and have the coordinate of each point from that radius search in a vector so I can work with it.
After banging my head against my monitor I found out that my answer was in front of my eyes but I was so stubborn in solving it a way I wasn't even able to think about I couldn't tell.
The only thing I needed to do is just
points = o3d.np.asarray(pcd.points)[idx[1:], :]
Just as I did for coloring each point.
Although I managed to get what I wanted I'd like to see any other useful answers or an actual optimal answer to keep learning. Thanks!

How to assign a pixel a value, then get that value's coordinates

I'm only a couple weeks into my IT degree and I'm trying to write a small program in Python, I've tried searching for a solution but my knowledge of terminology and concepts is probably limiting my results. Saying that, I'm trying to find out if it is possible to assign a value to a pixel in a random range, then get the x,y of that value and manipulate it. For example
import random
pic=makeEmptyPicture(500,500)
w=random.randint(0,getWidth(pic))
h=random.randint(0,getHeight(pic))
a=getPixel(pic,w,h)
for x in range(getX(a),getX(a+5),1): #this is where I'm stuck.
for y in range(getY(a),getY(a+5),1): #I need to get the x,y of "a"
#Do something #and manipulate it.
Thanks in advance.
The variables w and h are the (x, y) coordinates.
To manipulate that pixel, I would need to learn about your "picture" object.
First, see what kind of object makeEmptyPicture returns. Then look at that object to see if it had any useful functions.
pic = makeEmptyPicture(500, 500)
print("type: ", type(pic))
for var in dir(pic):
print(var)
If this isn't enough information, use Python's built-in "help" command.
pic = makeEmptyPicture(500, 500)
help(pic)
These might give you some good leads. If you're still stuck, post the results, and I'll help you.

Issues getting nodal coordinates Abaqus Python API

I am checking the elements beneath a surface for their labels & the coordinates of their nodes in the following code,
mySurf = mdb.models['Model-1'].rootAssembly.surfaces['Surf-1']
surfEls = mySurf.elements[:]
surfNodes = []
for eNode in mySurf.nodes:
surfNodes.append(eNode.coordinates)
This does something but when I check the sizes of each list then I get more element labels than I do sets of node coordinates!
I also tried the following to get the nodal coordinates,
surfNodes = mySurf.nodes[:]
surfNodesCoords = surfNodes.coordinates[:]
But this just throws up an error,
AttributeError: 'MeshSequence' object has no attribute 'coordinates'
Which I confess has dumbfounded me. Does anybody have a deeper understanding of the methods used above, who can explain this behaviour to me?
The problem is that the MeshSequenceObject does not have method 'coordinates'. However, a member of MeshSequenceObject may have this method, if sequence contains nodes. Just apply it to each member of the sequence:
surfNodesCoords = [Node.coordinates for Node in SurfNodes]
The latter will make the list with coordinates of all nodes.
P.S. The first part of the question is working fine. The number of nodes is bigger than the number of elements.

Abaqus Python getByBoundingBox command

I have a 2D part in Abaqus with many partitions and I therefore want to select many edges with the getByBoundingBox command to create a surface set. This is the bit of code I have:
p = mdb.models['Model-1'].parts['Plate']
s = p.edges
edges = s.getByBoundingBox((0,0.02,0,0.003,0.04,0))
p.Surface(side1Edges=edges, name='r1')
But it gives me the following error: "edges = s.getByBoundingBox((0,0.02,0,0.003,0.04,0)) TypeError: arg1; found tuple, expecting float".
Any advice much appreciated.
The corners of the bounding box should be provided as 6 separate numbers and not as a single tuple. The solution is very simple, just change the leading "((" and trailing "))" to single "(" and ")". So the call looks like this s.getByBoundingBox(0,0.02,0,0.003,0.04,0).
this comes quite late but in case anyone enters and has the same doubt:
When telling to Abaqus which edge/face/element you are actually selecting, sometimes you need to specify the "ID" of that object, that's why it's asking for a float instead of a tuple in the error message. This can be solved as:
You select the edge/face/node/element you want:
edge = s.getByBoundingBox((0,0.02,0,0.003,0.04,0))
Create a intermediate variable to know the "ID" of the element:
edge_id = edge.id
You now can refenciate it in the dialog for creating surfaces:
p.Surface(side1Edges=p.edges[edge_id], name='r1')
In this case, you're telling Abaqus to select the edge with the id "edge_id" from all the edges that your part "p" has.
This happens many times and you've to be aware what Abaqus is expecting from the code. Sometimes can be the object itselft, a tuple of elements or simply a float expressed as a tupple e.g: edge = (number, )
Regards
I tried the modified code on a 2D plate with the following code
p = mdb.models['Model-1'].parts['Plate']
s = p.edges
edges=s.getByBoundingBox(0,0,0,25,25,1)
And it does not crash. But its not really clear how you can create a surface using this. You need to use a different strategy to achieve what you want. You can find create a surface using the 'pointOn' method.

Python Pandas indexing

Sorry if this is a simple question, I've tried to look for a solution but can't find anything.
My code goes like this:
given zip1, create an index to select observations (other zipcodes) where some calculation has not been done yet (666)
I = (df['zip1'] == zip1) & (df['Distances'] == 666)
perform some calculation
distances = calc(zip1,df['zip2'][I])
So far so good, I've checked the distances variable, correct values, correct sized array.
put the distance variable in the right place
df['Distances'][I] = distances
but this last part updates all the df['Distances'] variables to nonsense values FOR ALL observations with df['zip1']=zip1 instead of the ones selected by I.
I've checked the boolean array I before the df['Distances'][I] = distances command and it looks fine. Any ideas would be greatly appreciated.
What you are attempting is called chained assignment and does not work the way you think as it returns a copy rather than a view hence the error you see.
There is more information about it here and related issues, this and this.
So you should either use .loc or .ix like so:
df.loc[I,'Distances']=distances

Categories