Short version:
Given: Vertices of a convex 3d-Polygon
Looking for: The edges connecting the vertices, s.t. the Polygon is convex.
Long version:
I started with a bunch of 3d-points and calculated the voronoi tessalation using this function from the scipy.spatial package. I'm actually are looking for the right edges to get the polygons created by it, but I do not understand how the package does it.
At the moment I just figured out how to get the vertices and to which polygon they belong, but knowing the vertices of a polygon alone would not be enough to recreate it unless I'd get the edges. So how do I get them? Is there maybe a simple way to do it or even better: a package which does it for me?
Since I know it must be convex I had an idea for the 2d-case (basically just circling around the centre (the mean) of the polygon and connecting the vertices following each other), but I don't know if this approach would work in 3d or if it would even create a convex polygon. I also think this approach would be probably not reliable and/or take a lot of time to compute.
I can supply code if wanted, but I don't think it would help.
Thanks bb1 for the answer :)
scipy.spatial.ConvexHull does the job. (Technically it didn't work 100%, but I think that might be a different problem which occurs in 3d.)
Related
I currently have 2 paths generated by a motion planning algorithm in Python. I interpolated into two 3D Polylines with equidistant points. Next I need to find whether these two paths of different lengths intersect (OR even ideally the point(s) at which they get near a certain distance of each other, if any). This is to eventually simulate a collision avoidance algorithm.
After much searching I have found multiple libraries and algorithms that can return points/line intersections of two Polylines, however they are all in 2D. I tried using the Bentley-Ottmann algorithm/python library, the Shapely library, the Geometry3D library, and other 2D solutions found on SO, but none have worked in a 3D environment. Next I tried using a 2D geometry library to find the intersections in the x-y, x-z, and y-z planes individually as shown in the graphs below showing a simple case, but I'm not sure where to go from there or whether that's even the right approach. The Polylines would usually contain 300+ points.
Any help pointing me towards a 3D algorithm or simple adjustments to make to the 2D libraries work in 3D would be really appreciated!
3D graph view, x-y view, z-y view.
TLDR: I need to construct a python object for fast interior point testing, similar to a SciPy ConvexHull or DelaunayTriangulation. The catch is that I know ahead of time the order in which the triangulation of the points must be constructed: (6 points, 8 triangular faces, with a specific ordering of each face). In effect, I already know what the convex hull should be, but I need it in a form that I can use with existing (and optimised!) libraries (eg Scipy spatial). How can I do this?
Context:
I need to construct a triangular prism (imagine a Toblerone bar - 2 end faces, 6 side faces, all triangular) in order to do some interior point testing. As I will have many such prisms lying adjacent to each other (adjacent on their side faces, imagine many Toblerone bars stood on their ends and next to each other), I need to be careful to ensure that no region in space is contained by two adjacent prisms. The cross section of the prism will not generally be uniform, hence the possibility of overlap between adjacent prisms, as illustrated by this diagram of the approximately planar face between two adjacent prisms:
____
|\ /|
| \/ |
| /\ |
|/__\|
Note the two different diagonals constructed along the face - this is the problem. One prism may split the face into two triangles using the \ diagonal, and the neighbouring prism may instead use the /. In order to ensure no overlap between adjacent prisms, I need to explicitly control the order in which the triangles are formed so that they always use the same diagonal. This I can do: for each prism that I need to construct, I know ahead of time in what order the triangular faces should be constructed. Here's an illustration of two adjacent prisms, with the correct shared diagonal between them: neighbouring prisms, shared diagonal
My issue is with performing fast interior point testing with these prisms. Previously, I was using the approach linked in this answer: Delaunay(prism_points).find_simplex(test_points) >= 0. It's quick because it is using highly optimised library code, but I have no control over the construction of the triangulation, so there could be overlap.
If I construct the hulls as explicit np.array objects (vertices, faces) then I can use my own code to do the tests (there are numerous possible approaches, I'm projecting rays and testing for intersection with each triangular face). The problem is that this is around ~100x slower than the find_simplex() approach mentioned earlier. Whilst I'm sure I could get the code a bit quicker, it is worth pointing out this code is already fairly optimised from another use case with Cython - I am not sure if I can find all the extra speed I need here. As for the inevitable "do you really need the speed question", please take my word for it. This is turning a 5 minute job into many hours.
What I need is to construct an object I can use with external optimised libraries, whilst retaining control of the triangular faces. Adding extra Cython to my code is of course an option, but which such highly optimised code already out there, using that would be vastly preferable.
Thanks to anyone that can help.
Half a solution... Not an exact solution to the original question, but a different way of achieving the same outcome. Any triangular prism can be split into exactly three tetrahedra (see http://www.alecjacobson.com/weblog/?p=1888). This is a specific case of the fact that any polyhedron may be split into tetrahedra by connecting all faces to one vertex, if the faces does not already include it.
Knowing exactly how I would like the face triangles of my prism to be arranged, I can work out what three tetrahedra would reproduce the same configuration of triangles (with extra faces of course being added inside the original prism itself). I then form Delaunay triangulations around each of these three tetrahedra (ie, collections of 4 points) in turn and perform the original interior point tests: if it matches on any then I have a positive result for the whole prism. The key point is that by only giving four points to the Delaunay constructor at a time, I know exactly what triangulation it will return as there is only one way of forming such a tetrahedra (assuming no geometric degeneracy).
It's a bit longwinded, and involves 3x as many tests as I would like, but it's a start. If anyone in the future does know how I could do this better please do let me know.
I need help in python coding an algorithm capable of detecting the corners of a image. I have a thresholded image so far and I was using cornerHarris from opencv to detect all the corners. My problem is filtrating all those points to output only the ones I desired. Maybe I can do a loop to achieve this?
In my case, I want the two lowest corners and the two highest corners points. My main interest is to obtain the pixel coordinates of this corners. You can see an example of a image I'm processing here:
In this image I draw the corners points I'm interested in.
There are several ways to solve this problem. In real-world applications it's rare (that is, actually never occurs) that you need to solve a problem once for a single image. If you have additional images it would be nice to see how much the object of interest varies.
One method to find corners is the convex hull. This method is more generally used to find a convex shape encompassing scattered points, but it's worth knowing about and implementing.
https://en.wikipedia.org/wiki/Convex_hull
What's handy about the convex hull is that the concept of a "corner" (a vertex on the convex hull polygon) is easy to grasp and doesn't rely on parameter settings. You don't have to consider whether a corner is sharp enough, strong enough, pointy enough, unique in its neighborhood, etc.--the convex hull will simply make sense to you.
You should be able to write a functional version of a convex hull "gift wrapping" algorithm in a reasonable period of time.
https://en.wikipedia.org/wiki/Gift_wrapping_algorithm
There are many ways to compute the convex hull, but don't get lost in all the different methods. Choose one that makes sense to you and implement it. The fastest known method may still be Seidel, but don't even think about running down that rabbit hole. Simple is good.
Before you compute the convex hull, you'll need to reduce your white shape to edge points; otherwise the hull algorithm will check far too many points. Reducing the number of points to be considered can be done using edge-finding on the connected component (the white "blob"), edge-finding without first segmenting foreground from background, or any of various simple kernels (e.g. Sobel).
Although the algorithm is called the "convex" hull, your shape doesn't have to be convex, especially if you're only interested in the top and bottom vertices/corners as shown in your sample image.
Corner finders can be a bit disappointing, frankly, especially since the name implies, "Hey, it'll just find corners all the time." There are some good ones out there, but you could spend a lot of time investigating all the alternatives. Even then you'll likely have to set thresholds, consider whether your application will yield the occasional weird result given the shape and scale of corners, and so on.
Although you mention wanting to find only the top and bottom points, if you wanted to find those two odd triangular outcroppings on the left side the corner-finding gets a little more complicated; using the convex hull keeps this very simple.
Although you want to find a robust solution to corner detection, preferably using a known algorithm for which performance can be understood easily, you also want to avoid overgeneralizing. In any case, review some list of corner detectors and see what strikes your fancy. If you see a promising algorithm that looks easy-ish to implement, why not try implementing it?
https://en.wikipedia.org/wiki/Corner_detection
I have a function whose range is a non-convex, simply connected region in R3. When I sample the function I know if the resulting point is on the surface of the region or not. I'd like to triangulate those samples subject to the surface constrains, i.e., the resulting tetrahedra should not
"hide" surface points. The hull would not be convex, of course.
I searched around for a library. So far I found Triangle, but it only works in R2. I also found TetGen, which works in R3, but it requires to provide
the surface triangulation (which I don't have). Also, as far as I can see, these C/C++ libraries do not have Python bindings.
Any suggestions? Thanks!
You may take a look at CGAL it has python-bindings.
One side note: If you need the surface triangulation (which seems to be a 2D problem), you may take each face, project it to 2D, triangulate it, and back to your 3D face.
EDIT due to comment: CGAL does "only" 3D triangulation. 3D constrained triangulation requires Steiner points. Since not every input can be triangulated in 3D (Schönhardt polyhedron as the classical counter-example).
Maybe you can take a look at MeshPy it looks like it has what you are looking for: "MeshPy provides Python interfaces to three well-regarded mesh generators, Triangle by J. Shewchuk, TetGen by Hang Si, and gmsh by Christophe Geuzaine and Jean-Francois Remacle."
I would like to find the rotation and location for a polygon that maximizes how large it can be scaled up within the constraints of fitting within a larger polygon.
Current idea is to use scipy optimization routines for optimizing position and rotation parameters to maximize the scaling parameter, and shapely to add a constraint that the polygon is contained. This seems like it'll be slow and not particularly elegant.
Other ideas?
This problem sounds like it might be NP-Hard. Given a candidate solution you can't really be certain that it is the best solution. It seems like you'd need to try to use some sort of incremental randomized search.
If the internal polygon is maximally scaled, then there are at least 4 pairs "internal vertice - external edge" or "external vertice - internal edge" where the vertice is on the edge.
Let's take all 4s of vertice-edge pairs. For every one we get the system of linear equations for two reference points' coordinates. If it has one solution, we verify that there are no intersections and if OK we remember the coordinates and size of the internal polygon.
This is an exact solution, but it's slow. On the other hand, scipy optimization routines are likely to find a local maximum which is not the global one.