views:

428

answers:

7

Hello everyone,

I have a closed object described by a surface representation of triangles (described by three vertices which forms a right hand rule with a normal pointing to the "outside" of the object). I place a sphere of some radius in 3D space somewhere close to the surface of the object. I want to determine if the sphere intersects the object or not.

I have thought of 3 ways to determine this, but each one has their downsides and none of them are ideal.

1) I can determine the "side" on which the sphere is going to be placed, from there i can calculate a grid of distances from a reference plane to the distance where the object is first encountered. I can do the same for the opposite "side" of the sphere and then simply check if the distance to the object is always greater than the distance to the surface of the sphere. If the distance to the object is always greater, the sphere doesn't intersect the object at any of the points on the grid.

The benefit to this is that it is fairly fast, but since i only calculate discreet points, its not absolute. If the resolution of my grid is too course, there is a chance that the sphere will intersect at a point that is in between my grid nodes.

2) I can take all the vertices of all the triangles and check them against the equation of the sphere i placed. If a vertices is detected inside the sphere, the sphere will absolutely be partially inside the object.

The benefit of this is that it is fairly fast but also very prone to failure. The sphere could intersect the object within a triangle and miss all vertices all together.

3) I can calculate cluster of points on the surface of the sphere. I can then check if each point is inside the object or not (using the 3D version of point inside a polygon algorithm). If any one point is inside the object, the part of the sphere is inside the object.

The benefit of this is that it can be very accurate, depending on how many points i use on the surface of my sphere (higher density of points = more accuracy). However, the point inside an object algorithm is fairly expensive, especially when the number of triangles increases. This method would be best (would even tell me exactly where and how much of the sphere intersects the object) but it would be very slow.

Is there any algorithm or method you guys may know to solve such a problem? My foremost goal is accuracy, I need to know if the sphere will or will not touch the object. It would also be nice to know where the sphere touches or at least the general area. Finally speed is always a good thing to have.

Thanks

-Faken

A: 

Hi

Intersection check using Bounding Volume might interest you. Please check this.

Here is a page which surveys algorithms on surface intersection algorithms.

cheers

Andriyev
Well, the bounding volume would work if i had an accurate set of points on the object side. Unfortunately i only have the vertices. My second method is essentially a spherical bounding volume method, except it would fail if i had a small sphere and large triangles where the sphere would sit inside a triangle. Its fast, no doubt, bit it lacks the accuarcy i need. I mostly require high accuarcy.
Faken
A: 

Would combining (2) and also testing the center of the triangular face as another vertex work for you?

John at CashCommons
It would help, but I don't think it has a good enough accuracy. Accuracy is required above all else, this program controls a physical system in which there sphere MUST NOT touch anything, otherwise something might break.
Faken
+1  A: 

OK, I'll try again. ;)

If you need accuracy, and if you know the vertices accurately, then you can use the shortest distance to a plane to see if the sphere touches any of the planes defined by any set of three vertices which give you your triangles. For those that do, you see if the point of closest approach actually lies within the triangle.

