circles and triangles problem - math

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.

Related

Find minimum set of rays intersecting all voxels

Okay first I wasn't sure if this was better suited to the MathSO so apologies if it needs migrating.
I have a 3D grid of points (representing the centers of voxels) with pitch varying in each dimension, but regular. For example resolution may be 100 by 50 by 40 for a cube shaped object.
Giving me nVox = 200,000.
For each voxel - I would like to cast (nVox - 1) rays, ending at the center, and originating from each of the other voxels.
Now there is obviously a lot of overlap here but I am having trouble finding how to calculate the minimum set of rays required. This sounds like a problem that has an elegant solution, I am however struggling to find it.
As a start, it is obvious that you only need to compute
[nVox * (nVox - 1)] / 2
of the rays, as the other half will simply be in the opposite directions. It is also easy in the 2D case to combine all of those parallel to one of the grid axes (and the two diagonals).
So how do I find the minimum set of rays I need, to pass from all voxel centers, to all others?
If someone could point me in the right direction that'd be great. Any and all help will be much appreciated.
Your problem really isn't about three dimensions in any specific way. All the conceptual complexity is present in the two dimensional case.
Instead of connecting points individually, think about the set of lines that pass through at least two points on your grid. Thus instead of thinking about points initially, think about directions. For 2-D these directions are slopes of lines. These slopes have to be rational numbers, since they intersect points on an integer lattice. Since you have a finite lattice, the numerator and the denominator of the slope can be bounded by the size of the figure. So your underlying problem is enumerating possible slopes for rational numbers of bounded "height" (math jargon).
There's an algorithm for that. It's the one used to generate the Farey sequence of reduced fractions. If your figure is N pixels wide, there will (in general) be a slope with denominator N in the somewhere, but there can't be a slope in reduced form with denominator >N; it wouldn't fit.
It's easier to deal with slopes between 0 and 1 directly. You get the other directions by two operations: negating the slope and by interchanging axes. For three dimensions, you need two slopes to define a direction.
Given an arbitrary direction (no necessarily a rational one as above), there's a perpendicular linear space of dimension k-1; for 3-D that's a plane. Projecting a 3-D parallelpiped onto this plane yields a hexagon in general; two vertices project onto the interior, six project to the vertices of the hexagon.
For a given discrete direction, there's a minimal bounding box on the integer lattice such that two opposite vertices lie along that direction. As long as that bounding box fits within your original grid, each of the interior points of the projection each correspond to a line that intersects your grid in at least two points.
In summary, enumerate directions, then for each direction enumerate where that direction intersects your grid in at least two points.

Coordinates of vectors going out from single point

I'm trying to build a visualization. The idea is to form a sphere out of circles. Similar to this:
In other words I want to pack certain number, lets say N, of circles in a sphere. All circles should have same radius and closest circles should have same distance from their centers.
I know how to draw a circle so the real problem is to find centers of the circles. How to find points on sphere where all neighboring points will be located on the same distance from each other and what is this distance is equal to.
Describing this task as a function it would have following notation
[RadiusOfSphere, NumberOfPoints] -> [CenterOfCircle, MaximumCircleRadius]
As the problem is stated, there may be no possible solution. The obstacle is that not every number of points N may admit a packing of the kind you are specifying.
You can take the radius to be fixed at 1 and scale afterwards in all cases here.
The requirement that the circles have the same radius and have the same distance to nearest neighbors is tantamount to saying that nearest neighbors are tangent to each other. All nearest neighbors, under this assumption, have the same gap on a line segment connecting their centers. Expand the radius by one-half this gap and now all closest circles are tangent. The centers don't move under this transformation. So we can assume the circles are tangent.
Circle packing is not a trivial mathematical problem, and proofs minimality or non-existence have tended to require computer-assisted proofs. I don't even know about that existence for arbitrary N. There might be a result out there, but it didn't come up in a brief search.
If you don't need every N, but simply a series of them so you can get N big enough, every quasiregular polyhedron and their duals (such as the rhombic triacontahedron, which folks on here might know better as a 30-sided die) all admit circle packings. So do their subdivisions (the figure induced by splitting edges into k pieces). So for given number of circles >N, pick one of the above polyhedrons and subdivide it so that the number of faces is large enough.

Sphere that surely encompass given list of points [points are with x, y and z co-ordinate]

I am trying to find sphere that surly encompasses given list of points.
Points will have x, y and z co-ordinate[Points are in 3D].
Actually I am trying to find new three points based on given list of points by some calculations like find MinX,MaxX ,MinY,MaxY,and MinZ and MaxZ and do some operation and find new three points
And I will draw sphere from these three points.
And I will also taking all these three points on the diameter of sphere so I have a unique sphere.
Is there any standard way for finding encompassing sphere of given list of points?
Yes, the standard algorithm is Welzl's algorithm (assuming you want the minimal sphere around your points). Particularly the improved version of Gaertner is very useful, robust and numerically stable! It handles all the degenerate cases well too.
At its core, the algorithm permutes the points (randomly) to find the 1-4 points that lie on the boundary of the sphere. It's basically a clever trial-and-error algorithm. From these points, you can find the center by finding a point that has the same distance to all those points. Gärtner's version uses an improved numerical device to find the center. Also, it employs an extra pivoting step that presumably makes the algorithm work better for a large number of input points.
If all you want is a sphere around three points, I suggest you still use Gärtners "device" to compute the circumsphere of the triangle. Otherwise, the method will probably degenerate easily (i.e. when the triangle is very flat).
Do you need 3 points, or any number of points?
If you only need the answer for 3 points, each pair of points defines a line segment. Take the longest line segment. Take a sphere centered at the middle of that line segment, whose radius is half the length of the line segment. There are two cases.
The third point is inside of that initial sphere. If so, then you have the smallest sphere.
The third point is outside of that initial sphere. Then the solution at Find Circum Center of Three point of Triangle [Not using Compass] will give you the center of the smallest sphere containing those 3 points.
If you need an arbitrary number of points, I'd do some sort of iterative approximation algorithm. Since you don't seem like you need that, I won't work out the details.

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).

