⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 readme

📁 [Game.Programming].Academic - Graphics Gems (6 books source code)
💻
字号:
		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 + -