Files Classes Functions Hierarchy
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
1.5.8