So I have a PolyData object of lines generated from extracting feature edges from a 2D unstructured grid and then cutting out portions of the feature edges I didn’t want.
In my example, the original grid was just a square, so the feature edges would equally just be a square. Then I “extracted” out one side of the square. I would like to have the points of this PolyData object be in the order of the line, as currently they are more-or-less random.
From this definition on the VTK examples website, maybe the solution would be to convert the PolyData to a PolyLine? I can’t find any obvious path to achieve this though.
I tried setting strip.SetJoinContiguousSegments(False), but this did not change anything. It’s not a deal breaker by any means, but it would be nice to preserve the cells/lines.
If the polygon is self-intersecing then you can split it to non-intersecting polygons, determine the winding direction for each polygon, and then merge the polygons.
yes, you can compute the winding direction of each loop and reverse the point IDs order based on its sign, e.g.
data = np.asarray(points)
datamean = data.mean(axis=0)
pts = data - datamean
res = np.linalg.svd(pts)
dd, vv = res[1], res[2]
n = np.cross(vv[0], vv[1])
v = np.zeros_like(pts)
for i in range(len(pts) - 1):
vi = np.cross(pts[i], pts[i + 1])
v[i] = vi / np.linalg.norm(vi)
ns = np.mean(v, axis=0) # normal to the points plane
if np.dot(n, ns) < 0:
n = -n
the less trivial part is the triangulation i guess… (you may consider some non linear 2d map projection…)
@marcomusy’s answer uses NumPy for performance critical operations (e.g. singular value decomposition), if that is your concern. And certainly the for loop can be avoided by vectorized calls to the cross product and the vector norm. NumPy is supposed to be a decent alternative to its Matlab equivalents. Vectorizing NumPy functions normally takes the standard of telling it how to iterate over the vectors according to how they are arranged in a matrix (e.g. np.linalg.norm(x, axis=1) if you have the point data as row-vectors). See this: python - How to apply numpy.linalg.norm to each row of a matrix? - Stack Overflow . The cross product function likely follows the same rationale.
Your problem is not truly 3-D. Your data are locations on the Earth, so working with their XYZ positions is an unnecessary complication. I strongly recommend working with lat-long polar values or use some projection suitable for world maps (e.g. Mercator) if you want to work with Cartesian coordinates.
You can convert XYZ absolute postions to polar coordinates with this example: python - Faster numpy cartesian to spherical coordinate conversion? - Stack Overflow . The first solution is a vectorized (loop-free) example. Just throw away the radius (will be constant for points in the surface of a sphere) and you’ll reduce your problem to 2D.