I have a list of 8 points given by their coordinates (x, y, z).
These 8 points are the 8 vertices of an hexahedron, which means that there are 6 faces which are quadrilaterals; the 4 points on each face are guaranteed to be coplanar.
I want to sort the list of points in a particular order:
the first 4 points must be on the same face, and in counterclockwise order;
the next 4 points must be their corresponding points on the opposite face.
Example:
I found similar question asked, but this algorithm fails on this example hexahedron:
I also have an idea to sort points in direct way by finding points in the same plane, then the other point in this plane, then point on same edge and etc.
But is there any easier way to order these points?
Related
Given set of 2D points find a triangle built from those points, that encloses the biggest number of points.
Brutal algorithm for this is just building triangles from every possible triad of points and checking how many points they enclose, but time complexity of this solution is O(n^4).
For the optimal solution I thought about first finding the convex hull of those points and arranging points inside this hull with some structure, but I can't figure it out.
Do you have any ideas about the optimal solution for this kind of problem?
In a set of n points, there are (n choose 3) triangles, and using brute force to check for each point whether it is contained in each triangle indeed has O(n4) complexity. To give a practical example of a few set sizes:
points: 100 1,000 10,000
triangles: 161,700 166,167,000 166,616,670,000
checks: 15,684,900 165,668,499,000 1,665,666,849,990,000
Below are a few geometrical ideas; they don't lead straight to a solution, but they can reduce the number of triangles that have to be checked.
Counter-example for convex hull
First of all, using only points on the convex hull is not guaranteed to give the optimal solution. Consider this counter-example:
The convex hull is the red rectangle. However, if we use two of its sides and a diagonal to form a triangle, the diagonal will cut through the central point cluster and leave out some of the points. And even if we only use 1 or 2 corners of the rectangle, combined with a point in the center, it will always cut through the blue triangle and leave out some points. The blue triangle, which has no points on the convex hull, is in fact the optimal solution.
Triangle contained in triangle
If you consider a triangle abc, and three points d, e and f contained within it, then the triangle def cannot be the triangle which contains the most points, because triangle abc contains at least three more points. Triangles made from a combination of points from abc and def, like abd, also contain fewer points than abc.
This means that finding a triangle and some points contained within it, allows you to discard a number of triangles. In the next paragraphs, we will use this idea to discard as many triangles as possible from having to be checked.
Expanding a triangle
If we consider a triangle made from three randomly chosen points a, b and c (named clock-wise), and then check whether all other points are on the left of right side of the lines |ab|, |bc| and |ca|, the points are partitioned into 7 zones:
If we replace a corner point of the triangle by a point in the adjacent coloured zone, e.g. zone LRL for point a, we get a larger triangle that contains triangle abc. If we randomly pick three points from zones LRL, LLR and RLL, we can expand the triangle like this:
We can then partition the points again using this new triangle a'b'c' (points already in zone RRR can be added to the new zone RRR without checking) and expand the triangle again as long as there is at least one point in the zones LRL, LLR or RLL.
If we have caught enough points inside the expanded triangle, we can now use the brute force algorithm, but skip any triangle which doesn't have a point outside of the expanded triangle a'b"c'.
If we haven't caught enough points to make that feasible, we can try again with another three random points. Note, however, that you should not use the union of the points contained within several triangles; three points which are each contained in another triangle, but not in the same triangle, can still be the triangle containing the most points.
Excluding triangles in multiple steps
We could repeatedly choose a random triangle, expand it maximally, and then mark the triangles made from three points on or inside the triangle, to then exclude these from the check. This would require storing a boolean for all possible triangles, e.g. in a 3D bit array, so it is only feasible for sets up to a few thousand points.
To simplify things, instead of expanding random triangles, we could do this with a number of randomly chosen triangles, or triangles made from points on the convex hull, or points far apart when sorted in the x or y-direction, or ... But any of these methods will only help us to find triangles which can be excluded, they will not give us optimal (or even good-enough) triangles by themselves.
I have a volume mesh which is actually a tetrahedral mesh. I would like to calculate the cross-section of this mesh given a plane function, saying z = 0. I can imagine that the cross section of a tetrahedron is either a triangle or a quadrilateral. For the first case, triangle, once I calculate the 3 cross points I can get it; but for the second case, how can I make the quadrilateral become 2 triangles? My problem is I cannot determine the diagonal of the quadrilateral.
Intersect all tetrahedron edges by the plane. You will get 3 or 4 intersection points.
If 3 points then a single triangle.
If 4 points, they form a convex quadrilateral. Take any 3 points, that form a first triangle. The other triangle if formed of the fourth point and the two endpoints of the edge that has this point to its right.
Alternatively (for a more general solution), tag the intersection points with the indexes of the faces incident on the edge, and reconstruct the ring of labels.
Ex: edges are common to faces AB, CD, DA and BC; then the section is ABCD.
This answer outlines a general volume-plane intersection algorithm. It will return the vertices of the intersection in order, so it's easy to determine the diagonal of your quadrilateral.
the polygons image
All of the polygons are simply, there are no holes in them.
board polygon(P0 to P7)
Red polygon (R0 to R6)
Green polygon (G0 G1 P2 G3)
Yellow polygon(Y0 to Y3)
I want to got new four polygons marked as 1 to 4 , polygon 1's coordinates are(J7 J10 R5 R4).
When I use polygon clipping algorithm, I can got the results easy , board diff(red union green union yellow). But when I have more than 10,000 polygons, I need a long time to get my results. My polygons are simply and my result polygons are simply also, there are no holes in the result polygons also.
You know I can find out the four polygons form the image easy using eyes, but how to find them using algorithm.
Thanks.
If all vertices of your computed black polygons do not have more than 2 edges intersecting at the vertex, then there may be a faster way than a more general tool.
Since the number of polygons is on the order of 10000, first try computing the intersection points of all pairs of polygons, and hopefully the number of intersection points is small enough (like 10 million or less). Then, for each intersection point test to see if it is contained in the interior of another polygon (in case you have multiple polygons that jointly overlap). Testing to see if a point is contained in the interior of a polygon can be done quickly, you can read how online. Then, all intersection points that are not contained in another polygon, which note also contains all the original polygon vertices that are not contained in the interior of a polygon, these are the vertices for the "black" polygons you want to compute. These points should be stored with a secondary structure that for each polygon edge, it stores all the stored intersection points along that edge, in sorted order. Similarly, for each stored vertex and intersection point you should store the edges that intersect at that point, and the location of the intersection point in the previous structure. So then pick any stored intersection point that hasn't been used yet in a black polygon, and pick one edge that defines the intersection point. Then you move to the neighboring intersection point along the edge which has the property that the part of the edge between the two intersection points does not pass inside a polygon. Then continue by similarly moving along the other edge that defines the neighboring intersection point. Continue until you reach the vertex you started at; this defines one black polygon. Then you can pick a new unused stored intersection point and repeat. Since your polygons have no holes, this will find all black polygons.
I have a set of e.g. 8 points. I know all distances between each points. Is there an algorithm to reconstruct the 3d coordinates of those points.
What you are try to do is called Trilateration. It might be wise to do a bit of research before you proceed, as it's tricky to get right. However, I'll start you off with the following.
The following should work, as long as you have the actual 3D distances. Problems may come up if you don't.
Take a point, p1, and assign it to be the origin, (0,0,0).
Take another point, p2, and place it at (distance(p1,p2),0,0)
Take another point, p3, and place it on the (x,y,0) plane based on it's distance from p1 and p2.
Take another point, p4, and place in 3D space, based on it's distance from p1, p2, p3.
Repeat step 4 until no points remain.
The first 3 steps are enough to orient and fix the coordinates.
Solving steps 3 and 4 can be done by making use of planar triangles, that form easily due to how the points are centered.
Let assume that points are in a general position. That no 3 points are on a same line, and no 4 points are on a same plane. It isn't a restriction, just to make algorithm simpler without checks for a special cases.
Intersection, if exists, of four spheres (in a general position) is a single point. It can be seen since intersection of two spheres is a circle, intersection of three spheres are 2 points, and if center of forth sphere isn't on a plane with centers of other 3 spheres, that sphere can pass only through one of intersection points.
So, if distances are valid, than shape can be created by incremental adding points to it.
Position on first 4 points defines orientation. E.g. first point set in origin, second point set on +X on given distance to first, third point set in XY plane in +Y direction on intersection of circles, and forth point set in +Z direction on intersection of 3 spheres.
Additional points can be positioned by intersection of 4 spheres with centers in first 4 points and radii given by distances to them.
An other possibility is the metric Multidimensionale Skalierung.
How to link four points to a convex polygon? I mean how to identify the order of these four points.
Thanks.
Zhong
Take the center point (i.e. average of x and y coords), then calculate x/y values for y<centery, then for y>=centery. would be fastest I guess.
(that is, if I understood the question in the first place...)
Sort them vertically, connect 2 top most to each other and two lowest to each other.
Sort horizontally and then connect 2 leftmost to each other and two rightmost to each other.
EDIT: anyways, SO's cool related section on the right suggests an answered duplicate:
Sort Four Points in Clockwise Order
The atan2() method is handy for this, and is found in most languages.
atan2(y,x) and converts rectangular coordinates (x,y) to the angle theta from the polar coordinates (r,theta).
Given 4 points, find their average. Then calculate the four (x,y) vectors obtained by subtracting the average from each of the four points.
For each of these (x,y) vectors, calculate the angle θ = atan2(y,x). θ will be between -π/2 and π/2.
Sort the θ's. This will give you the order of the points, in clockwise order.
This only works for convex quadrilaterals.