cgma
|
00001 //- Class: CurveOverlapFacet 00002 //- Description: Facet definition class for efficient processing 00003 //- for OverlapTool. 00004 //- Owner: Corey Ernst 00005 //- Created: August 11, 2005 00006 00007 #include "CurveOverlapFacet.hpp" 00008 #include "IntersectionTool.hpp" 00009 #include "GfxPreview.hpp" 00010 00011 //AnalyticGeometryTool* CurveOverlapFacet::agt = AnalyticGeometryTool::instance(); 00012 00013 // Constructor 00014 CurveOverlapFacet::CurveOverlapFacet( GPoint p[2] ) 00015 { 00016 p0.set( p[0].x, p[0].y, p[0].z); 00017 p1.set( p[1].x, p[1].y, p[1].z); 00018 00019 CubitVector min; 00020 min.set( CUBIT_MIN( p[0].x, p[1].x ), 00021 CUBIT_MIN( p[0].y, p[1].y ), 00022 CUBIT_MIN( p[0].z, p[1].z ) ); 00023 00024 CubitVector max; 00025 max.set( CUBIT_MAX( p[0].x, p[1].x ), 00026 CUBIT_MAX( p[0].y, p[1].y ), 00027 CUBIT_MAX( p[0].z, p[1].z ) ); 00028 00029 boundingBox.reset( min, max ); 00030 00031 facetLength = 0.0; 00032 } 00033 00034 // Destructor 00035 CurveOverlapFacet::~CurveOverlapFacet() 00036 { 00037 } 00038 00039 double CurveOverlapFacet::distance_overlapping( CurveOverlapFacet *other_facet ) 00040 { 00041 //determine which is the smaller facet 00042 CurveOverlapFacet *short_facet, *long_facet; 00043 if( this->length() < other_facet->length() ) 00044 { 00045 short_facet = this; 00046 long_facet = other_facet; 00047 } 00048 else 00049 { 00050 short_facet = other_facet; 00051 long_facet = this; 00052 } 00053 00054 CubitVector long_facet_vector(long_facet->p1 - long_facet->p0); 00055 double long_facet_length = long_facet_vector.length(); 00056 long_facet_vector.normalize(); 00057 00058 CubitVector l_p0_to_s_p0( short_facet->p0 - long_facet->p0 ); 00059 CubitVector l_p0_to_s_p1( short_facet->p1 - long_facet->p0 ); 00060 00061 double dot_to_s_p0 = l_p0_to_s_p0 % long_facet_vector; 00062 double dot_to_s_p1 = l_p0_to_s_p1 % long_facet_vector; 00063 00064 //no overlap 00065 if( ( dot_to_s_p0 <= 0.0 && dot_to_s_p1 <= 0.0) || 00066 ( dot_to_s_p0 >= long_facet_length && 00067 dot_to_s_p1 >= long_facet_length ) ) 00068 { 00069 return 0.0; 00070 } 00071 00072 //overlap like this: 00073 // o-----------o 00074 // o---------------------o 00075 if( dot_to_s_p0 > 0.0 && dot_to_s_p1 < 0.0 ) 00076 return dot_to_s_p0; 00077 if( dot_to_s_p1 > 0.0 && dot_to_s_p0 < 0.0 ) 00078 return dot_to_s_p1; 00079 if( dot_to_s_p0 > long_facet_length && 00080 dot_to_s_p1 < long_facet_length ) 00081 return long_facet_length - dot_to_s_p1; 00082 if( dot_to_s_p1 > long_facet_length && 00083 dot_to_s_p0 < long_facet_length ) 00084 return long_facet_length - dot_to_s_p0; 00085 00086 00087 //overlap like this 00088 // o-----------o 00089 // o---------------------o 00090 // or this: 00091 // o-----------o 00092 // o---------------------o 00093 // or this: 00094 // o---------------------o 00095 // o---------------------o 00096 if( (dot_to_s_p0 <= long_facet_length && 00097 dot_to_s_p1 < long_facet_length ) || 00098 (dot_to_s_p1 <= long_facet_length && 00099 dot_to_s_p0 < long_facet_length ) ) 00100 return fabs( dot_to_s_p0 - dot_to_s_p1 ); 00101 00102 return 0.0; 00103 00104 /* 00105 //create vectors 00106 CubitVector v0( long_facet->p1 - long_facet->p0 ); 00107 CubitVector v1( short_facet->p0 - long_facet->p0 ); 00108 CubitVector v2( short_facet->p1 - long_facet->p0 ); 00109 CubitVector normalized_v0 = v0; 00110 normalized_v0.normalize(); 00111 00112 //project v1 and v2 onto v0 00113 double dot1 = normalized_v0 % v1; 00114 double dot2 = normalized_v0 % v2; 00115 v1 = normalized_v0 * dot1; 00116 v2 = normalized_v0 * dot2; 00117 double length0 = v0.length(); 00118 double length1 = v1.length(); 00119 double length2 = v2.length(); 00120 00121 //no overlap at all 00122 if( (length1 > long_facet->length() && length2 > long_facet->length() ) || 00123 (dot1 <= 0 && dot2 <= 0 ) ) 00124 { 00125 return 0.0; 00126 } 00127 else if( dot1 <= 0 && dot2 > 0 ) 00128 { 00129 return length2; 00130 } 00131 else if( length2 <= 0 && length1 > 0 ) 00132 { 00133 return length1; 00134 } 00135 else if( length1 > length0 ) 00136 { 00137 return length0 - length2; 00138 } 00139 else if( length2 > length0 ) 00140 { 00141 return length0 - length1; 00142 } 00143 //else 00144 return fabs( length2 - length1 ); 00145 */ 00146 /* 00147 CubitVector tmp_vec1( p0.x, p0.y, p0.z); 00148 CubitVector tmp_vec2( p1.x, p1.y, p1.z); 00149 00150 CubitVector tmp_vec3( other_facet->p0.x, other_facet->p0.y, other_facet->p0.z); 00151 CubitVector tmp_vec4( other_facet->p1.x, other_facet->p1.y, other_facet->p1.z); 00152 00153 00154 IntersectionTool int_tool( GEOMETRY_RESABS ); 00155 00156 CubitVector closest_point_seg_1; 00157 CubitVector closest_point_seg_2; 00158 double sc, tc; 00159 CubitStatus stat = int_tool.closest_points_on_segments( p0, p1, 00160 other_facet->p0, other_facet->p1, 00161 closest_point_seg_1, closest_point_seg_2, 00162 sc, tc ); 00163 //Make sure the closest points aren't the end points. If they are 00164 //and we are within tolerance, it may be that the tolerance is too big 00165 //cause we shouldn't be at a cross if the closest point is an end point... 00166 if ( sc > 0. && sc < 1. && tc > 0. && tc < 1. && 00167 closest_point_seg_1.within_tolerance(closest_point_seg_2, 0.001) ) 00168 { 00169 00170 00171 00172 } 00173 return 0.0; 00174 */ 00175 } 00176 00177 double CurveOverlapFacet::angle( CurveOverlapFacet *other_facet ) 00178 { 00179 CubitVector vec1 = p1 - p0; 00180 CubitVector vec2 = other_facet->p1 - other_facet->p0; 00181 00182 double angle = vec1.interior_angle( vec2 ); 00183 return angle; 00184 } 00185 00186 double CurveOverlapFacet::length() 00187 { 00188 if( facetLength == 0.0 ) 00189 { 00190 CubitVector tmp_vec = p1 - p0; 00191 facetLength = tmp_vec.length(); 00192 } 00193 return facetLength; 00194 } 00195 00196 double CurveOverlapFacet::facet_to_facet_distance( CurveOverlapFacet *other_facet ) 00197 { 00198 CubitVector u = p1 - p0; 00199 CubitVector v = other_facet->p1 - other_facet->p0; 00200 CubitVector w = p0 - other_facet->p0; 00201 double a = u%u; 00202 double b = u%v; 00203 double c = v%v; 00204 double d = u%w; 00205 double e = v%w; 00206 double D = a*c - b*b; 00207 double sc, sN, sD = D; 00208 double tc, tN, tD = D; 00209 00210 // compute the line parameters of the two closest points 00211 if( D < GEOMETRY_RESABS ) 00212 { 00213 sN = 0.0; // force using point P0 on segment S1 00214 sD = 1.0; // to prevent possible division by 0.0 later 00215 tN = e; 00216 tD = c; 00217 } 00218 else // get the closest points on the infinite lines 00219 { 00220 sN = (b*e - c*d); 00221 tN = (a*e - b*d); 00222 if (sN < 0.0) 00223 { // sc < 0 => the s=0 edge is visible 00224 sN = 0.0; 00225 tN = e; 00226 tD = c; 00227 } 00228 else if (sN > sD) 00229 { // sc > 1 => the s=1 edge is visible 00230 sN = sD; 00231 tN = e + b; 00232 tD = c; 00233 } 00234 } 00235 00236 if (tN < 0.0) 00237 { // tc < 0 => the t=0 edge is visible 00238 tN = 0.0; 00239 // recompute sc for this edge 00240 if (-d < 0.0) 00241 sN = 0.0; 00242 else if (-d > a) 00243 sN = sD; 00244 else 00245 { 00246 sN = -d; 00247 sD = a; 00248 } 00249 } 00250 else if (tN > tD) 00251 { // tc > 1 => the t=1 edge is visible 00252 tN = tD; 00253 // recompute sc for this edge 00254 if ((-d + b) < 0.0) 00255 sN = 0; 00256 else if ((-d + b) > a) 00257 sN = sD; 00258 else 00259 { 00260 sN = (-d + b); 00261 sD = a; 00262 } 00263 } 00264 00265 // finally do the division to get sc and tc 00266 sc = (fabs(sN) < GEOMETRY_RESABS ? 0.0 : sN / sD); 00267 tc = (fabs(tN) < GEOMETRY_RESABS ? 0.0 : tN / tD); 00268 00269 // get the difference of the two closest points 00270 CubitVector dP = w + (sc * u) - (tc * v); // = S1(sc) - S2(tc) 00271 00272 return dP.length(); // return the closest distance 00273 } 00274 00275 void CurveOverlapFacet::draw( int color ) 00276 { 00277 GfxPreview::draw_line( p0, p1, color ); 00278 return; 00279 } 00280 00281 CubitVector CurveOverlapFacet::start_point() 00282 { 00283 return p0; 00284 } 00285 00286 CubitVector CurveOverlapFacet::end_point() 00287 { 00288 return p1; 00289 } 00290