MOAB: Mesh Oriented datABase  (version 5.2.1)
GeomPrimTest.cpp
Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines