Determining the cut of any given polygon and pyramid - polygon

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.

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 compute Voronoi tesselation based on manhattan distance in R

I am trying to compute a Voronoi tesselation in 2D with the Manhattan distance in R.
Ideally this would be a function that takes a set of two-dimensional points and outputs a list of polygons that partition the space. I am not certain what representations of Voronoi tesselations are standard.
There are of course many ways to do this with the Euclidean metric (packages like deldir and qhull make this very easy), but I haven't found a way to do this for the manhattan distance. A search using sos's findFn('voronoi') also yielded no results.
Info: taxicabgeometry.net
Interactive: Manhattan-metric Voronoi diagram(Click version)
I've been rolling my own in python, and can sum up the basics here:
Between neighboring centroids is a perpendicular line, in manhattan metric - two rays and a 45 degree diagonal most likely, if the centroids are randomly generated, but a straight horizontal, vertical, or 45 degree diagonal line may also occur. Given a set of such lines for every centroid pair, the edges separating the regions are among them. Collect intersect points of each pair of lines which are equal-distant (within an epsilon), in manhattan metric, to it's 3 nearest centroids. Also collect the two mid points of the 45 degree diagonal which are similarly equal-distant to their nearest two centroids. The outer polies won't be closed. How to deal with them depends on what you need. The poly borders and border verts will need sorting, so your polies aren't a zigzagged mess. Winding order can be determined if they should be clockwise or other. More can be done, just depends on what you need.
Unfortunately, this gets exponentially slower the more points are involved. The intersecting of every bisector to every other bisector is the bottleneck. I've been attempting an insertion method, with some success, but . Now I'm thinking to try first creating a nearest-neighbor linkage between the centroids. If the neighbors are known, the bisectors to intersect will be minimal, and many centroids can be computed quickly.
Anyway, the brute-force approach does work:
The point near the cursor is actually 2 points of a tiny diagonal. It's a precise method, but more complicated than it first seems. The java code from the interactive link above may be faster, but was difficult to get solid and precise geometry from.
Sorry, I dont know R.
Maybe the question is about finding the maximum area of a square that match inside a circumcircle (of a triangle). The equation for such a square abs(x)+abs(y)=r (www.mathematische-basteleien.de/taxicabgeometry.htm). When you have a mesh of triangles the voronoi diagram is the dual.

Line(s) Equidistant From Two Convex Polygons In 2D

Given two convex polygons in 2D space, how would you go about constructing the line segment(s ) which, at any point on the lines, is equidistant from the closest point of either convex polygon?
I'm looking towards an implementation of Voronoi diagrams for convex polygons instead of points, but I'm unsure how to even begin calculating the line for just two polygons. So I figured I'd take this one step at a time and start here.
Edit To try to make the question a little clearer, I want to bisect the plane (or a subset thereof).
Suppose we have polygon A on the left and polygon B on the right. There will be some line of bisection that divides the plane into points on the left and points on the right. Every point on the line is equally distance from either polygon. Every point left of the line is closer to polygon A than to polygon B. Every point right of the line is closest to polygon B.
Here's an image generated by a Matlab script I wrote that brute-forces an approximation:
The problem, I believe, is not as simple as examining the space in "between" the two polygons, since the line must extend beyond the area directly between the two shapes. And ideally I'd like to find a solution that generalizes to more than two shapes, which, to me, seems to complicate the problem a great deal more. Here's a (obviously very rough) approximation of how that might look:
Well, proceeding one step at a time I'd look at the closest points in the polygons themselves. Let's say a in A is the closest point to B and b in B is the closest point to A. You know the middle point of AB is in the desired segments.
What are the posibilities for a? It can be a vertex of A or it can be a point in one side. The same applies for b. What happens with the "equidistant-segments"? How to build them in each case?
Since those segments are equidistant to sides of the polygons, they have to be part of the line that bissects the angle of the lines containing the corresponding sides.
Am I understanding you correctly but assuming you're wanting the line that effectively bisects the space between 2 convex polygons? If so, then ...
find the line that joins the 2 polygons (P1 & P2)
find each polygon centre (P1.centre & P2.centre) by calculating the average X and Y coordinate.
find the vertex on each polygon that's closest to the other's centre (P1.vc & P2.vc)
given that P1.vc & P2.vc now define the line joining P1 & P2
find the midpoint (mp) of P1.vc & P2.vc
Bisecting line = perpendicular of the line joining P1.vc & P2.vc that passes through mp

Determine the correct solutions for three circles intersection

I have three intersecting circles with inaccurate radii. How can I determine three out of six intersection points which form the intersection area? I was initially thinking of simply getting the cluster points - points which have smallest distances between them. But since the radii are not always correct, there might be cases where the cluster points are not the points forming the intersection area. Any ideas?
For each pair of circles, find the two intersections (if they exist) on their boundary. Then test to see if one of these points is inside the third circle (distance to the center less than the radius of that circle).
This will identify the three "corner" points of the region of triple intersection, at least when such an intersection exists.
By the way, the intersection of two circles is really more of a linear problem than a quadratic one, properly approached.

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