📄 readme
字号:
EFFICIENT INTERSECTION TESTING OF GENERAL POLYGONS AND POLYHEDRA AGAINST AN AXIALLY-ALIGNED CUBE Authors: Don Hatch - hatch@hadron.org Daniel Green - dgreen@superliminal.com January 1994Published routines: polygon_intersects_cube fast_polygon_intersects_cube trivial_vertex_tests segment_intersects_cube polygon_contains_point_3dBACKGROUNDIn Graphics Gems III, Douglas Voorhies gives an algorithm that testswhether a given triangle intersects the axially-aligned cube of edgelength 1 centered at the origin. The algorithm presented here extendsthat work in several ways. The most important difference is that it isgeneralized to handle arbitrary polygons which may be convex, concaveor self-intersecting. The implementation is also more efficient inseveral places and fixes bugs in the original implementation which cangenerate both false positive and false negative results. The newefficiency and robustness come mostly from completely rewritten coreroutines.In Graphics Gems IV, Ned Greene describes an efficient algorithm fortesting convex polyhedra against axially aligned boxes. That algorithmworks by attempting to find a plane separating the two figures. Greenementions that the intuitive approach is inefficient because of thenumber of possible intersection calculations. (The intuitive approachcontains an intersection test of each polygon edge with each cube face,followed by intersecting each cube diagonal with the polygon body). Ourapproach is something of a hybrid. It contains only a singleintersection calculation which is rarely performed because of thetrivial tests that precede it. The rest of the calculations are of thesame sort of fast inequality tests that Greene uses.DESCRIPTIONVoorhies's original approach is elegant and sound, and we've kept thegeneral approach which proceeds from cheap trivial accept and rejecttests through more expensive edge and face intersection tests. We'vealso broken these individual tests out into separate routines in orderto allow higher level routines to be built on top of them - such asgeneral polyhedra and polygon mesh tests - without having to sufferredundant tests on shared vertices or edges.The composite fast_polygon_intersects_cube routine presented here ismeant to replace Voorhies' triangle-cube intersection routine. Itbegins by calling the trivial_vertex_tests routine which is almost anexact copy of the trivial point-plane tests from the beginning ofVoorhies' implementation and only calls the definitivepolygon_intersects_cube routine when that fails.The main algorithmic difference in our point-plane tests is that in anumber of places we avoid testing against planes which cannot possiblygive useful information. For example, when a point is found to be tothe left of the left face plane of the cube, we don't need to also testwhether it might be to the right of the right face plane.The trivial_vertex_tests routine can be used to quickly test an entireset of vertices for trivial reject or accept. This can be useful fortesting polyhedra or entire polygon meshes. Useful applications forpolyhedra testing include more than just the faster rendering ofpolyhedra; another important use is in testing for trivial rejection ofpolyhedral bounding volumes (described more fully in the last section).Note that when trivial_vertex_tests is used to simultaneously test alarge set of vertices against a set of bounding planes it's sometimespossible for the function to stop testing vertices early when it can bedetermined that there are no planes left that all of the vertices mightbe outside of. For example, if at least one vertex has been found to beto the right of the left face plane, and at least one is found to bebelow the top face plane and likewise for the other four face planes,then there is no point in classifying all the remaining verticesbecause it's impossible that as a set they could all lie outside anyone of those planes. We do this by keeping a running "cumulative AND"mask representing the set of cube face planes which still have apossibility of trivially rejecting the entire figure while loopingthrough all the vertices. We do the same when testing against the setsof bevel and corner planes (i.e. the 12 planes adjacent to the cubeedges and the 8 planes adjacent to the corners).[NB: A graphic here showing these three sets of planes would be veryuseful here especially because one was not included in Voorhies'paper.]As stated previously, when trivial_vertex_tests fails to classify agiven polygon, fast_polygon_intersects_cube then calls the definitivepolygon_intersects_cube routine. Just like in Voorhies' version thegeneral algorithm is: 1. If any edge intersects the cube, return true. 2. If the polygon interior intersects the cube, return true. 3. Return false.Our implementation, however, is very different. In the first step,testing whether a line segment intersects the cube is equivalent totesting whether the origin is contained in the solid obtained bydragging a unit cube from (being centered at) one segment endpoint tothe other. This solid is a warped rhombic dodecahedron. The code toimplement this consists of 12 sidedness tests, which is more efficientand less error-prone than the original six line-plane intersectionsplus six point-within-polygon tests.[NB: a graphic might be useful here but it may be difficult to generateone that's any clearer than the above textual description.]In the second step, since we know no vertex or edge intersects thecube, this amounts to testing whether any of the four cube diagonalsintersects the interior of the polygon. (This is the same asVoorhies' test). The difference in our implementation is that werecognize that we really only need to test against the diagonal thatcomes closest to being perpendicular to the plane of the polygon; ifthe polygon intersects any of the cube diagonals, it will intersectthat one. Finding that diagonal is trivial, so this part of ourimplementation is roughly four times as fast as the original.The last part of the second step is a test to see whether the polygoncontains the point which is the intersection of the polygon's planewith the chosen diagonal. We provide the polygon_contains_point_3d forthat purpose, and are publishing it because it may be useful for otherpurposes.VECTOR MATH MACRO LIBRARYAnother way we squeeze performance out of our implementation is throughthe use of the linear algebra library "vec.h". This library isimplemented purely as a set of C macros, thereby avoiding a functioncall for every operation. Another big advantage of using a macroimplementation is that it is completely type independent. The sourceand destination types of vectors and matrices may be any types that canbe indexed into and are assignment compatible. All integer and floatingpoint types may be freely mixed; in addition, any C++ classes thatsupport arithmetic operations may be used.The vec.h header file is automatically generated by the programvec_h.c. This program takes a single integer argument and outputs avec.h file containing macros that handle vectors and matrices up to thedimension specified. The library includes N-dimensional determinantsand cross products in addition to the simpler operations.POLYHEDRON-CUBE INTERSECTION TESTINGWhen used to test polyhedra, remember that the routines included in ourmodule only test for intersections with points, edges and surfaces, notvolumes. If no such intersection is reported, the caller should beaware that the volume of the polyhedra could still contain the entireunit box. That condition would then need to be checked for with anadditional point-within-polyhedron test. The origin would be a naturalpoint to check in such a test. Below is C-like pseudo-code that putsall the pieces together for a fast, complete polyhedron-cubeintersection test. switch(trivial_vertex_tests(verts)) { case 1: return true /* trivial accept */ case 0: return false /* trivial reject */ case -1: for each edge if(segment_intersects_cube(edge)) return true for each face if(fast_polygon_intersects_cube(..., true, true)) return true return polyhedra_contains_point(polyhedra, origin) }It's useful to notice that when a box is used as a modeling-spacebounding polyhedron, testing its intersection against a view volume canoften be performed in either direction. In other words, not only canthe box be transformed by the viewing transformation that takes theview volume to the unit cube and then tested there, but the the viewvolume can also be transformed by the transformation that takes thebounding box to be the unit cube and the test performed there. In thelatter case it is the world-space truncated pyramid of the view volumethat becomes the polyhedron being tested.[Note that our implementation contains "const" arguments which may needto be removed for those old compilers that do not understand const.]
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -