proj home

Files   Classes   Functions   Hierarchy  

disk.cpp

Go to the documentation of this file.
00001 #include <cassert>
00002 #include <sstream>
00003 using namespace std;
00004 
00005 
00006 #include <disk.h>
00007 #include <mathlib.h>
00008 #include <zero.h>
00009 
00010 disk::disk
00011 (
00012   point3<double> const & nml_,
00013   point3<double> const & pos_,
00014   doublec radius_
00015 )
00016   : nml(nml_), pos(pos_), radius(radius_)
00017 {
00018 //cout << SHOW(nml.dot()) << endl;
00019 //  assert(nml.dot()<=1.0+zero<double>::val);
00020 }
00021 
00022 
00023 boolc disk::intersects
00024 (
00025   point3<double> & p0,
00026   point3<double> & p1,
00027   disk const & D2
00028 ) const
00029 {
00030   // Four intersection points of disks on line.
00031   point3<double> q[4];
00032 
00033   plane w2(D2.nml,D2.nml.dot(D2.pos));
00034   if (intersects(q[0],q[1],w2)==false)
00035     return false;
00036 
00037   plane w1(nml,nml.dot(pos));
00038   if (D2.intersects(q[2],q[3],w1)==false)
00039     return false;
00040 
00041   // Given line segments [q0,q1] and [q3,q4],
00042   // determine if they overlap and the start and end points.
00043   // These lines should be colinear.
00044   // <TODO>
00045 
00046   
00047   point3<double> linegrad(q[2]-q[0]);
00048   if (zero<double>::test(linegrad.dot()))
00049   {
00050     linegrad = q[3]-q[0];
00051     // The disks are touching.
00052     if (zero<double>::test(linegrad.dot()))
00053     {
00054       p0 = q[0];
00055       p1 = q[0];
00056       return true;
00057     }
00058   };
00059 
00060   // Let the line by q[0] + linegrad*t.
00061 
00062   double t[4];
00063   t[0] = 0.0;
00064 
00065   if (zero<double>::test(linegrad.x*linegrad.x))
00066   {
00067     assert(zero<double>::test(linegrad.y*linegrad.y)==false);
00068 
00069     for (uint i=1; i<4; ++i)
00070       t[i] = (q[i].y-q[0].y) / linegrad.y;
00071   }  
00072   else
00073   {
00074     for (uint i=1; i<4; ++i)
00075       t[i] = (q[i].x-q[0].x) / linegrad.x;
00076   }
00077 
00078 #ifndef NDEBUG
00079   for (uint i=0; i<4; ++i)
00080   {
00081     //cout << SHOW( (q[i]-(q[0]+linegrad*t[i])).dot() ) << endl;
00082     assert( zero<double>::test((q[i]-(q[0]+linegrad*t[i])).dot()) );
00083   }
00084 #endif
00085 
00086   double c0;
00087   double c1;
00088   if (intervalintersection::unordered(c0,c1,t[0],t[1],t[2],t[3])==false)
00089     return false;
00090 
00091   p0 = q[0] + linegrad*c0;
00092   p1 = q[0] + linegrad*c1;
00093 
00094   return true;
00095 }
00096 
00097 
00098 boolc disk::intersects
00099 (
00100   point3<double> & p0,
00101   point3<double> & p1,
00102   plane const & w2
00103 ) const
00104 {
00105   plane w1(nml,nml.dot(pos));
00106 
00107   // linept + linegrad*t
00108   point3<double> linept;
00109   point3<double> linegrad;
00110 
00111   bool res = w1.intersects(linept,linegrad,w2); 
00112   if (res==false)
00113     return false;
00114 
00115   // Make a coordinate system relative to the disks origin.
00116   point3<double> q0(linept-pos);
00117   point3<double> q1(linept+linegrad-pos);
00118 
00119   // armx and army are the arms of the 2D coordinate system
00120   // in 3D space.
00121   point3<double> armx(q0);
00122   if (zero<double>::test(armx.dot()))
00123   {
00124     //t=1 case
00125     armx += linegrad;
00126     if (zero<double>::test(armx.dot()))
00127       return false;
00128 
00129     q0=linept+linegrad-pos;
00130     q1=linept-pos;
00131   }
00132   armx.normalize();
00133 
00134   point3<double> army;
00135   crossproduct::evalxyz(army,armx,nml);
00136   assert(zero<double>::test(army.dot())==false);
00137 
00138   // Get the line points in the 2D coordinate system representation.
00139   point2<double> Q0(armx.dot(q0),0.0);
00140   assert(zero<double>::test(army.dot(q0)));
00141   point2<double> Q1(armx.dot(q1),army.dot(q1));
00142 
00143   point2<double> P0;
00144   point2<double> P1;
00145   res = circleLine::intersection2D(P0,P1,radius,Q0,Q1);
00146   if (res==false)
00147     return false;
00148 
00149   p0 = armx*P0.x + army*P0.y + pos;
00150   p1 = armx*P1.x + army*P1.y + pos;
00151 
00152   return true;
00153 }
00154 
00155 disk::operator stringc () const
00156 {
00157   stringstream ss;
00158   ss << nml.x << " " << nml.y << " " << nml.z << "  ";
00159   ss << pos.x << " " << pos.y << " " << pos.z << "  "; 
00160   ss << radius;
00161 
00162   return ss.str();
00163 }
00164 
00165 
00166 
00167 
00168 

Generated on Fri Mar 4 00:49:28 2011 for Chelton Evans Source by  doxygen 1.5.8