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
1.5.7.1