![]() |
Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
00001 /*
00002 * MOAB, a Mesh-Oriented datABase, is a software component for creating,
00003 * storing and accessing finite element mesh data.
00004 *
00005 * Copyright 2004 Sandia Corporation. Under the terms of Contract
00006 * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government
00007 * retains certain rights in this software.
00008 *
00009 * This library is free software; you can redistribute it and/or
00010 * modify it under the terms of the GNU Lesser General Public
00011 * License as published by the Free Software Foundation; either
00012 * version 2.1 of the License, or (at your option) any later version.
00013 *
00014 */
00015
00016 /**\file Geometry.hpp
00017 *\author Jason Kraftcheck (kraftche@cae.wisc.edu)
00018 *\date 2006-07-27
00019 */
00020
00021 #ifndef MB_GEOM_UTIL_HPP
00022 #define MB_GEOM_UTIL_HPP
00023
00024 #include "moab/CartVect.hpp"
00025 #include
00026
00027 namespace moab
00028 {
00029
00030 /** \class GeomUtil
00031 * \brief Functions for computational geometry on triangles, rays, and boxes
00032 */
00033 namespace GeomUtil
00034 {
00035
00036 /** Given a line segment and an axis-aligned box,
00037 * return the sub-segment of the line segment that
00038 * itersects the box.
00039 *
00040 * Can be used to intersect ray with box by passing seg_end
00041 * as HUGE_VAL or std::numeric_limits::maximum().
00042 *
00043 *\param box_min Minimum corner of axis-aligned box
00044 *\param box_max Maximum corner of axis-aligned box
00045 *\param seg_pt A point in the line containing the segement
00046 *\param seg_unit_dir A unit vector in the direction of the line
00047 * containing the semgent.
00048 *\param seg_start The distance from seg_pt in the direction of
00049 * seg_unit_dir at which the segment begins.
00050 * As input, the start of the original segment, as output, the
00051 * start of the sub-segment intersecting the box.
00052 * Note: seg_start must be less than seg_end
00053 *\param seg_end The distance from seg_pt in the direction of
00054 * seg_unit_dir at which the segment ends.
00055 * As input, the end of the original segment, as output, the
00056 * end of the sub-segment intersecting the box.
00057 * Note: seg_start must be less than seg_end
00058 *\return true if line semgent intersects box, false otherwise.
00059 */
00060 bool segment_box_intersect( CartVect box_min,
00061 CartVect box_max,
00062 const CartVect& seg_pt,
00063 const CartVect& seg_unit_dir,
00064 double& seg_start,
00065 double& seg_end );
00066
00067 /**\brief Test for intersection between a ray and a triangle.
00068 *\param ray_point The start point of the ray.
00069 *\param ray_unit_direciton The direction of the ray. Must be a unit vector.
00070 *\param t_out Output: The distance along the ray from ray_point in the
00071 * direction of ray_unit_direction at which the ray
00072 * itersected the triangle.
00073 *\param ray_length Optional: If non-null, a pointer a maximum length
00074 * for the ray, converting this function to a segment-tri-
00075 * intersect test.
00076 *\return true if intersection, false otherwise.
00077 */
00078 bool ray_tri_intersect( const CartVect vertices[3],
00079 const CartVect& ray_point,
00080 const CartVect& ray_unit_direction,
00081 double& t_out,
00082 const double* ray_length = 0 );
00083
00084 /**\brief Plücker test for intersection between a ray and a triangle.
00085 *\param vertices Nodes of the triangle.
00086 *\param ray_point The start point of the ray.
00087 *\param ray_unit_direction The direction of the ray. Must be a unit vector.
00088 *\param t_out Output: The distance along the ray from ray_point in the
00089 * direction of ray_unit_direction at which the ray
00090 * intersected the triangle.
00091 *\param nonneg_ray_length Optional: If non-null, a maximum length for the ray,
00092 * converting this function to a segment-tri-intersect
00093 * test.
00094 *\param neg_ray_length Optional: If non-null, a maximum length for the ray
00095 * behind the origin, converting this function to a
00096 * segment-tri-intersect test.
00097 *\param orientation Optional: Reject intersections without the specified
00098 * orientation of ray with respect to triangle normal
00099 * vector. Indicate desired orientation by passing
00100 * 1 (forward), -1 (reverse), or 0 (no preference).
00101 *\param int_type Optional Output: The type of intersection; used to
00102 * identify edge/node intersections.
00103 *\return true if intersection, false otherwise.
00104 */
00105 enum intersection_type
00106 {
00107 NONE = 0,
00108 INTERIOR,
00109 NODE0,
00110 NODE1,
00111 NODE2,
00112 EDGE0,
00113 EDGE1,
00114 EDGE2
00115 };
00116 /* intersection type is determined by which of the intermediate values are == 0. There
00117 are three such values that can therefore be encoded in a 3 bit integer.
00118 0 = none are == 0 -> interior type
00119 1 = pip0 == 0 -> EDGE0
00120 2 = pip1 == 1 -> EDGE1
00121 4 = pip2 == 2 -> EDGE2
00122 5 = pip2 = pip0 == 0 -> NOEE0
00123 3 = pip0 = pip1 == 0 -> NODE1
00124 6 = pip1 = pip2 == 0 -> NODE2 */
00125 const intersection_type type_list[] = { INTERIOR, EDGE0, EDGE1, NODE1, EDGE2, NODE0, NODE2 };
00126
00127 bool plucker_ray_tri_intersect( const CartVect vertices[3],
00128 const CartVect& ray_point,
00129 const CartVect& ray_unit_direction,
00130 double& dist_out,
00131 const double* nonneg_ray_length = 0,
00132 const double* neg_ray_length = 0,
00133 const int* orientation = 0,
00134 intersection_type* int_type = 0 );
00135 double plucker_edge_test( const CartVect& vertexa,
00136 const CartVect& vertexb,
00137 const CartVect& ray,
00138 const CartVect& ray_normal );
00139
00140 //! Find range of overlap between ray and axis-aligned box.
00141 //!
00142 //!\param box_min Box corner with minimum coordinate values
00143 //!\param box_max Box corner with minimum coordinate values
00144 //!\param ray_pt Coordinates of start point of ray
00145 //!\param ray_dir Directionion vector for ray such that
00146 //! the ray is defined by r(t) = ray_point + t * ray_vect
00147 //! for t > 0.
00148 //!\param t_enter Output: if return value is true, this value
00149 //! is the parameter location along the ray at which
00150 //! the ray entered the leaf. If return value is false,
00151 //! then this value is undefined.
00152 //!\param t_exit Output: if return value is true, this value
00153 //! is the parameter location along the ray at which
00154 //! the ray exited the leaf. If return value is false,
00155 //! then this value is undefined.
00156 //!\return true if ray intersects leaf, false otherwise.
00157 bool ray_box_intersect( const CartVect& box_min,
00158 const CartVect& box_max,
00159 const CartVect& ray_pt,
00160 const CartVect& ray_dir,
00161 double& t_enter,
00162 double& t_exit );
00163
00164 /**\brief Test if plane intersects axis-aligned box
00165 *
00166 * Test for intersection between an unbounded plane and
00167 * an axis-aligned box.
00168 *\param plane_normal Vector in plane normal direction (need *not*
00169 * be a unit vector). The N in
00170 * the plane equation: N . X + D = 0
00171 *\param plane_coeff The scalar 'D' term in the plane equation:
00172 * N . X + D = 0
00173 *\param box_min_corner The smallest coordinates of the box along each
00174 * axis. The corner of the box for which all three
00175 * coordinate values are smaller than those of any
00176 * other corner. The X, Y, Z values for the planes
00177 * normal to those axes and bounding the box on the
00178 * -X, -Y, and -Z sides respectively.
00179 *\param box_max_corner The largest coordinates of the box along each
00180 * axis. The corner of the box for which all three
00181 * coordinate values are larger than those of any
00182 * other corner. The X, Y, Z values for the planes
00183 * normal to those axes and bounding the box on the
00184 * +X, +Y, and +Z sides respectively.
00185 *\return true if overlap, false otherwise.
00186 */
00187 bool box_plane_overlap( const CartVect& plane_normal,
00188 double plane_coeff,
00189 CartVect box_min_corner,
00190 CartVect box_max_corner );
00191
00192 /**\brief Test if triangle intersects axis-aligned box
00193 *
00194 * Test if a triangle intersects an axis-aligned box.
00195 *\param triangle_corners The corners of the triangle.
00196 *\param box_min_corner The smallest coordinates of the box along each
00197 * axis. The corner of the box for which all three
00198 * coordinate values are smaller than those of any
00199 * other corner. The X, Y, Z values for the planes
00200 * normal to those axes and bounding the box on the
00201 * -X, -Y, and -Z sides respectively.
00202 *\param box_max_corner The largest coordinates of the box along each
00203 * axis. The corner of the box for which all three
00204 * coordinate values are larger than those of any
00205 * other corner. The X, Y, Z values for the planes
00206 * normal to those axes and bounding the box on the
00207 * +X, +Y, and +Z sides respectively.
00208 *\param tolerance The tolerance used in the intersection test. The box
00209 * size is increased by this amount before the intersection
00210 * test.
00211 *\return true if overlap, false otherwise.
00212 */
00213 bool box_tri_overlap( const CartVect triangle_corners[3],
00214 const CartVect& box_min_corner,
00215 const CartVect& box_max_corner,
00216 double tolerance );
00217
00218 /**\brief Test if triangle intersects axis-aligned box
00219 *
00220 * Test if a triangle intersects an axis-aligned box.
00221 *\param triangle_corners The corners of the triangle.
00222 *\param box_center The center of the box.
00223 *\param box_hanf_dims The distance along each axis, respectively, from the
00224 * box_center to the boundary of the box.
00225 *\return true if overlap, false otherwise.
00226 */
00227 bool box_tri_overlap( const CartVect triangle_corners[3],
00228 const CartVect& box_center,
00229 const CartVect& box_half_dims );
00230
00231 bool box_point_overlap( const CartVect& box_min_corner,
00232 const CartVect& box_max_corner,
00233 const CartVect& point,
00234 double tolerance );
00235
00236 /**\brief Test if the specified element intersects an axis-aligned box.
00237 *
00238 * Test if element intersects axis-aligned box. Use element-specific
00239 * optimization if available, otherwise call box_general_elem_overlap.
00240 *
00241 *\param elem_corners The coordinates of the element vertices
00242 *\param elem_type The toplogy of the element.
00243 *\param box_center The center of the axis-aligned box
00244 *\param box_half_dims Half of the width of the box in each axial
00245 * direction.
00246 */
00247 bool box_elem_overlap( const CartVect* elem_corners,
00248 EntityType elem_type,
00249 const CartVect& box_center,
00250 const CartVect& box_half_dims,
00251 int nodecount = 0 );
00252
00253 /**\brief Test if the specified element intersects an axis-aligned box.
00254 *
00255 * Uses MBCN and separating axis theorem for general algorithm that
00256 * works for all fixed-size elements (not poly*).
00257 *
00258 *\param elem_corners The coordinates of the element vertices
00259 *\param elem_type The toplogy of the element.
00260 *\param box_center The center of the axis-aligned box
00261 *\param box_half_dims Half of the width of the box in each axial
00262 * direction.
00263 */
00264 bool box_linear_elem_overlap( const CartVect* elem_corners,
00265 EntityType elem_type,
00266 const CartVect& box_center,
00267 const CartVect& box_half_dims );
00268
00269 /**\brief Test if the specified element intersects an axis-aligned box.
00270 *
00271 * Uses MBCN and separating axis theorem for general algorithm that
00272 * works for all fixed-size elements (not poly*). Box and element
00273 * vertices must be translated such that box center is at origin.
00274 *
00275 *\param elem_corners The coordinates of the element vertices, in
00276 * local coordinate system of box.
00277 *\param elem_type The toplogy of the element.
00278 *\param box_half_dims Half of the width of the box in each axial
00279 * direction.
00280 */
00281 bool box_linear_elem_overlap( const CartVect* elem_corners, EntityType elem_type, const CartVect& box_half_dims );
00282
00283 void closest_location_on_box( const CartVect& box_min_corner,
00284 const CartVect& box_max_corner,
00285 const CartVect& point,
00286 CartVect& closest );
00287
00288 /**\brief find closest location on triangle
00289 *
00290 * Find closest location on linear triangle.
00291 *\param location Input position to evaluate from
00292 *\param vertices Array of three corner vertex coordinates.
00293 *\param closest_out Result position
00294 */
00295 void closest_location_on_tri( const CartVect& location, const CartVect* vertices, CartVect& closest_out );
00296
00297 /**\brief find closest location on polygon
00298 *
00299 * Find closest location on polygon
00300 *\param location Input position to evaluate from
00301 *\param vertices Array of corner vertex coordinates.
00302 *\param num_vertices Length of 'vertices' array.
00303 *\param closest_out Result position
00304 */
00305 void closest_location_on_polygon( const CartVect& location,
00306 const CartVect* vertices,
00307 int num_vertices,
00308 CartVect& closest_out );
00309
00310 /**\brief find closest topological location on triangle
00311 *
00312 * Find closest location on linear triangle.
00313 *\param location Input position to evaluate from
00314 *\param vertices Array of three corner vertex coordinates.
00315 *\param tolerance Tolerance to use when comparing to corners and edges
00316 *\param closest_out Result position
00317 *\param closest_topo Closest topological entity
00318 * 0-2 : vertex index
00319 * 3-5 : edge beginning at closest_topo - 3
00320 * 6 : triangle interior
00321 */
00322 void closest_location_on_tri( const CartVect& location,
00323 const CartVect* vertices,
00324 double tolerance,
00325 CartVect& closest_out,
00326 int& closest_topo );
00327
00328 // Finds whether or not a box defined by the center and the half
00329 // width intersects a trilinear hex defined by its eight vertices.
00330 bool box_hex_overlap( const CartVect hexv[8], const CartVect& box_center, const CartVect& box_dims );
00331
00332 // Finds whether or not a box defined by the center and the half
00333 // width intersects a linear tetrahedron defined by its four vertices.
00334 bool box_tet_overlap( const CartVect tet_corners[4], const CartVect& box_center, const CartVect& box_dims );
00335
00336 // tests if 2 boxes overlap within a tolerance
00337 // assume that data is valid, box_min1 << box_max1, and box_min2<< box_max2
00338 // they are overlapping if they are overlapping in all directions
00339 // for example in x direction:
00340 // box_max2[0] + tolerance < box_min1[0] -- false
00341 bool boxes_overlap( const CartVect& box_min1,
00342 const CartVect& box_max1,
00343 const CartVect& box_min2,
00344 const CartVect& box_max2,
00345 double tolerance );
00346
00347 // see if boxes formed by 2 lists of "CartVect"s overlap
00348 bool bounding_boxes_overlap( const CartVect* list1, int num1, const CartVect* list2, int num2, double tolerance );
00349
00350 // see if boxes from vertices in 2d overlap (used in gnomonic planes right now)
00351 bool bounding_boxes_overlap_2d( const double* list1, int num1, const double* list2, int num2, double tolerance );
00352 // point_in_trilinear_hex
00353 // Tests if a point in xyz space is within a hex element defined with
00354 // its eight vertex points forming a trilinear basis function. Computes
00355 // the natural coordinates with respect to the hex of the xyz point
00356 // and checks if each are between +/-1. If anyone is outside the range
00357 // the function returns false, otherwise it returns true.
00358 //
00359 bool point_in_trilinear_hex( const CartVect* hex, const CartVect& xyz, double etol );
00360
00361 bool nat_coords_trilinear_hex( const CartVect* corner_coords, const CartVect& x, CartVect& xi, double tol );
00362 } // namespace GeomUtil
00363
00364 } // namespace moab
00365
00366 #endif