Clipping two 2D triangles - math

I know that there are efficient polygon clipping algorithms out there (e.g., Maillot, Vatti, Greiner-Hormann). However, these algorithms work for arbitrary polygons and although they fit my case, it seems to me that using such general algorithms for a simple case like mine is an overkill.
What I have is two 2D triangles (see figure below) that I want to clip the one against the other. Searching in the web didn't find anything apart from general polygon clipping algorithms.
Q: Is there a specialized algorithm for clipping two 2D triangles?

For two convex shapes the traditional approach is just Sutherland Cohen, but with more or fewer flags.
E.g. in your case:
blue A is outside red AB but inside the other two red edges; give it code 100;
blue B is the same; give it code 100;
blue C is outside red BC but inside the other two so give it code 010.
Starting from A:
code is non-zero, don't include blue A in the output;
looking at edge blue AB, the binary AND is non-zero so don't consider for output;
code for blue B is non-zero, don't include in output;
codes B and C AND to 0 so XOR* them. Gives 110. So find intersections of blue BC with edges red AB and BC, add them to the outpyt list;
code for blue C is non-zero, don't include in output;
codes for blue C and D again indicate to intersect with BC and AB so do so and add to output.
(* or OR them; we've established they share no bits in common so it makes no difference — I think XOR is a little more descriptive in saying that you're looking for differences)