John at CashCommons
Hmm, maybe I dismissed the distance between point and plane equation too quickly, ill look into it a bit more. Using this equation we can quickly weed out triangles that defiantly will not intersect the sphere, however then the problem lies in figuring out if the sphere actually intersects the triangle or misses it. We can't simply check if the point of shortest distance is in the triangle because the sphere can be offset and just graze the side of the triangle, the test would then fail. However, we can calculate the equation of the intersection. There we could use a few tests to determine one
Faken
of three possibilities. 1) large triangle, intersecting circle is completely inside the triangle. We can test for point inside triangle on this (although I've never done this in full 3D space). 2) small triangle, circle completely encompasses triangle. We can test for distance from sphere centre to vertices. 3) intersecting circle grazes a triangle edge. We can check for intersections between circle and lines created by the 3 vertices. 1 or more intersection points in between the two points and we know the sphere hits the triangle. Ill look into this more. Thanks for your help so far.
Faken
+1  A: 

I think you can do this with CGAL. First calculate the Minkowski sum of the sphere and the object, then you can just test if the center of the sphere (as a reference point) is inside or outside the object. This can be done in arbitrary precision arithmetic, so you can be exact if you need to be.

Andrew McGregor
Hmm, the theory is pretty simple, but how exactly would i go about calculating that sum? I could offset all the triangles outwards by the radius of the sphere along the triangle's normal, but that would only be accurate for concave surfaces. Still, any idea how i would then determine if a point was inside the new volume?
Faken
CGAL provides all the algorithms you need... you just have to work out what number type to use, and get your data into the templates.
Andrew McGregor
I see. I would actually prefer that i wrote it myself. Two reasons i guess, first of all, i actually don't know how to use these non standard libraries. Second, i want to know exactly what is going on, especially in the likely case that i will be questioned about it.
Faken
Yes, but... it's probably less work to understand CGAL than to get this right. Geometry is really, really, really hard to get right in computers... thing is, you cannot use floating point numbers, because rounding errors can make your algorithms fail (point is on both sides of a line, but not on it, for instance... that can happen). CGAL provides you a bunch of templates that let you get around that problem perfectly stably. It's the right answer.
Andrew McGregor
+1  A: 

The intersection between a sphere and a plane is a connected set.

Hence taking John's "closest approach to the plane" idea, if the sphere and the triangle intersect, and if both are closed, then either:

  • the closest point on the plane lies inside the triangle
  • the sphere intersects at least one of the edges of the triangle (because by connectedness there exists a continuous path within the plane/sphere intersection from some point inside the triangle, to some point outside the triangle. This path must cross the boundary, and the point at which it does so lies in the sphere).

The intersection between a sphere and a line is a connected set.

So extend the edge to a line the same way we extended the triangle to a plane. If the sphere intersects the edge, then either:

  • the closest point on the line lies inside the edge
  • the sphere intersects at least one of the vertices of the triangle.

So, if any of the 4 closest points (1 plane, three lines) lies in the sphere and the triangle then of course they intersect. Otherwise: if all four are outside the sphere then the two don't intersect, and if any of them is inside the sphere, then they intersect iff any of the vertices of the triangle lies in the sphere.

Unfortunately, doing this for each triangle only tells you whether the sphere and the surface of the solid intersect. It doesn't consider the case where the sphere is entirely inside the solid. So finally (or perhaps first), you must also check whether the centre of the sphere is inside the solid.

This may not be efficient, of course - I am no expert in programming geometry. And as Andrew McGregor points out, floating-point calculations don't necessarily give consistent results.

Steve Jessop
Good observation on the intersection of a edge. That makes sence, all i need to really test for is see if a triangle's plane intersects the sphere and then check if any of the edges intersect the sphere (bounded by two vertices). Accuracy is important, but i guess in a physical system, if its accurate to within 0.01mm, its good enough. Floats already give me way more accuracy than is physically meaningful. Ill code this up and let you know how it goes.
Faken
+4  A: 

This should be a full answer to your question. I haven't given an implementation, so it might require thought to avoid unnecessary divisions etc. Please ask for clarification is anything is unclear. I am building off of John at CashCommons's ideas.

Let c be the center of a sphere with radius r. What we really need to know is: is any point of the triangle T (NOT just the three vertices) closer to c than r units?

There are three cases to consider:

  1. The point in T which is closest to c is a vertex of T. This is easy!
  2. The point in T which is closest to c is inside of T.
  3. The point in T which is closest to c is on one of T's edges.

We define some variables:

  • c: the center of the sphere
  • r: the radius of the sphere
  • T: our triangle
  • v1,v2,v3: the vertices of T
  • t: the point in T that is closest to c
  • P: the unique plane that contains v1, v2, v3
  • p: the point in P that is closest to c

STEP 1: Check all the triangle vertices, in case we are in Case 1.

STEP 2: find p, the point in P that is closest to c. This can be done by projecting c onto P.

STEP 3: If we are in case 2, we are basically done. So check if p is in T. (Checking if a point is in a given triangle is relatively easy, but I don't know the BEST way to do it, so I'll leave that out.) If it is, check whether dist(p,c) > r, and that gives you your answer.

This leaves only case 3. So, assume we have p, and that p is not in T. Now, we actually know something specific about p from the geometry: the line c-->p is perpendicular to P. (If it wasn't, we could find a point p' that is closer to c than p.) Because of this perpendicularity, we can use the Pythagorean theorem:

Dist(c, z)^2 = Dist(c, z)^2 + D(p, z)^2

for any z in P. In particular this is true for z=t.

So now we just need to find t and check whether:

D(p,t)^2 <= r^2 - D(c,p)^2

This is a very similar problem, now in 2 dimensions. The thing to do is to find the t in T which is closest to p, and thus to c. We have already checked that t is not inside of T, or one of the vertices of T. Therefore, it must be on one of the edges. So, we can just try to find it on each edge. If t is not at a vertex, then the line t-->p will be perpendicular to the side, so it is reasonably straightforward to do.

STEP 4: For each side v1-->v2 of the triangle, do the following:

4.1. The line segment from v1 to v2 is given by

(x,y,z) = (v1x, v1y, v1z) + s * (v2x - v1x, v2y - v1y, v2z - v1z), 0 <= s <= 1

4.2 We want a line that lies in plane P, is perpendicular to v1-->v2, and contains p. This line will have the form

(px, py, pz) + s * (qx, qy, qz)

so we just have to pick a vector q that is parallel to plane P and perpendicular to v1-->v2. Taking

q = (p-->c) x (v1-->v2)

(i.e., the cross product) should do it, since this will be perpendicular to the normal of P, and thus parallel to P, and perpendicular to v1-->v2.

4.3 Solve the system of equations

(tx,ty,tz) = (v1x, v1y, v1z) + s1 * (v2x - v1x, v2y - v1y, v2z - v1z)
(tx,ty,tz) = (px, py, pz) + s2 * (qx, qy, qz)

to find t that lies on both lines. This really just means solving

v1x + s1 * (v2x - v1x) = px + s2 * qx
v1y + s1 * (v2y - v1y) = py + s2 * qy
v1z + s1 * (v2z - v1z) = pz + s2 * qz

for s1 and s2.

4.4. If s1 is between 0 and 1, then we found a point t that is between v1 and v2, and it should be checked.

4.5. If s1 is not between 0 and 1, then one of v1 or v2 was the closest to p, so we already checked it.

forefinger
Awesome answer.
Joseph Silvashy
Thanks for an answer. I pretty much understand what your talking about except for I can't seem to understand where z comes in or plays a part. As for the rest of your answer, its great except we have a few problems when it comes to the line geometry. The line will most defiantly be in 3D space so we will need to deal with it in parametric form, that means we cant really calculate the m or use it in the equation y = mx+b (2d equation).
Faken
This is a good point. You can get a 2d equation for the relevant line if you find an orthonormal basis for P. This in turn is relatively straightforward, since you just have to do Gram-Schmidt on v2-v1 and v3-v1. That should be enough, but I will try to think of how to do it in completely parametric terms.
forefinger
There, I put it in parametric form. Let me know if that works.
forefinger
Thanks for your help on this. You've given me a bunch of insight on how to go about doing this. This is the best answer ill likely get so ill mark it as so. As far as implementation goes, it will be probably a few more days before i actually come back with results, i still have a bunch of other things to code up before i get to this stage (it was more of a preemptive strike at the problem, rather than waiting till i actualy get to the problem to ask it).
Faken
Ill post back with an optimized implementation when i finish coding and testing it (though i cant guarantee it is actually an optimized implementation, I'm not a computer scientist by trade). If you liked this problem, take a look at another question i posted on finding centres of masses of objects defined as a surface boundary of triangles, you'll like the implementation.
Faken
A: 

Make hybrid. Find the closesed triangle/point whit method 2 and check all combinations of intersections whit all triagles near the triangle.

ralu