Given a set of points in three dimensional space, e.g. as a numpy array of shape (n, 3) where the second dimension encodes the x, y and z coordinates for each point in the pointcloud, I know that I can find its convex hull using scipy.spatial.ConvexHull.
What I would additionally like to do is obtain the vertices of a two dimensional polygon that describes the cross-section of this convex hull at an arbitrary value of z.
This seems to me like it should be computationally feasible, is there python module which already implements this sort of thing?
Related
I need to create a 3D Spline (or NURBS, both would be possible as I can convert these internally) based on two 2D Splines (or NURBS). The two base Splines are on orthogonal planes in a 3D space.
Let's say, for simplicity, spline A is on the XY-Plane, spline B on the YZ-Plane.
Both splines start and end on the same Y coordinate but do not share any points in between.
Image above: Two 2D Splines; Black on XY, blue on YZ. Shared Y coordinate for start and end point, different control points
How can I calculate the resulting 3D spline that is a merge of the two 2D splines?
Purple spline is the resulting 3D Spline.
If allways two spline control points of the 2D splines share the same Y coordinate, it is simple, the new point is the compound of the two old points, where
the new X cooridnate is the XY-Plane's spline X coordinate
the new Y cooridnate is any Y coordinate as they are the same
the new Z coordinate is the YZ-Plane's spline Z coordinate
If the spline control points do not share a common Y coordinate, it seems more difficult. Is there a library I can use to achieve that?
Hope I made my problem somewhat clear.
I have a given 3D mesh which is constructed by taking a set of random points and finding the convex hull of those points. I then use open3d and trimesh to convert the conex hull into a mesh. I want to know how I can convert this mesh or the convex hull itself into a filled boolean voxel grid.
I can use trimesh to get a voxel grid of some sort but it seems the insides are hollow. I want a boolean voxel grid which gives true for the volume inside the convex hull and false otherwise.
Simply rasterize your convex polygon volume ...
compute any inside point c
for convex hull its enough to compute avg point so sum all n points together an divide by n
compute per face normals
each triangle face has 3 points p0,p1,p2 so
nor = cross( p1-p0 , p2-p0 );
and chose direction so it points out of the convex hull so:
if ( dot( p0-c , nor ) < 0) nor = -nor;
loop through all voxels
so 3 nested for loops going through your grid. Lets call the actual iterated point q
test inside convex hull
the q is inside your convex hull if all dot products between q-face_point and face_normal is negative or zero... So loop through all triangles/faces and test... after that either fill the voxel or not ...
If you want something faster (in case you got too many triangles) there are ways like:
Rasterize the triangles and floodfill
Tetrahedronize volume and rasterize each tetrahedron separately
render depth maps from 6 sides of outscribed cube and infill
So I figured out a simple solution which can be implemented using trimmesh. The idea is to generate a large set of coordinates and query the mesh to determine if the coordinate is within the mesh/convex hull. If the coordinate is within the mesh it is indicated in the grid as 1 and 0 otherwise. res is an array that determines the resolution along x,y,z axis. A higher resolution provides much better representation of the mesh.
x, y, z = np.indices((res[0], res[1], res[2]))
total_voxels = np.product(res)
coords = np.concatenate((np.reshape(x/res[0], [total_voxels, 1]),
np.reshape(y/res[1], [total_voxels, 1]),
np.reshape(z/res[2], [total_voxels, 1])), axis=1)
out = mesh.contains(coords)
voxel = np.reshape(out, res)
Suppose we have some predefined positions statements in a 2d or 3d space (e.g. generated by a robot arm with the axis/joints x, y, z, a, b). How do we get any position statement (same format x, y, z, a, b) in between these points in Python (SciPy, NumPy, MatPlotLab, etc...)?
E.g. "What is the position statement for x = -2.5 and y = 152.8"
For better understanding, I have attached a small illustration of my problem.
Essentially, for your problem:
Calculate a bounding box that fits the given points.
Generate a random point in the bounding box.
If the random point is not in the convex hull of the given points, go to step 1.
For two-dimensional cases, if you know all the shapes you care about are convex, then this is relatively trivial: divide the shape into triangles, choose one of them at random based on their area, and generate a random point in that triangle. But for higher dimensions, this is far from trivial. In fact, the convex hull is likely to be much smaller than the bounding box with higher dimensions, so many points are likely to be rejected. And computing the convex hull itself may be complicated. This question's answers have some ideas on how to find if a point is inside a convex hull.
If you can accept approximations, you can also precalculate a number of points that are in the convex hull, then, each time you need a random point:
Choose one of the precalculated points at random.
Calculate a random point that's "close" to the chosen point (e.g., a point shifted by a normally-distributed distance in each dimension).
Clamp the random point by the bounding box.
This has the disadvantage that the random points will be as dense as the precalculated points, and not necessarily uniformly distributed.
I will have a 3-d grid of points (defined by Cartesian vectors). For any given coordinate within the grid, I wish to find the 8 grid points making the cuboid which surrounds the given coordinate. I also need the distances between the vertices of the cuboid and the given coordinate. I have found a way of doing this for a meshgrid with regular spacings, but not for irregular spacings. I do not yet have an example of the irregularly spaced grid data, I just know that the algorithm will have to deal with them eventually. My solution for the regularly spaced points is based off of this post, Finding index of nearest point in numpy arrays of x and y coordinates and is as follows:
import scipy as sp
import numpy as np
x, y, z = np.mgrid[0:5, 0:10, 0:20]
# Example 3-d grid of points.
b = np.dstack((x.ravel(), y.ravel(), z.ravel()))[0]
tree = sp.spatial.cKDTree(b)
example_coord = np.array([1.5, 3.5, 5.5])
d, i = tree.query((example_coord), 8)
# i being the indices of the closest grid points, d being their distance from the
# given coordinate, example_coord
b[i[0]], d[0]
# This gives one of the points of the surrounding cuboid and its distance from
# example_coord
I am looking to make this algorithm run as efficiently as possible as it will need to be run a lot. Thanks in advance for your help.
I have a list of vertices in 3d, in random order. I need to construct a polygon from them.
I've found a solution for this in 2d, that uses polar coordinates: ordering shuffled points that can be joined to form a polygon (in python)
It calculates the center of the shape, then arranges the vertices by polar coordinate. Problem is, in 3d there are 2 angles involved, if I use spherical coordinates. How do I sort my list of vertices in case of sphereical coordinates?
Are the points lying on a plane? First find the center, then use a vector cross product on the relative positions of a couple randomly chosen points to find the normal to the plane. Analyze the coordinates of the points relative to the center into components along the normal and perpendicular. The perpendicular components are a 2D problem, for which you've already found a solution.