Two methods, effective for convex polygons, are described here - Hoey's algorithm and O'Rourke's algorithm.
(I've used O'Rourke's one for convex quadrilaterals)

Just hints for optimization.
The complete discussion of which edges intersect and which vertexes belong to the final outline only depends on the algebraic areas of the triangles formed by a vertex of one triangle (A) and an edge of the other (B).
There are 9 such triangles, hence 9 areas and 9 signs. Anyway, the three triangles built with the same vertex of (A) have areas that sum to the area of (B), and only 9 - 3 + 1 = 7 areas need to be fully computed.
In addition, an intersection point between two edges is computed from two areas, using a formula like t= S / (S - S'), where t is the parameter along an edge.
So a completely unrolled algorithm can be written as a decision tree of depth 9 (using the 9 signed areas), with every leaf (512 of them !) generating a sequence of vertexes/intersections. There can be at worst 6 intersections.

Related

Determining whether an object is in the path of two other objects in 2D space

Say there are 3 objects defined by rectangles in x-y coordinates. The rectangles can be of any orientation (not necessarily parallel to the axes).
How would you go about approaching the problem of determining whether object C is partially, fully, or not at all obscured by object B from the perspective of object A (object A can see from anywhere on its rectangle)?
Second question: is it possible to determine the percentage of object C that is visible?
Here is my (completely untested) approach.
Consider first the same problem but only looking from one fixed point P.
Find the two (infinite) lines that go through P and enclose your rectangle B. Since it is a rectangle these two lines will be two of the four lines that go through P and each vertex of B.
Check whether each vertex of C is in between these two lines or not. If any vertex of C is between these two lines check whether it is closer or farther from P than B is. If it is farther than B is at least partially obscuring C.
Now do this for each vertex of A. You may get more complicated results if you see a part of C from one point P in A and a different part of C from a different point P in A. I will leave it up to you how to deal with that.
To determine the percent coverage, compute the shape that you get from intersecting rectangle C with these two lines and compute its area, then divide by the total area of the shape.
I have left all the math in this up to you to figure out, but if you have any specific questions about your work, feel free to ask those.
This answer would benefit nicely from having some pictures added, but I'm hoping you can understand this answer while drawing your own diagrams according to the steps provided.

Matching between two groups of points in 3D space in R

I have an unsorted group of N blue points and M red points in 3D space, where M<=N (each point is represented by X,Y,Z coordinates). Is there an "off the shelf" algorithm in R that can find for each red point the closest blue point?
The algorithm needs to minimize the sum of squares of euclidean distances between the M matched pairs, subject the constrain that the mapping is one to one, meaning that each blue point is mapped to no more than one red point. Notice that since M<=N, there will be some blue points without a match.
Seems what you need is close to the assignment problem, solved by Hungarian algorithm . You should (1) reformulate this as an assignment problem and (2) check whether it is implemented in R (google for assignment problem R or Hungarian algorithm R, etc.)

How many points define a cylinder?

It is known that 4 non-collinear, non-coplanar 3D points define a 3D sphere.
Is there an equivalent property/theorem for cylinder?
For cylinder you need 5 points. But I am not EXACTLY sure if 5 points uniquely defines a cylinder.
Following references justifies this:
http://library.wolfram.com/infocenter/Conferences/7521/cylinder_5_points_computation.pdf
A cylinder has 5 degrees of freedom: 4 for the axis (a line in 3D space), 1 for the radius, so in principle 5 points are required and enough.
But there can be several solutions: taking five point that form a regular bipyramid (two tetrahedra with a common base), there are 6 solutions, by symmetry.
This question is much more interesting than it looks like at a first look.
It is relatively easy to see how 5 points define a cylinder but not uniquely:
you can pick 3 of such points to define a circular cross section and let the other two define the bases. However it is not difficult to see that the choice of the three first points is not unique. It also depends on whether "define" means that the points have to lie on the surface (in which case the two last point have to lie inside the unbounded cylinder defined by the previous three) or not.
I think there is no simple elegant statement like in the case of the sphere.
For a finite cylinder you need a total of 7 parameters.
A 3D line needs 4 parameters (minimum distance from origin, and 3 for orientation). Then from the point closest to the origin you need 2 distances defining the beginning and end of the cylinder. One more parameter is needed for the radius, and voila, you have a 3D cylinder in space defined.
You can also use two 3D points plus a radius which also needs 7 parameters.
For in infinite cylinder you need 5 parameters. 4 for the line and 1 for the radius.
Sticking to the exact vocabulary of the question, you only need two points (really one point and a scalar for the radius) for a sphere.
A cylinder needs no more that 3 points. Two to define the axis and end points, plus a 3rd (really, 2 points and a scalar) to get the radius.

circles and triangles problem

I have an interesting problem here I've been trying to solve for the last little while:
I have 3 circles on a 2D xy plane, each with the same known radius. I know the coordinates of each of the three centers (they are arbitrary and can be anywhere).
What is the largest triangle that can be drawn such that each vertex of the triangle sits on a separate circle, what are the coordinates of those verticies?
I've been looking at this problem for hours and asked a bunch of people but so far only one person has been able to suggest a plausible solution (though I have no way of proving it).
The solution that we have come up with involves first creating a triangle about the three circle centers. Next we look at each circle individually and calculate the equation of a line that passes through the circle's center and is perpendicular to the opposite edge. We then calculate two intersection points of the circle. This is then done for the next two circles with a result of 6 points. We iterate over the 8 possible 3 point triangles that these 6 points create (the restriction is that each point of the big triangle must be on a separate circle) and find the maximum size.
The results look reasonable (at least when drawn out on paper) and it passes the special case of when the centers of the circles all fall on a straight line (gives a known largest triangle). Unfortunate i have no way of proving this is correct or not.
I'm wondering if anyone has encountered a problem similar to this and if so, how did you solve it?
Note: I understand that this is mostly a math question and not programming, however it is going to be implemented in code and it must be optimized to run very fast and efficient. In fact, I already have the above solution in code and tested to be working, if you would like to take a look, please let me know, i chose not to post it because its all in vector form and pretty much impossible to figure out exactly what is going on (because it's been condensed to be more efficient).
Lastly, yes this is for school work, though it is NOT a homework question/assignment/project. It's part of my graduate thesis (abet a very very small part, but still technically is part of it).
Thanks for your help.
Edit: Heres a new algorithm that i came up with a little while ago.
Starting at a circle's centre, draw a line to the other two centres. Calculate the line that bisects the angle created and calculate the intersections between the circle and the line that passes through the centre of your circle. You will get 2 results. Repeat this for the other two circles to get a total of 6 points. Iterate over these 6 points and get 8 possible solutions. Find the maximum of the 8 solutions.
This algorithm will deal with the collinear case if you draw your lines in one "direction" about the three points.
From the few random trials i have attempted using CAD software to figure out the geometries for me, this method seems to outperform all other methods previously stated However, it has already been proven to not be an optimal solution by one of Victor's counter examples.
I'll code this up tomorrow, for some reason I've lost remote access to my university computer and most things are on it.
I've taken the liberty of submitting a second answer, because my original answer referred to an online app that people could play with to get insight. The answer here is more a geometric argument.
The following diagram illuminates, I hope, what is going on. Much of this was inspired by #Federico Ramponi's observation that the largest triangle is characterized by the tangent at each vertex being parallel to the opposite side.
(source: brainjam.ca)
The picture was produced using a trial version of the excellent desktop program Geometry Expressions. The diagram shows the three circles centered at points A,E, and C. They have equal radii, but the picture doesn't really depend on the radii being equal, so the solution generalizes to circles of different radii. The lines MN, NO, and OM are tangent to the circles, and touch the circles at the points I,H, and G respectively. The latter points form the inner triangle IHG which is the triangle whose size we want to maximize.
There is also an exterior triangle MNO which is homethetic to the interior triangle, meaning that its sides are parallel to that of IHG.
#Federico observed that IHG has maximal area because moving any of its vertices along the corresponding circle will result an a triangle that has the same base but less height, therefore less area. To put it in slightly more technical terms, if the triangle is parameterized by angles t1,t2,t3 on the three circles (as pointed out by #Charles Stewart, and as used in my steepest descent canvas app), then the gradient of the area w.r.t to (t1,t2,t3) is (0,0,0), and the area is extremal (maximal in the diagram).
So how is this diagram computed? I'll admit in advance that I don't quite have the full story, but here's a start. Given the three circles, select a point M. Draw tangents to the circles centered at E and C, and designate the tangent points as G and I. Draw a tangent OHN to the circle centered at A that is parallel to GI. These are fairly straightforward operations both algebraically and geometrically.
But we aren't finished. So far we only have the condition that OHN is parallel to GI. We have no guarantee that MGO is parallel to IH or that MIN is parallel to GH. So we have to go back and refine M. In an interactive geometry program it's no big deal to set this up and then move M until the latter parallel conditions are met (by eyeballs, anyways). Geometry Expressions created the diagram, but I used a bit of a cheat to get it to do so, because its constraint solver was apparently not powerful enough to do the job. The algebraic expressions for G, I, and H are reasonably straightforward, so it should be possible to solve for M based on the fact that MIHG is a parallelogram, either explicitly or numerically.
I should point out that in general if you follow the construction starting from M, you have two choices of tangent for each circle, and therefore eight possible solutions. As in the other attempted answers to the question, unless you have a good heuristic to help you choose in advance which of the tangents to compute, you should probably compute all eight possible triangles and find the one with maximum area. The other seven will be extremal in the sense of being minimal area or saddle points.
That's it. This answer is not quite complete in that it leaves the final computation of M somewhat open ended. But it's reduced to either a 2D search space or the solution of an ornery but not humongous equation.
Finally, I have to disagree with #Federico's conclusion that this confirms that the solution proposed by the OP is optimal. It's true that if you draw perpendiculars from the circle centers to the opposite edge of the inner triangle, those perpendiculars intersect the circle to give you the triangle vertex. E.g. H lies on the line through A perpendicular to GI), but this is not the same as in the original proposed solution (which was to take the line through A and perpendicular to EC - in general EC is not parallel to GI).
I've created an HTML5 canvas app that may be useful for people to play with. It's pretty basic (and the code is not beautiful), but it lets you move three circles of equal radius, and then calculates a maximal triangle using gradient/steepest descent. You can also save bitmaps of the diagram. The diagram also shows the triangle whose vertices are the circle centers, and one of the altitudes. Edit1: the "altitude" is really just a line segment through one of the circle centers and perpendicular to the opposite edge of the triangle joining the centers. It's there because some of the suggested constructions use it. Edit2: the steepest descent method sometimes gets stuck in a local maximum. You can get out of that maximum by moving a circle until the black triangle flips and then bringing the circle back to its original position. Working on how to find the global maximum.
This won't work in IE because it doesn't support canvas, but most other "modern" browsers should work.
I did this partially because I found some of the arguments on this page questionable, and partially because I've never programmed a steepest descent and wanted to see how that worked. Anyways, I hope this helps, and I hope to weigh in with some more comments later.
Edit: I've looked at the geometry a little more and have written up my findings in a separate answer.
Let A, B, C be the vertexes of your triangle, and suppose they are placed as in your solution.
Notice that the key property of your construction is that each of the vertexes lies on a tangent to its circle which is parallel to the opposite side of the triangle. Obviously, the circle itself lies entirely on one side of the tangent, and in the optimal solution each tangent leaves its circle on the same side as the other vertexes.
Consider AB as the "base" of the triangle, and let C float in its circle. If you move C to another position C' within the circle, you will obtain another triangle ABC' with the same base but a smaller height, hence also with a smaller area:
figure 1 http://control.ee.ethz.ch/~ramponif/stuff/circles1.png
For the same reason, you can easily see that any position of the vertexes that doesn't follow your construction cannot be optimal. Suppose, for instance, that each one of the vertexes A', B', C' does not lie on a tangent parallel to the side connecting the other two.
Then, constructing the tangent to the circle that contains (say) C', which is parallel to A'B' and leaves the circle on the same side as A'B', and moving C' to the point of tangency C, it is always possible to construct a triangle A'B'C which has the same base, but a greater height, hence also a greater area:
figure 2 http://control.ee.ethz.ch/~ramponif/stuff/circles2.png
Since any triangle that does not follow your construction cannot be optimal, I do believe that your construction is optimal. In the case when the centers of the circles are aligned I'm a bit confused, but I guess that it is possible to prove optimality along the same lines.
I believe this is a convex optimization problem (no it's not, see below), and hence can be solved efficiently using well known methods.
You essentially want to solve the problem:
maximize: area(v1,v2,v3) ~ |cross((v2-v1), (v3-v1))|
such that: v1 in C1, v2 in C2, v3 in C3 (i.e., v_i-c_i)^2 - r_i^2 <= 0)
Each of the constraints are convex, and the area function is convex as well. Now, I don't know if there is a more efficient formulation, but you can at least use an interior point method with derivatives since the derivative of the area with respect to each vertex position can be worked out analytically (I have it written down somewhere...).
Edit: grad(area(v1,v2,v3))(v_i) = rot90(vec(vj,vk)), where vec(a,b) is making a 2D vector starting at a and ending at b, and rot90 means a positive orientation rotation by 90 degrees, assuming (vi,vj,vk) was positively oriented.
Edit 2: The problem is not convex, as should be obvious considering the collinear case; two degenerate solutions is a sure sign of non-convexity. However, the configuration starting at the circle centers should be in the globally optimal local maximum.
Not optimal, works well when all three are not colinear:
I don't have a proof (and therefore don't know if it's guaranteed to be biggest). Maybe I'll work on one. But:
We have three circles with radius R with positions (from center) P0, P1, and P2. We wish to find the vertices of a triangle such that the area of the triangle is maximum, and the vertices lie on any point of the circles edges.
Find the center of all the circles and call that C. Then C = (P0 + P1 + P2) / 3. Then we find the point on each circle farthest from C.
Find vectors V0, V1, and V2, where Vi = Pi - C. Then find points Q0, Q1, and Q2, where Qi = norm(Vi) * R + Pi. Where norm indicates normalization of a vector, norm(V) = V / |V|.
Q0, Q1, and Q2 are the vertices of the triangle. I assume this is optimal because this is the farthest the vertices could be from each other. (I think.)
My first thought is that you should be able to find an analytic solution.
Then the equations of the circles are:
(x1-h1)^2 + (y1-k1)^2 = r^2
(x2-h2)^2 + (y2-k2)^2 = r^2
(x3-h3)^2 + (y3-k3)^2 = r^2
The vertices of your triangle are (x1, y1), (x2, y2), and (x3, y3). The side lengths of your triangle are
A = sqrt((x1-x2)^2 + (y1-y2)^2)
B = sqrt((x1-x3)^2 + (y1-y3)^2)
C = sqrt((x2-x3)^2 + (y2-y3)^2)
So the area of the triangle is (using Heron's formula)
S = (A+B+C)/2
area = sqrt(S(S-A)(S-B)(S-C))
So area is a function of 6 variables.
At this point I realize this is not a fruitful line of reasoning. This is more like something I'd drop into a simulated annealing system.
So my second thought is to choose the point on circle with centre A as follows: Construct line BC joining the centres of the other two circles, then construct the line AD that is perpendicular to BC and passes through A. One vertex of the triangle is the intersection of AD and circle with centre A. Likewise for the other vertices. I can't prove this but I think it gives different results than the simple "furthest from the centre of all the circles" method, and for some reason it feels better to me. I know, not very mathematical, but then I'm a programmer.
Let's assume the center of the circles to be C0,C1 and C2; and the radius R.
Since the area of a triangle is .5*base*height, let's first find the maximum base that can be constructed with the circles.
Base = Max {(|C0-C1|+2R),(|C1-C2|+2R,(|C2-C0|+2R}
Once the base length is determined between 2 circles, then we can find the farthest perpendicular point from the base line to the third circle. (product of the their slopes is -1)
For special cases such as circles aligned in a single line, we need to perform additional checks at the time of determining the base line.
It appears that finding the largest Apollonius circle for the three circles and then inscribing an equilateral triangle in that circle would be a solution. Proof left as an exercise ;).
EDIT
This method has issues for collinear circles like other solutions here, too and doesn't work.
Some initial thoughts.
Definition Call the sought-after triangle, the maximal triangle. Note that this might not be unique: if the circles all have the same centre, then there are infinitely many maximal triangles obtained by rotation around the center, and if the centres are colinear, then there will be two maximal triangles, each a mirror image of the other.
Definition Call the triangle (possibly, degenerately, either a point or a line) whose vertices are the centres of the circles the interior triangle.
Observation The solution can be expressed as three angles, indicating where on the circumference of each circle the triangle is to be found.
Observation Given two exterior vertices, we can determine a third vertex that gives the maximal area: draw the altitude of the triangle between the two exterior vertices and the centre of the other circle. This line intersects the circumference in two places; the further away point is the maximising choice of third vertex. (Fixed incorrect algorithm, Federico's argument can be adapted to show correctness of this observation)
Consequence The problem is reduced to from a problem in three angles to one in two.
Conjecture Imagine the diagram is a pinboard, with three pins at the three centres of the circles. Imagine also a closed loop of string of length equal to the perimiter of the interior triangle, plus the radius of a circle, and we place this loop around the pins. Take an imaginary pen and imaginarily draw the looping figure where the loop is always tight. I conjecture that the points of the maximal triangle will all lie on this looping figure, and that in the case where the interior triangle is not degenerate, the vertices of the maximal triangle will be the three points where the looping figure intersects one of the circle circumferences. Many counterexamples
More to follow when I can spare time to think about it.
This is just a thought, no proof or math to go along with the construction just yet. It requires that the circle centers not be colinear if the radii are the same for each circle. This restriction can be relaxed if the radii are different.
Construction:
(1) Construct a triangle such that each side of the triangle is tangent to two circles, and therefore, each circle has a tangent point on two sides of the triangle.
(2) Draw the chord between these two tangent points on each circle
(3) Find the point on the boundary of the circle on the extended ray starting at the circle's center through the midpoint of the chord. There should be one such point on each of the three circles.
(4) Connect them three points of (3) to fom a triangle.
At that point I don't know if it's the largest such triangle, but if you're looking for something approximate, this might be it.
Later: You might be able to find an approximate answer for the degenerate case by perturbing the "middle" circle slightly in a direction perpendicular to the line connecting the three circles.

How to determine ordering of 3D vertices

If I have 5 Vertices in 3D coordinate space how can I determined the ordering of those Vertices. i.e clockwise or anticlockwise.
If I elaborate more on this,
I have a 3D model which consists of set of polygons. Each polygon is collection of vertices and I want to calculate the norm of the polygon surface. To calculate the norm I have to consider the vertices in counter clockwise order . My question is given set of vertices how can I determine whether it is ordered in clockwise or counter clockwise?
This is for navigation mesh generation where I want to remove the polygons which cannot be walked by the agent. To do so my approach is to calculate the surface norm(perpendicular vector of the polygon) and remove the polygon based on the angle with 2D plane. To calculate the norm I should know in which order points are arranged. So for given set of points in polygon how can I determine the order of the arrangement of points.
Ex.
polygon1 consist of Vertex1 = [-21.847065 -2.492895 19.569759], Vertex2 [-22.279873 1.588395 16.017160], Vertex3 [-17.234818 7.132950 7.453146] these 3 points and how can I determine the order of them
As others have noted, your question isn't entirely clear. Is the for something like a 3D backface culling test? If so, you need a point to determine the winding direction relative to. Viewed from one side of the polygon the vertices will appear to wind clockwise. From the other side they'll appear to wind counter clockwise.
But suppose your polygon is convex and properly planar. Take any three consecutive vertices A, B, and C. Then you can find the surface normal vector using the cross product:
N = (B - A) x (C - A)
Taking the dot product of the normal with a vector from the given view point, V, to one of the vertices will give you a value whose sign indicates which way the vertices appear to wind when viewed from V:
w = N . (A - V)
Whether this is positive for clockwise and negative for anticlockwise or the opposite will depend on the handedness of your coordinate system.
Your question is too poorly defined to give a complete answer, but here's the skeleton of one.
The missing part (the meat if you will), is a function that takes any two coordinates and tells you which one is 'greater' than the other. Without a solid definition for this, you won't be able to make anything work.
The rest, the skeleton, is pretty simple. Sort your list of vectors using your comparison function. For five vectors, a simple bubble sort will be all you need, although if the number of vertices increases considerably you may want to look into a faster sorting algorithm (ie. Quicksort).
If your chosen language / libraries provide sorting for you, you've already got your skeleton.
EDIT
After re-reading your question, it also occurred to me that since these n vertices define a polygon, you can probably make the assumption that all of them lie on the same plane (if they don't, then good luck rendering that).
So, if you can map the vector coordinates to 2d positions on that plane, you can reduce your problem to ordering them clockwise or counterclockwise in a two dimensional space.
I think your confusion comes from the fact that methods for computing cross products are sometimes taught in terms of clockwiseness, with a check of the clockwiseness of 3 points A,B,C determining the sign of:
(B-A) X (C - A)
However a better definition actually determines this for you.
In general 5 arbitrary points in 3 dimensions can't be said to have a clockwise ordering but 3 can since 3 points always lie in a plane.

Resources