How can I detect if two polygons have the same shape? - math

I would like to check if two polygons (number of vectors unclear) have the same shape. Without rotations this is easy, but how do I do this with rotated polygons? I need to know the rotation angle, too.
boolean polygonsHaveSameShape(PVector[] polygon1, PVector[] polygon2){
…
}
float getRotationAngle(PVector[] polygon1, PVector[] polygon2){
…
}

With a small number of vertices it might be worth checking the distances between each vertex and the others.
In your square example dist(p1,p2), dist(p1,p3), dist(p1,p4), dist(p2,p3), dist(p2,p4) and dist(p3,p4). These values will exist for each polygon. There will be a point that has the same distance set as p1, and as p2, and so on.
Once you have a vertex in one polygon where all the distances connected to it are the same as those in the second polygon then you can use one of those lines to determine the angle of rotation.
Hope that made sense.

Related

Clipping and triangulating a triangle with a non convex polygon

I'm starting with a single 2D triangle that I want to clip with a (potentially) convex 2D polygon. It's not self-intersecting, but may 'keep' or 'discard' the intersecting area based on the winding order.
I want to end up with a triangulation, i.e. a list of n vertices and m triangles, defined by 3 vertices each, of the clipped region in 2D space.
What would be the easiest (for me as a developer), and what the fastest (in terms of computation) way to achieve this?
If I a right, you want to clip inside the polygon, i.e. get the intersection between the triangle and the polygon.
As the triangle is a convex shape, the Sutherland-Hodgman algorithm is appropriate and no too difficult to implement (https://en.wikipedia.org/wiki/Sutherland%E2%80%93Hodgman_algorithm).
Notice that if the intersection is not simply connected, the resulting polygon will be connected, with double edges joining the would-be parts. Some cleanup might be required.
After finding the intersection, you re-triangulate using the ear-clipping method or a more efficient one (https://en.wikipedia.org/wiki/Polygon_triangulation).
Alternatively, you can triangulate the polygon and perform the clipping of every triangle with the original one.
The triangle-triangle clipping problem is again solved with Sutherland-Hodgman, somewhat simplified as the input polygons have a constant size, and their intersection is convex and at worse an hexagon. Trigulation of a convex polygon is immediate.

How to fix non-coplannar polygons?

I have a 3-D object described by surface facets. It is saved as OFF file. However, some of the vertices in a surface facet (polygon) are not exactly coplannar. Is there any good idea to fix these non-coplannar polygons to let them become coplannar?
My idea is
1) for every polygon, find the base plane of the polygon that most vertices fall into the plane, for example, the distance of vertex to the plane is less than machine precision (but how to find this base plane?);
2) for these vertices that are not fall into the base plane of the polygon, find the intersection of vertex's associated polygons' base planes and take it as the new location of this vertex.
Is there any problem? Do you have any better idea?
Thanks,
Tang Laoya
Maybe you should concentrate on fixing quadrilaterals, and repeat that over and over. Say two adjacent triangles have vertices abc and cbd, sharing edge bd.
Compute the volume of the tetrahedron abcd, and if it is small, decided to flatten. Or, maybe better, compute the dihedral angle at bd and flatten if
near pi; yes, that is probably a better measure.
Once you decide you would like to repair abcd, project d to the plane determined by abc, and replace d with that projected point. Now abcd are coplanar. You could do this for all the permutations and replace the point that moves the least.
Unfortunately, it seems this is order-dependent and could lead to cycles when
repeated over and over on all pairs of triangles.

Vector direction equations

I have three vectors in 3D space, one is a light source, one is a ray and one is the point on a circle a ray hits. With this information, how can I work out the vector which points back at the light source from the point the ray hits the circle?
What you really have is two points (light source, circle intersection), and a vector between them, right? The vector is already implied by the two points -- it's the intersection coordinates minus light source coordinations. To reverse it, just negate all the coordinates of the vector!

Determining the cut of any given polygon and pyramid

I am trying to implement in C++ a function that determines the cut of any given polygon and pyramid.
This has actually turned out to be far simpler than I had first imagined.
Firstly for each edge of the pyramid, test line-plane intersection (the given polygon is a plane, made up of 3 points). This will result in the new vertices at the cutting plane.
Secondly, since the polygon is not an infinite plane one needs to test for line-line intersection between the polygon edges (three) and each of the edges.
Indeed, this is not a simple problem. For simplicity, let's assume that there are no parallel line segments.
First determine the plane where your convex polygon is in. Then detemerine the intersection of that plane with the pyramid. This results in a second convex polygon.
Now you should find the intersection of the two convex polygons. How this can be done, you can find here.

How to compute a pair of closest points on two 3d circles?

