polygon_cube_intersection.h

Go to the documentation of this file.
00001 /******************************************************************************
00002 *       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 3      *
00003 *                (c) 2006-2008 MGH, INRIA, USTL, UJF, CNRS                    *
00004 *                                                                             *
00005 * This library is free software; you can redistribute it and/or modify it     *
00006 * under the terms of the GNU Lesser General Public License as published by    *
00007 * the Free Software Foundation; either version 2.1 of the License, or (at     *
00008 * your option) any later version.                                             *
00009 *                                                                             *
00010 * This library is distributed in the hope that it will be useful, but WITHOUT *
00011 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
00012 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
00013 * for more details.                                                           *
00014 *                                                                             *
00015 * You should have received a copy of the GNU Lesser General Public License    *
00016 * along with this library; if not, write to the Free Software Foundation,     *
00017 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
00018 *******************************************************************************
00019 *                              SOFA :: Framework                              *
00020 *                                                                             *
00021 * Authors: M. Adam, J. Allard, B. Andre, P-J. Bensoussan, S. Cotin, C. Duriez,*
00022 * H. Delingette, F. Falipou, F. Faure, S. Fonteneau, L. Heigeas, C. Mendoza,  *
00023 * M. Nesme, P. Neumann, J-P. de la Plata Alcade, F. Poyer and F. Roy          *
00024 *                                                                             *
00025 * Contact information: contact@sofa-framework.org                             *
00026 ******************************************************************************/
00027 #ifndef SOFA_HELPER_PCUBE_H
00028 #define SOFA_HELPER_PCUBE_H
00029 
00030 namespace sofa
00031 {
00032 namespace helper
00033 {
00034 namespace polygon_cube_intersection
00035 {
00036 
00037 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
00038  *                                                                           *
00039  *                       POLYGON-CUBE INTERSECTION                           *
00040  *                       by Don Hatch & Daniel Green                         *
00041  *                       January 1994                                        *
00042  *                                                                           *
00043  *    CONTENTS:                                                              *
00044  *        polygon_intersects_cube()                                          *
00045  *        fast_polygon_intersects_cube()                                     *
00046  *        trivial_vertex_tests()                                             *
00047  *        segment_intersects_cube()                                          *
00048  *        polygon_contains_point_3d()                                        *
00049  *                                                                           *
00050  *                                                                           *
00051  *  This module contains  routines that test points,  segments and polygons  *
00052  *  for intersections  with the  unit cube defined  as the  axially aligned  *
00053  *  cube of edge length 1 centered  at the origin.  Polygons may be convex,  *
00054  *  concave or  self-intersecting.  Also contained is a routine  that tests  *
00055  *  whether a point  is within a polygon.  All routines  are intended to be  *
00056  *  fast and robust. Note that the cube and polygons are defined to include  *
00057  *  their boundaries.                                                        *
00058  *                                                                           *
00059  *  The  fast_polygon_intersects_cube  routine  is  meant  to  replace  the  *
00060  *  triangle-cube  intersection routine  in  Graphics Gems  III by  Douglas  *
00061  *  Voorhies.   While  that  original  algorithm  is  still sound,   it  is  *
00062  *  specialized  for triangles  and  the  implementation contained  several  *
00063  *  bugs and inefficiencies.  The trivial_vertex_tests routine defined here  *
00064  *  is  almost an  exact copy  of the  trivial point-plane  tests from  the  *
00065  *  beginning of Voorhies' algorithm but broken out into a separate routine  *
00066  *  which is called by  fast_polygon_intersects_cube.  The segment-cube and  *
00067  *  polygon-cube intersection algorithms have been completely rewritten.     *
00068  *                                                                           *
00069  *  Notice that trivial_vertex_tests can be  used to quickly test an entire  *
00070  *  set of vertices  for trivial reject or accept.  This  can be useful for  *
00071  *  testing  polyhedra  or  entire  polygon  meshes.   When  used  to  test  *
00072  *  polyhedra, remember  that these  routines only  test points,  edges and  *
00073  *  surfaces, not volumes.  If no such intersection is reported, the caller  *
00074  *  should be  aware that the volume  of the polyhedra could  still contain  *
00075  *  the entire  unit box which  would then need to  be checked for  with an  *
00076  *  additional point-within-polyhedron test.  The origin would be a natural  *
00077  *  point to check in such a test.                                           *
00078  *                                                                           *
00079 \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00080                                     
00081 
00082 #ifndef real
00083 #define real float
00084 #endif
00085 
00086 /*
00087  *                   POLYGON INTERSECTS CUBE
00088  *
00089  * Tells how the given polygon intersects the cube of edge length 1 centered
00090  * at the origin.
00091  * If any vertex or edge of the polygon intersects the cube,
00092  * a value of 1 will be returned.
00093  * Otherwise the value returned will be the multiplicity of containment
00094  * of the cross-section of the cube in the polygon; this may
00095  * be interpreted as a boolean value in any of the standard
00096  * ways; e.g. the even-odd rule (it's inside the polygon iff the
00097  * result is odd) or the winding rule (it's inside the polygon iff
00098  * the result is nonzero).
00099  *
00100  * The "polynormal" argument is a vector perpendicular to the polygon.  It
00101  * need not be of unit length.  It is suggested that Newell's method be used
00102  * to calculate polygon normals (See Graphics Gems III).  Zero-lengthed normals
00103  * are quite acceptable for degenerate polygons but are not acceptable
00104  * otherwise.  In particular, beware of zero-length normals which Newell's
00105  * method can return for certain self-intersecting polygons (for example
00106  * a bow-tie quadrilateral).
00107  *
00108  * The already_know_verts_are_outside_cube flag is unused by this routine
00109  * but may be useful for alternate implementations.
00110  *
00111  * The already_know_edges_are_outside_cube flag is useful when testing polygon
00112  * meshes with shared edges in order to not test the same edge more than once.
00113  *
00114  * Note: usually users of this module would not want to call this routine
00115  * directly unless they have previously tested the vertices with the trivial
00116  * vertex test below.  Normally one would call the fast_polygon_intersects_cube
00117  * utility instead which combines both of these tests.
00118  */
00119 extern int
00120 polygon_intersects_cube(int nverts, const real verts[/* nverts */][3],
00121             const real polynormal[3],
00122             int already_know_verts_are_outside_cube,
00123             int already_know_edges_are_outside_cube);
00124 
00125 
00126 /*
00127  *                   FAST POLYGON INTERSECTS CUBE
00128  *
00129  * This is a version of the same polygon-cube intersection that first calls
00130  * trivial_vertex_tests() to hopefully skip the more expensive definitive test.
00131  * It simply calls polygon_intersects_cube() when that fails.
00132  * Note that unlike polygon_intersects_cube(), this routine does use the
00133  * already_know_verts_are_outside_cube argument.
00134  */
00135 extern int
00136 fast_polygon_intersects_cube(int nverts, const real verts[/* nverts */][3],
00137             const real polynormal[3],
00138             int already_know_verts_are_outside_cube,
00139             int already_know_edges_are_outside_cube);
00140 
00141 
00142 /*
00143  *                   TRIVIAL VERTEX TESTS
00144  *
00145  * Returns 1 if any of the vertices are inside the cube of edge length 1
00146  * centered at the origin (trivial accept), 0 if all vertices are outside
00147  * of any testing plane (trivial reject), -1 otherwise (couldn't help).
00148  */
00149 extern int
00150 trivial_vertex_tests(int nverts, const real verts[/* nverts */][3],
00151             int already_know_verts_are_outside_cube);
00152 
00153 
00154 /*
00155  *                   SEGMENT INTERSECTS CUBE
00156  *
00157  * Returns 1 if the given line segment intersects the cube of edge length 1
00158  * centered at the origin, 0 otherwise.
00159  */
00160 extern int
00161 segment_intersects_cube(const real v0[3], const real v1[3]);
00162 
00163 
00164 /*
00165  *                   POLYGON CONTAINS POINT 3D
00166  *
00167  * Tells whether a given polygon with nonzero area contains a point which is
00168  * assumed to lie in the plane of the polygon.
00169  * Actually returns the multiplicity of containment.  This will always be 1
00170  * or 0 for non-self-intersecting planar polygons with the normal in the
00171  * standard direction (towards the eye when looking at the polygon so that
00172  * it's CCW).
00173  */
00174 extern int
00175 polygon_contains_point_3d(int nverts, const real verts[/* nverts */][3],
00176             const real polynormal[3],
00177             real point[3]);
00178 
00179 /*
00180  *  Calculate a vector perpendicular to a planar polygon.
00181  *  If the polygon is non-planar, a "best fit" plane will be used.
00182  *  The polygon may be concave or even self-intersecting,
00183  *  but it should have nonzero area or the result will be a zero vector
00184  *  (e.g. the "bowtie" quad).
00185  *  The length of vector will be twice the area of the polygon.
00186  *  NOTE:  This algorithm gives the same answer as Newell's method
00187  *  (see Graphics Gems III) but is slightly more efficient than Newell's
00188  *  for triangles and quads (slightly less efficient for higher polygons).
00189  */
00190 real *
00191 get_polygon_normal(real normal[3],
00192            int nverts, const real verts[/* nverts */][3]);
00193 
00194 }
00195 }
00196 }
00197 
00198 #endif

Generated on Sun Nov 23 02:29:30 2008 for Sofa by  doxygen 1.5.7.1