MOAB: Mesh Oriented datABase
(version 5.4.1)
|
00001 /* ***************************************************************** 00002 MESQUITE -- The Mesh Quality Improvement Toolkit 00003 00004 Copyright 2008 Sandia National Laboratories. Developed at the 00005 University of Wisconsin--Madison under SNL contract number 00006 624796. The U.S. Government and the University of Wisconsin 00007 retain certain rights to 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 This library is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 Lesser General Public License for more details. 00018 00019 You should have received a copy of the GNU Lesser General Public License 00020 (lgpl.txt) along with this library; if not, write to the Free Software 00021 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00022 00023 (2008) kraftche@cae.wisc.edu 00024 00025 ***************************************************************** */ 00026 00027 /** \file GeomPrimTest.cpp 00028 * \brief 00029 * \author Jason Kraftcheck 00030 */ 00031 00032 #include "Mesquite.hpp" 00033 #include "MsqGeomPrim.hpp" 00034 #include "UnitUtil.hpp" 00035 00036 using namespace MBMesquite; 00037 using namespace std; 00038 00039 class GeomPrimTest : public CppUnit::TestFixture 00040 { 00041 private: 00042 CPPUNIT_TEST_SUITE( GeomPrimTest ); 00043 CPPUNIT_TEST( test_line_basic ); 00044 CPPUNIT_TEST( test_line_closest_to_point ); 00045 CPPUNIT_TEST( test_line_intersect ); 00046 CPPUNIT_TEST( test_line_closest_to_line ); 00047 CPPUNIT_TEST( test_circle_basic ); 00048 CPPUNIT_TEST( test_circle_from_three_points ); 00049 CPPUNIT_TEST( test_circle_from_two_points ); 00050 CPPUNIT_TEST( test_circle_closest_to_point ); 00051 CPPUNIT_TEST( test_circle_closest_with_tangent ); 00052 CPPUNIT_TEST( test_plane_basic ); 00053 CPPUNIT_TEST( test_plane_distance ); 00054 CPPUNIT_TEST( test_plane_closest_to_point ); 00055 CPPUNIT_TEST( test_plane_intersect_plane ); 00056 CPPUNIT_TEST( test_plane_intersect_line ); 00057 CPPUNIT_TEST( test_sphere_basic ); 00058 CPPUNIT_TEST( test_sphere_closest_to_point ); 00059 CPPUNIT_TEST( test_sphere_intersect_plane ); 00060 CPPUNIT_TEST( test_sphere_intersect_sphere ); 00061 CPPUNIT_TEST_SUITE_END(); 00062 00063 public: 00064 void test_line_basic(); 00065 void test_line_closest_to_point(); 00066 void test_line_intersect(); 00067 void test_line_closest_to_line(); 00068 void test_circle_basic(); 00069 void test_circle_from_three_points(); 00070 void test_circle_from_two_points(); 00071 void test_circle_closest_to_point(); 00072 void test_circle_closest_with_tangent(); 00073 void test_plane_basic(); 00074 void test_plane_distance(); 00075 void test_plane_closest_to_point(); 00076 void test_plane_intersect_plane(); 00077 void test_plane_intersect_line(); 00078 void test_sphere_basic(); 00079 void test_sphere_closest_to_point(); 00080 void test_sphere_intersect_plane(); 00081 void test_sphere_intersect_sphere(); 00082 }; 00083 00084 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( GeomPrimTest, "Unit" ); 00085 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( GeomPrimTest, "GeomPrimTest" ); 00086 00087 void GeomPrimTest::test_line_basic() 00088 { 00089 const Vector3D point( 1, 2, 3 ), direction( -1, -2, -3 ); 00090 const MsqLine line( point, direction ); 00091 CPPUNIT_ASSERT_VECTORS_EQUAL( point, line.point(), DBL_EPSILON ); 00092 CPPUNIT_ASSERT_DOUBLES_EQUAL( 1.0, line.direction().length(), 1e-6 ); 00093 CPPUNIT_ASSERT_VECTORS_EQUAL( direction / direction.length(), line.direction(), 1e-6 ); 00094 double param = direction.length(); 00095 CPPUNIT_ASSERT_VECTORS_EQUAL( point + direction, line.point( param ), 1e-6 ); 00096 00097 const MsqLine line2( MsqLine::two_point( point, point + direction ) ); 00098 CPPUNIT_ASSERT_VECTORS_EQUAL( line.point(), line2.point(), 1e-6 ); 00099 CPPUNIT_ASSERT_VECTORS_EQUAL( line.direction(), line2.direction(), 1e-6 ); 00100 } 00101 00102 void GeomPrimTest::test_line_closest_to_point() 00103 { 00104 const MsqLine line( Vector3D( 1, 2, 3 ), Vector3D( 3, 2, 1 ) ); 00105 00106 const Vector3D p1( 0, 0, 0 ), p2( 1, 1, 1 ), p3( -5, 0, 0 ); 00107 00108 double p = line.closest( p1 ); 00109 Vector3D diff = line.point( p ) - p1; 00110 CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0, diff % line.direction(), 1e-6 ); 00111 00112 p = line.closest( p2 ); 00113 diff = line.point( p ) - p2; 00114 CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0, diff % line.direction(), 1e-6 ); 00115 00116 p = line.closest( p3 ); 00117 diff = line.point( p ) - p3; 00118 CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0, diff % line.direction(), 1e-6 ); 00119 } 00120 00121 void GeomPrimTest::test_line_intersect() 00122 { 00123 const Vector3D xsect( 2, 0, 0 ); 00124 const MsqLine line1( Vector3D( 0, 0, 0 ), Vector3D( 1, 0, 0 ) ); 00125 const MsqLine line2( Vector3D( 2, -1, 0 ), Vector3D( 0, 1, 0 ) ); 00126 double param; 00127 00128 CPPUNIT_ASSERT( line1.intersect( line2, param, 1e-6 ) ); 00129 CPPUNIT_ASSERT_VECTORS_EQUAL( xsect, line1.point( param ), 1e-6 ); 00130 CPPUNIT_ASSERT( line2.intersect( line1, param, 1e-6 ) ); 00131 CPPUNIT_ASSERT_VECTORS_EQUAL( xsect, line2.point( param ), 1e-6 ); 00132 } 00133 00134 void GeomPrimTest::test_line_closest_to_line() 00135 { 00136 const MsqLine line1( Vector3D( 3, 2, 1 ), Vector3D( 5, 6, 5 ) ); 00137 const MsqLine line2( Vector3D( -1, -2, -3 ), Vector3D( 1, 0, 0 ) ); 00138 double param1, param2; 00139 Vector3D diff; 00140 00141 CPPUNIT_ASSERT( line1.closest( line2, param1 ) ); 00142 CPPUNIT_ASSERT( line2.closest( line1, param2 ) ); 00143 diff = line1.point( param1 ) - line2.point( param2 ); 00144 CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0, diff % line1.direction(), 1e-6 ); 00145 CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0, diff % line2.direction(), 1e-6 ); 00146 } 00147 00148 void GeomPrimTest::test_circle_basic() 00149 { 00150 const Vector3D center( 0, 0, 2 ), normal( 1, 0, 0 ); 00151 const double radius = 1.5; 00152 const MsqCircle circle( center, normal, radius ); 00153 CPPUNIT_ASSERT_VECTORS_EQUAL( center, circle.center(), 1e-6 ); 00154 CPPUNIT_ASSERT_VECTORS_EQUAL( normal, circle.normal(), 1e-6 ); 00155 CPPUNIT_ASSERT_DOUBLES_EQUAL( radius, circle.radius(), 1e-6 ); 00156 } 00157 00158 void GeomPrimTest::test_circle_from_three_points() 00159 { 00160 const Vector3D p1( 1, 1, 1 ), p2( 2, 2, 2 ), p3( 3, 0, 0 ); 00161 MsqCircle circ; 00162 CPPUNIT_ASSERT( MsqCircle::three_point( p1, p2, p3, circ ) ); 00163 const Vector3D r1( p1 - circ.center() ); 00164 const Vector3D r2( p2 - circ.center() ); 00165 const Vector3D r3( p3 - circ.center() ); 00166 CPPUNIT_ASSERT_DOUBLES_EQUAL( circ.radius(), r1.length(), 1e-6 ); 00167 CPPUNIT_ASSERT_DOUBLES_EQUAL( circ.radius(), r2.length(), 1e-6 ); 00168 CPPUNIT_ASSERT_DOUBLES_EQUAL( circ.radius(), r3.length(), 1e-6 ); 00169 CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0, r1 % circ.normal(), 1e-6 ); 00170 CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0, r2 % circ.normal(), 1e-6 ); 00171 CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0, r3 % circ.normal(), 1e-6 ); 00172 } 00173 00174 void GeomPrimTest::test_circle_from_two_points() 00175 { 00176 const Vector3D center( 1, 2, 3 ); 00177 const Vector3D normal( 1, 1, 1 ); 00178 const Vector3D somedir( 0, 0, 1 ); 00179 const double radius = 0.33; 00180 Vector3D p1dir = normal * somedir; 00181 Vector3D p2dir = p1dir + normal * p1dir; 00182 p1dir *= radius / p1dir.length(); 00183 p2dir *= radius / p2dir.length(); 00184 00185 MsqCircle circ; 00186 const Vector3D p1( center + p1dir ); 00187 const Vector3D p2( center + p2dir ); 00188 CPPUNIT_ASSERT( MsqCircle::two_point( center, p1, p2, circ ) ); 00189 CPPUNIT_ASSERT_VECTORS_EQUAL( center, circ.center(), 1e-6 ); 00190 CPPUNIT_ASSERT_VECTORS_EQUAL( normal / normal.length(), circ.normal(), 1e-6 ); 00191 CPPUNIT_ASSERT_DOUBLES_EQUAL( radius, circ.radius(), 1e-6 ); 00192 } 00193 00194 void GeomPrimTest::test_circle_closest_to_point() 00195 { 00196 const MsqCircle circ( Vector3D( 1, 1, 2 ), Vector3D( 0, 1, 0 ), 0.5 ); 00197 Vector3D v1 = circ.radial_vector(); 00198 Vector3D v2 = circ.normal() * v1; 00199 v1 /= v1.length(); 00200 v2 /= v2.length(); 00201 const Vector3D q1 = circ.center() + 0.2 * v1; 00202 const Vector3D r1 = circ.center() + circ.radius() * v1; 00203 const Vector3D q2 = circ.center() + 100 * v2; 00204 const Vector3D r2 = circ.center() + circ.radius() * v2; 00205 00206 CPPUNIT_ASSERT_VECTORS_EQUAL( r1, circ.closest( q1 ), 1e-6 ); 00207 CPPUNIT_ASSERT_VECTORS_EQUAL( r2, circ.closest( q2 ), 1e-6 ); 00208 } 00209 00210 void GeomPrimTest::test_circle_closest_with_tangent() 00211 { 00212 const Vector3D center( 1, 3, 2 ); 00213 const Vector3D x( 1, 0, 0 ), y( 0, 1, 0 ), z( 0, 0, 1 ); 00214 const double radius = 2.81; 00215 const MsqCircle circ( center, z, radius ); 00216 00217 Vector3D in, out, tan; 00218 00219 // at x minimum 00220 in = center; 00221 in[0] -= radius; 00222 CPPUNIT_ASSERT( circ.closest( in, out, tan ) ); 00223 CPPUNIT_ASSERT_VECTORS_EQUAL( in, out, 1e-6 ); 00224 CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0, tan % z, 1e-6 ); 00225 CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0, tan % x, 1e-6 ); 00226 00227 // at x maximum 00228 in = center; 00229 in[0] += radius; 00230 CPPUNIT_ASSERT( circ.closest( in, out, tan ) ); 00231 CPPUNIT_ASSERT_VECTORS_EQUAL( in, out, 1e-6 ); 00232 CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0, tan % z, 1e-6 ); 00233 CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0, tan % x, 1e-6 ); 00234 00235 // at y minimum 00236 in = center; 00237 in[1] -= radius; 00238 CPPUNIT_ASSERT( circ.closest( in, out, tan ) ); 00239 CPPUNIT_ASSERT_VECTORS_EQUAL( in, out, 1e-6 ); 00240 CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0, tan % z, 1e-6 ); 00241 CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0, tan % y, 1e-6 ); 00242 00243 // at y maximum 00244 in = center; 00245 in[1] += radius; 00246 CPPUNIT_ASSERT( circ.closest( in, out, tan ) ); 00247 CPPUNIT_ASSERT_VECTORS_EQUAL( in, out, 1e-6 ); 00248 CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0, tan % z, 1e-6 ); 00249 CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0, tan % y, 1e-6 ); 00250 } 00251 00252 void GeomPrimTest::test_plane_basic() 00253 { 00254 const Vector3D norm( 1, 1, 2 ); 00255 const double coeff = -1; 00256 const MsqPlane plane( norm, coeff ); 00257 CPPUNIT_ASSERT_VECTORS_EQUAL( norm / norm.length(), plane.normal(), 1e-6 ); 00258 CPPUNIT_ASSERT_DOUBLES_EQUAL( coeff / norm.length(), plane.coefficient(), 1e-6 ); 00259 00260 const MsqPlane plane2( norm, plane.point() ); 00261 CPPUNIT_ASSERT_VECTORS_EQUAL( plane.normal(), plane2.normal(), 1e-6 ); 00262 CPPUNIT_ASSERT_DOUBLES_EQUAL( plane.coefficient(), plane2.coefficient(), 1e-6 ); 00263 } 00264 00265 void GeomPrimTest::test_plane_distance() 00266 { 00267 double offset = 2.3; 00268 const Vector3D x( 1, 0, 0 ), y( 0, 1, 0 ), z( 0, 0, 1 ); 00269 const MsqPlane xyplane( z, z * offset ); 00270 const MsqPlane yzplane( x, x * offset ); 00271 const MsqPlane xzplane( y, y * offset ); 00272 00273 const Vector3D p1( 1, 2, 3 ), p2( -1, -5, 0 ), p3( 0.5, 0.5, 100 ); 00274 CPPUNIT_ASSERT_DOUBLES_EQUAL( fabs( p1[2] - offset ), xyplane.distance( p1 ), 1e-6 ); 00275 CPPUNIT_ASSERT_DOUBLES_EQUAL( fabs( p2[2] - offset ), xyplane.distance( p2 ), 1e-6 ); 00276 CPPUNIT_ASSERT_DOUBLES_EQUAL( fabs( p3[2] - offset ), xyplane.distance( p3 ), 1e-6 ); 00277 CPPUNIT_ASSERT_DOUBLES_EQUAL( fabs( p1[0] - offset ), yzplane.distance( p1 ), 1e-6 ); 00278 CPPUNIT_ASSERT_DOUBLES_EQUAL( fabs( p2[0] - offset ), yzplane.distance( p2 ), 1e-6 ); 00279 CPPUNIT_ASSERT_DOUBLES_EQUAL( fabs( p3[0] - offset ), yzplane.distance( p3 ), 1e-6 ); 00280 CPPUNIT_ASSERT_DOUBLES_EQUAL( fabs( p1[1] - offset ), xzplane.distance( p1 ), 1e-6 ); 00281 CPPUNIT_ASSERT_DOUBLES_EQUAL( fabs( p2[1] - offset ), xzplane.distance( p2 ), 1e-6 ); 00282 CPPUNIT_ASSERT_DOUBLES_EQUAL( fabs( p3[1] - offset ), xzplane.distance( p3 ), 1e-6 ); 00283 } 00284 00285 void GeomPrimTest::test_plane_closest_to_point() 00286 { 00287 double offset = 2.3; 00288 const Vector3D x( 1, 0, 0 ), y( 0, 1, 0 ), z( 0, 0, 1 ); 00289 const MsqPlane xyplane( z, z * offset ); 00290 const MsqPlane yzplane( x, x * offset ); 00291 const MsqPlane xzplane( y, y * offset ); 00292 00293 const Vector3D p1( 1, 2, 3 ), p2( -1, -5, 0 ), p3( 0.5, 0.5, 100 ); 00294 const Vector3D p1xy( p1[0], p1[1], offset ); 00295 00296 CPPUNIT_ASSERT_VECTORS_EQUAL( Vector3D( p1[0], p1[1], offset ), xyplane.closest( p1 ), 1e-6 ); 00297 CPPUNIT_ASSERT_VECTORS_EQUAL( Vector3D( p2[0], p2[1], offset ), xyplane.closest( p2 ), 1e-6 ); 00298 CPPUNIT_ASSERT_VECTORS_EQUAL( Vector3D( p3[0], p3[1], offset ), xyplane.closest( p3 ), 1e-6 ); 00299 00300 CPPUNIT_ASSERT_VECTORS_EQUAL( Vector3D( p1[0], offset, p1[2] ), xzplane.closest( p1 ), 1e-6 ); 00301 CPPUNIT_ASSERT_VECTORS_EQUAL( Vector3D( p2[0], offset, p2[2] ), xzplane.closest( p2 ), 1e-6 ); 00302 CPPUNIT_ASSERT_VECTORS_EQUAL( Vector3D( p3[0], offset, p3[2] ), xzplane.closest( p3 ), 1e-6 ); 00303 00304 CPPUNIT_ASSERT_VECTORS_EQUAL( Vector3D( offset, p1[1], p1[2] ), yzplane.closest( p1 ), 1e-6 ); 00305 CPPUNIT_ASSERT_VECTORS_EQUAL( Vector3D( offset, p2[1], p2[2] ), yzplane.closest( p2 ), 1e-6 ); 00306 CPPUNIT_ASSERT_VECTORS_EQUAL( Vector3D( offset, p3[1], p3[2] ), yzplane.closest( p3 ), 1e-6 ); 00307 } 00308 00309 void GeomPrimTest::test_plane_intersect_plane() 00310 { 00311 const double zoffset = 2.0; 00312 const double yoffset = -3.0; 00313 const MsqPlane xy( Vector3D( 0, 0, 1 ), Vector3D( 0, 0, zoffset ) ); 00314 const MsqPlane xz( Vector3D( 0, 1, 0 ), Vector3D( 0, yoffset, 0 ) ); 00315 MsqLine line; 00316 00317 CPPUNIT_ASSERT( xy.intersect( xz, line ) ); 00318 CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0, xy.distance( line.point() ), 1e-6 ); 00319 CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0, xz.distance( line.point() ), 1e-6 ); 00320 CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0, line.direction() % xy.normal(), 1e-6 ); 00321 CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0, line.direction() % xz.normal(), 1e-6 ); 00322 } 00323 00324 void GeomPrimTest::test_plane_intersect_line() 00325 { 00326 const Vector3D normal( 1, 1, 1 ); 00327 const double coeff = -3; 00328 const Vector3D direction( -1, -1, -1 ); 00329 const Vector3D point( 0, 0, 0 ); 00330 const MsqPlane plane( normal, coeff ); 00331 const MsqLine line( point, direction ); 00332 00333 double param; 00334 CPPUNIT_ASSERT( plane.intersect( line, param ) ); 00335 CPPUNIT_ASSERT_VECTORS_EQUAL( Vector3D( 1, 1, 1 ), line.point( param ), 1e-6 ); 00336 } 00337 00338 void GeomPrimTest::test_sphere_basic() 00339 { 00340 const Vector3D center( -1, 2, 0.5 ); 00341 const double radius = 3.5; 00342 const MsqSphere sphere( center, radius ); 00343 CPPUNIT_ASSERT_VECTORS_EQUAL( center, sphere.center(), 1e-10 ); 00344 CPPUNIT_ASSERT_DOUBLES_EQUAL( radius, sphere.radius(), 1e-10 ); 00345 } 00346 00347 void GeomPrimTest::test_sphere_closest_to_point() 00348 { 00349 const Vector3D center( -1, 2, 0.5 ); 00350 const double radius = 3.5; 00351 MsqSphere sphere( center, radius ); 00352 00353 const Vector3D xpt = center + Vector3D( 1, 0, 0 ); 00354 const Vector3D ypt = center + Vector3D( 0, -100, 0 ); 00355 const Vector3D zpt = center + Vector3D( 0, 0, 0.5 ); 00356 00357 Vector3D closest, normal; 00358 closest = sphere.closest( xpt ); 00359 CPPUNIT_ASSERT_VECTORS_EQUAL( center + Vector3D( radius, 0, 0 ), closest, 1e-6 ); 00360 closest = Vector3D( 0, 0, 0 ); 00361 CPPUNIT_ASSERT( sphere.closest( xpt, closest, normal ) ); 00362 CPPUNIT_ASSERT_VECTORS_EQUAL( center + Vector3D( radius, 0, 0 ), closest, 1e-6 ); 00363 CPPUNIT_ASSERT_VECTORS_EQUAL( Vector3D( 1, 0, 0 ), normal, 1e-6 ); 00364 00365 closest = sphere.closest( ypt ); 00366 CPPUNIT_ASSERT_VECTORS_EQUAL( center + Vector3D( 0, -radius, 0 ), closest, 1e-6 ); 00367 closest = Vector3D( 0, 0, 0 ); 00368 CPPUNIT_ASSERT( sphere.closest( ypt, closest, normal ) ); 00369 CPPUNIT_ASSERT_VECTORS_EQUAL( center + Vector3D( 0, -radius, 0 ), closest, 1e-6 ); 00370 CPPUNIT_ASSERT_VECTORS_EQUAL( Vector3D( 0, -1, 0 ), normal, 1e-6 ); 00371 00372 closest = sphere.closest( zpt ); 00373 CPPUNIT_ASSERT_VECTORS_EQUAL( center + Vector3D( 0, 0, radius ), closest, 1e-6 ); 00374 closest = Vector3D( 0, 0, 0 ); 00375 CPPUNIT_ASSERT( sphere.closest( zpt, closest, normal ) ); 00376 CPPUNIT_ASSERT_VECTORS_EQUAL( center + Vector3D( 0, 0, radius ), closest, 1e-6 ); 00377 CPPUNIT_ASSERT_VECTORS_EQUAL( Vector3D( 0, 0, 1 ), normal, 1e-6 ); 00378 } 00379 00380 void GeomPrimTest::test_sphere_intersect_plane() 00381 { 00382 const MsqSphere sphere( Vector3D( 1, 1, 1 ), 2.0 ); 00383 MsqCircle result; 00384 00385 const MsqPlane noxsect( Vector3D( 1, 1, 1 ), 5 ); 00386 CPPUNIT_ASSERT( !sphere.intersect( noxsect, result ) ); 00387 00388 const MsqPlane bisect( Vector3D( 0, 0, 1 ), -1.0 ); 00389 CPPUNIT_ASSERT( sphere.intersect( bisect, result ) ); 00390 CPPUNIT_ASSERT_VECTORS_EQUAL( sphere.center(), result.center(), 1e-6 ); 00391 CPPUNIT_ASSERT_VECTORS_EQUAL( bisect.normal(), result.normal(), 1e-6 ); 00392 CPPUNIT_ASSERT_DOUBLES_EQUAL( sphere.radius(), result.radius(), 1e-6 ); 00393 00394 const MsqPlane tangent( Vector3D( 0, 1, 0 ), 1.0 ); 00395 CPPUNIT_ASSERT( sphere.intersect( tangent, result ) ); 00396 CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0, result.radius(), 1e-6 ); 00397 CPPUNIT_ASSERT_VECTORS_EQUAL( sphere.center() - Vector3D( 0, sphere.radius(), 0 ), result.center(), 1e-6 ); 00398 00399 const MsqPlane xyz0( Vector3D( 1, 1, 1 ), 0.0 ); 00400 CPPUNIT_ASSERT( sphere.intersect( xyz0, result ) ); 00401 if( xyz0.normal() % result.normal() > 0.0 ) 00402 CPPUNIT_ASSERT_VECTORS_EQUAL( xyz0.normal(), result.normal(), 1e-6 ); 00403 else 00404 CPPUNIT_ASSERT_VECTORS_EQUAL( -xyz0.normal(), result.normal(), 1e-6 ); 00405 CPPUNIT_ASSERT_VECTORS_EQUAL( Vector3D( 0, 0, 0 ), result.center(), 1e-6 ); 00406 CPPUNIT_ASSERT_DOUBLES_EQUAL( sqrt( sphere.radius() * sphere.radius() - 3 ), result.radius(), 1e-6 ); 00407 } 00408 00409 void GeomPrimTest::test_sphere_intersect_sphere() 00410 { 00411 const MsqSphere orig( Vector3D( 0, 0, 0 ), 5.0 ); 00412 const MsqSphere zsph( Vector3D( 0, 0, 3 ), 3.0 ); 00413 const MsqSphere ysph( Vector3D( 0, 6, 0 ), 2.0 ); 00414 const MsqSphere noxsct( Vector3D( 7, 0, 0 ), 1.0 ); 00415 Vector3D p1, p2, v1, v2; 00416 MsqCircle result; 00417 00418 CPPUNIT_ASSERT( !orig.intersect( noxsct, result ) ); 00419 00420 CPPUNIT_ASSERT( orig.intersect( zsph, result ) ); 00421 // choose two points on resulting circle 00422 v1 = result.radial_vector(); 00423 v2 = result.normal() * result.radial_vector(); 00424 p1 = result.center() + v1; 00425 p2 = result.center() + v2; 00426 // verify points are on both spheres 00427 CPPUNIT_ASSERT_DOUBLES_EQUAL( ( p1 - orig.center() ).length(), orig.radius(), 1e-6 ); 00428 CPPUNIT_ASSERT_DOUBLES_EQUAL( ( p1 - zsph.center() ).length(), zsph.radius(), 1e-6 ); 00429 CPPUNIT_ASSERT_DOUBLES_EQUAL( ( p2 - orig.center() ).length(), orig.radius(), 1e-6 ); 00430 CPPUNIT_ASSERT_DOUBLES_EQUAL( ( p2 - zsph.center() ).length(), zsph.radius(), 1e-6 ); 00431 00432 CPPUNIT_ASSERT( orig.intersect( ysph, result ) ); 00433 // choose two points on resulting circle 00434 v1 = result.radial_vector(); 00435 v2 = result.normal() * result.radial_vector(); 00436 p1 = result.center() + v1; 00437 p2 = result.center() + v2; 00438 // verify points are on both spheres 00439 CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0, orig.distance( p1 ), 1e-6 ); 00440 CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0, ysph.distance( p1 ), 1e-6 ); 00441 CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0, orig.distance( p2 ), 1e-6 ); 00442 CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0, ysph.distance( p2 ), 1e-6 ); 00443 }