I have two 2d circles in 3d space (defined by a center, normal, and radius) and I'm trying to come up with a pair of points that is one of the set of closest pairs of points. I know that there are anywhere from 1 to an infinite number of point pairs, I just need a single matching pair.
Is there a simple way to do that? Precision is not essential. The radius of both circles are the same, non-zero value.
In case the background is helpful, my overall algorithm takes in a NURBS curve in space and extrudes a 2d polygon along the curve, yielding a deformed cylinder. I just sample several points along the curve. The normal of each circle is the NURBS curve tangent, and I'm trying to figure out how to align adjacent samples, so I don't get weird twisting. It seems that the closest points on adjacent samples should be aligned.
Thanks for all the responses here.. this part of the project got a little delayed, which is why I haven't tested all the answers yet. I'll be sure to toss up some images here and mark an answer when I get to work on this again.
What you are really trying to compute is the pair of points that minimizes the distance between points that lie on 2 different circles in 3 dimensions. The method that you should be employing to find the exact solution (as in almost all optimization problems) is to represent the distance as a function of all possible points and to take its derivate with respect to the independent variables and set the resulting expressions to 0. Since you have 2 circles, you will have 2 independent variables (ie. the angle of a point on one circle and one on the other circle). Once you have solved the minimization equations you would have also found the points on the circles that will satisfy your constraint. (Basically you will find the angles on the circles for the pair of points you are looking for.)
I have found a paper online (at this site) that rigorously goes through with the calculations but the end result is solving an 8th order polynomial equation. You might try to simplify the equations and come up with a less exact solution that satisfies your needs.
There is also an paper that claims to have a much faster algorithm for finding the distance between two circles in 3d; however, I cannot view the contents and, thus, cannot tell if it also gives you the pair of points that satisfy that condition.
UPDATE: Having re-read your question, I see that even though you are asking for a way to find the closest pair of points on two circles in 3 dimensions, I think, you should pay more attention to the properties of the NURBS curve that you are trying to extrude the 2D polygon along. You mention that the orientation of the circle at a given point on the curve is specified by the tangent vector at that point. However, there is more to 3D curves than just the tangent vector; there is the normal (or curvature) vector that points towards the center of curvature of the curve at a given point and then there is the torsion vector that basically specifies the amount of "lift" of the curve from the plane given by the tangent and the normal vectors. All of these define a (what is called) Frenet frame. You can read up more on these at the Wikipedia article.
My suspicion is that you can achieve the effect you desire by joining the points of consecutive circles that each lie along the the normal vector direction of the underlying 3D curve. That way, you will have twisting only when the curve is actually twisting, ie when the torsion vector is non-zero and the normal vector is changing direction as well. In other circumstances, this should satisfy your actual need.
You probably don't need the overkill of finding closest points on consecutive circles.
For what you describe, it is sufficient to select a point on the perimeter of the first circle and find the point on the perimeter of each circle along that is closest to the one selected for the previous circle; this will completely constrain the polygonization, with no twisting, and should be much easier to solve than the general case - simply find the point on the plane containing the second circle that is closest to that selected in the first, and intersect the line passing through that point and the second circle's center with the second circle's perimeter.
However, this might not yield as pleasing a polygonisation for the extruded cylinder as keeping the polygon area constant as possible, and to do that will require some twisting between adjacent circles.
Yikes, unless the circles happen to be on the same plane or parallel planes I think the only way to do it is to find a minimum on the equation of the distance between two points on the circle.
http://www.physicsforums.com/showthread.php?t=123168
That link shows how to get the equation of each circle in 3D space, then minimize for the distance formula between those equations. Not pretty though, hopefully someone will come up with something more clever.
I think with the two closest points you might still get weird twisting... An extreme example: Let's assume both circles have the R=1. If the first circle's centre is O, and it is sitting on X-Y plane, and the second circle's centre is sitting at X=1,Y=0,Z=0.01, and it just slightly tilted in the growing direction of X, the closest points on the two circles will for sure get the "weird twist" you are trying to avoid. Since the closest points would not get you the weird twist in case the second circle is at X=0,Y=0,Z=0.01 and is equally tilted, then at some point the statements "aligned to two closest points on two circles" and "no weird twisting seen" no longer correspond to each other.
Assuming this can happen within the constraint of NURBS, here's another idea. In the start, take the three points on the NURBS curve - two that belong to the centers of your circles, and the third one precisely inbetween. Draw a plane between the three. This plane will cross the two circles at 4 points. Two of these points will be on the same "side" of the line that connects the centers of the circles - they are your alignment points.
For the next alignment points you would take the alignment point of the "previous circle", and draw the plane between the center of the "previous circle", this alignment point, and the center of the "new circle". From this you get the "next alignment point" based on the intersection with the other circle.
Next step - "previous circle" = "new circle", and the "new circle" - your next one according to the NURBS curve.
If the radii from the centers of the circles to the selected alignment points cross, you know you the picture will look a bit ugly - that's the scenario where with the "closest point" algorithm you'd still get the weird twisting.
I think the coordinates of the point on the circle that is intersection with the plane going via its center should be easy to calculate (it's a point on the line made by intersection of the two planes, one of the circle and the target plane; at the distance R from the center).
I don't have the rigorous proof to fully assert or deny the above - but hopefully it helps at all, and I think it should be quick enough to verify, compared to calculating the closet points on the two circles... (If there are any flaws in my logic, the corrections in the comments are very welcome).
The thread here, mentioned in another answer gives the parameterization formula for a 3D circle: P = R cos(t) u + R sin(t) nxu + c, where u is a unit vector from the centre of the circle to any point on the circumference; R is the radius; n is a unit vector perpendicular to the plane and c is the centre of the circle, t goes from 0 to 2pi, and by nxu I mean "n cross u". Parameterize one circle this way, and another similarly with a different parameter, say s. Then each point Pt on the first circle will have coordinates in the variable t, and each point Ps on the second circle will have coordinates in the variable s.
Write the distance function d(s,t) between Ps and Pt in the usual way (or better, the square of the Euclidean distance so you don't have to mess with the square root when you take derivatives). The graph of this function d of two variables is a surface over a 2pi by 2pi square in the s,t plane, and it's minimum is what you're after. You can determine it with the standard calculus methods, e.g. as explained here.
Extend the circles to planes (using the center points and normals). If the planes are parallel, then any points will do. If the planes are not parallel, then they intersect in a line. Construct the plane through the two centers of the circles perpendicular to the line. The two circles intersect this new plane in four points. These four points are the two nearest points and the two farthest points on the circles.
Isn't this just a matter of constructing the line between the two centers of the circles/spheres and finding the intersection of the line and the circles? The solutions that are closest are it (unless the circle intersect, then the answer depends on how you want to interpret that case).

Resources