Point-Triangle Collision Detection in 3D

How do I correct for floating point error in the following physical simulation:
Original point (x, y, z),
Desired point (x', y', z') after forces are applied.
Two triangles (A, B, C) and (B, C, D), who share edge BC
I am using this method for collision detection:
For each Triangle
If the original point is in front of the current triangle, and the desired point is behind the desired triangle:
Calculate the intersection point of the ray (original-desired) and the plane (triangle's normal).
If the intersection point is inside the triangle edges (!)
Respond to the collision.
End If
End If
Next Triangle
The problem I am having is that sometimes the point falls into the grey area of floating point math where it is so close to the line BC that it fails to collide with either triangle, even though technically it should always collide with one or the other since they share an edge. When this happens the point passes right between the two edge sharing triangles. I have marked one line of the code with (!) because I believe that's where I should be making a change.
One idea that works in very limited situations is to skip the edge testing. Effectively turning the triangles into planes. This only works when my meshes are convex hulls, but I plan to create convex shapes.
I am specifically using the dot product and triangle normals for all of my front-back testing.
This is an inevitable problem when shooting a single ray against some geometry with edges and vertices. It's amazing how physical simulations seem to seek out the smallest of numerical inaccuracies!
Some of the explanations and solutions proposed by other respondents will not work. In particular:
Numerical inaccuracy really can cause a ray to "fall through the gap". The problem is that we intersect the ray with the plane ABC (getting the point P, say) before testing against line BC. Then we intersect the ray with plane BCD (getting the point Q, say) before testing against line BC. P and Q are both represented by the closest floating-point approximation; there's no reason to expect that these exactly lie on the planes that they are supposed to lie on, and so every possibility that you can have both P to the left of BC and Q to the right of BC.
Using less-than-or-equal test won't help; it's inaccuracy in the intersection of the ray and the plane that's the trouble.
Square roots are not the issue; you can do all of the necessary computations using dot products and floating-point division.
Here are some genuine solutions:
For convex meshes, you can just test against all the planes and ignore the edges and vertices, as you say (thus avoiding the issue entirely).
Don't intersect the ray with each triangle in turn. Instead, use the scalar triple product. (This method makes the exact same sequence of computations for the ray and the edge BC when considering each triangle, ensuring that any numerical inaccuracy is at least consistent between the two triangles.)
For non-convex meshes, give the edges and vertices some width. That is, place a small sphere at each vertex in the mesh, and place a thin cylinder along each edge of the mesh. Intersect the ray with these spheres and cylinders as well as with the triangles. These additional geometric figures stop the ray passing through edges and vertices of the mesh.
Let me strongly recommend the book Real-Time Collision Detection by Christer Ericson. There's a discussion of this exact problem on pages 446–448, and an explanation of the scalar triple product approach to intersecting a ray with a triangle on pages 184–188.
It sounds like you ain't including testing if it's ON the edge (you're writing "Inside triangle edges"). Try changing code to "less than or equal" (inside, or overlapping).
I find it somewhat unlikely that your ray would fall exactly between the triangles in a way that the floating point precision would take effect. Are you absolutely positive that this is indeed the problem?
At any rate, a possible solution is instead of shooting just one ray to shoot three that are very close to each other. If one falls exactly in between that atleast one of the other two is guaranteed to fall on a triangle.
This will atleast allow you to test if the problem is really the floating point error or something more likely.
#Statement: I am indeed already using a "greater than or equal to" comparison in my code, thank you for the suggestion. +1
My current solution is to add a small nudge amount to the edge test. Basically when each triangle is tested, its edges are pushed out by a very small amount to counteract the error in floating point. Sort of like testing if the result of a floating point calculation is less than 0.01 rather than testing for equality with zero.
Is this a reasonable solution?
If you are doing distance measurements, watch out for square roots. They have a nasty habit of throwing away half of your precision. If you stack a few of these calculations up, you can get in big trouble fast. Here is a distance function I have used.
double Distance(double x0, double y0, double x1, double y1)
{
double a, b, dx, dy;
dx = abs(x1 - x0);
dy = abs(y1 - y0);
a = max(dx, dy));
if (a == 0)
return 0;
b = min(dx, dy);
return a * sqrt( 1 + (b*b) / (a*a) );
}
Since the last operation isn't a square root, you don't lose the precision any more.
I discovered this in a project I was working on. After studying it and figuring out what it did I tracked down the programmer who I thought was responsible to congratulate him, but he had no idea what I was talking about.

Resources