Compounds | |
struct | guar::Interval |
class | guar::rational |
struct | guar::rational::rational_rep |
class | guar::ULong |
Functions | |
void | IntAdd (const unsigned int na, const unsigned long *a, const unsigned int nb, const unsigned long *b, unsigned int *nc, unsigned long *c) |
int | IntSub (const unsigned int na, const unsigned long *a, const unsigned int nb, const unsigned long *b, unsigned int *nc, unsigned long *c) |
unsigned long | IntMultShort (const unsigned int na, const unsigned long *a, const unsigned long b, unsigned long *c) |
void | IntMult (const unsigned int na, const unsigned long *a, const unsigned int nb, const unsigned long *b, unsigned int *nc, unsigned long *c) |
unsigned long | IntDivShort (const unsigned int na, const unsigned long *a, const unsigned long b, unsigned int *nq, unsigned long *q) |
int | IntDiv (const unsigned int na, const unsigned long *a, const unsigned int nb, const unsigned long *b, unsigned int *nq, unsigned long *q, unsigned int *nr, unsigned long *r) |
int | DoubleToInt (const double d, const unsigned int na, unsigned long *a, int *retLen) |
Interval | operator * (const Interval &a, const Interval &b) |
GULAPI rational | operator * (const rational &a, const rational &b) |
GULAPI rational | operator+ (const rational &A, const rational &B) |
GULAPI rational | operator/ (const rational &A, const rational &B) |
GULAPI rational | operator- (const rational &A, const rational &B) |
template<class T> void | IntTo (const unsigned int na, const unsigned long *a, T &t) |
int | IntSub (const int unsigned na, const unsigned long *a, const int unsigned nb, const unsigned long *b, unsigned int *nc, unsigned long *c) |
int | DoubleToInt (const double d, const unsigned int na, unsigned long *a, unsigned int *retLen) |
double | IntToDouble (const unsigned int na, const unsigned long *a) |
Interval | operator+ (const Interval &a, const Interval &b) |
Interval | operator- (const Interval &a, const Interval &b) |
Interval | operator/ (const Interval &a, const Interval &b) |
Interval | Sqrt (const Interval &a) |
int | Test (const Interval &a) |
int | Test (const Interval &a, const Interval &b) |
double | GetRatio (const Interval &a) |
bool | RegularIntersectLines (const point< rational > &A, const point< rational > &B, const point< rational > &a, const point< rational > &b, rational *lambda, rational *mu) |
template<class T> GULAPI void | BarycentricCoordinates (const point< T > &P1, const point< T > &P2, const point< T > &P3, const point< T > &Pin, T *w, T *u, T *v) |
template GULAPI void | BarycentricCoordinates (const point< rational > &P1, const point< rational > &P2, const point< rational > &P3, const point< rational > &Pin, rational *w, rational *u, rational *v) |
template<class T> GULAPI void | BarycentricCoordinates (const point< T > &P1, const point< T > &P2, const point< T > &P3, const point< T > &P12, const point< T > &P13, const point< T > &P23, const point< T > &N, const point< T > &Pin, T *w, T *u, T *v) |
template GULAPI void | BarycentricCoordinates (const point< rational > &P1, const point< rational > &P2, const point< rational > &P3, const point< rational > &P12, const point< rational > &P13, const point< rational > &P23, const point< rational > &N, const point< rational > &Pin, rational *w, rational *u, rational *v) |
GULAPI int | IntersectTriangles (const triangle< rational > &tri0, const triangle< rational > &tri1, Ptr< point< rational > > &retP) |
GULAPI bool | IntersectTrianglesUV (const triangle< rational > &tri1, const triangle2< rational > &tri1uv, const triangle< rational > &tri2, const triangle2< rational > &tri2uv, point2< rational > *S1uv, int *S1flag, point2< rational > *S2uv, int *S2flag, point< rational > *S) |
template<class T> GULAPI void | BarycentricCoordinates (const gul::point< T > &P1, const gul::point< T > &P2, const gul::point< T > &P3, const gul::point< T > &Pin, T *w, T *u, T *v) |
template<class T> GULAPI void | BarycentricCoordinates (const gul::point< T > &P1, const gul::point< T > &P2, const gul::point< T > &P3, const gul::point< T > &P12, const gul::point< T > &P13, const gul::point< T > &P23, const gul::point< T > &N, const gul::point< T > &Pin, T *w, T *u, T *v) |
GULAPI int | IntersectTriangles (const gul::triangle< rational > &tri0, const gul::triangle< rational > &tri1, gul::Ptr< gul::point< rational > > &retP) |
GULAPI bool | IntersectTrianglesUV (const gul::triangle< rational > &tri1, const gul::triangle2< rational > &tri1uv, const gul::triangle< rational > &tri2, const gul::triangle2< rational > &tri2uv, gul::point2< rational > *S1uv, int *S1flag, gul::point2< rational > *S2uv, int *S2flag, gul::point< rational > *S) |
|
|
|
|
|
|
|
Definition at line 220 of file guar_intersect.cpp.
00226 { 00227 point2<T> W,U,V,P; 00228 point2<T> WU,WV,UV,WP,UP; 00229 point<T> UVW,PVW,PWU,PUV; 00230 T aUVW,aPVW,aPWU,aPUV; 00231 rational one_neg(ULong(1),-1); 00232 00233 // calculate barycentric coordinates in xy-plane 00234 if( test(N.z) ) 00235 { 00236 W.x = P1.x; 00237 W.y = P1.y; 00238 00239 U.x = P2.x; 00240 U.y = P2.y; 00241 00242 V.x = P3.x; 00243 V.y = P3.y; 00244 00245 WU.x = P12.x; 00246 WU.y = P12.y; 00247 00248 WV.x = P13.x; 00249 WV.y = P13.y; 00250 00251 UV.x = P23.x; 00252 UV.y = P23.y; 00253 00254 P.x = Pin.x; 00255 P.y = Pin.y; 00256 } 00257 else if( test(N.y) ) // calculate barycentric coordinates in xz-plane 00258 { 00259 W.x = P1.x; 00260 W.y = P1.z; 00261 00262 U.x = P2.x; 00263 U.y = P2.z; 00264 00265 V.x = P3.x; 00266 V.y = P3.z; 00267 00268 WU.x = P12.x; 00269 WU.y = P12.z; 00270 00271 WV.x = P13.x; 00272 WV.y = P13.z; 00273 00274 UV.x = P23.x; 00275 UV.y = P23.z; 00276 00277 P.x = Pin.x; 00278 P.y = Pin.z; 00279 } 00280 else // calculate barycentric coordinates in yz-plane 00281 { 00282 gul::Assert<InternalError>( ndebug || test(N.x) ); 00283 00284 W.x = P1.y; 00285 W.y = P1.z; 00286 00287 U.x = P2.y; 00288 U.y = P2.z; 00289 00290 V.x = P3.y; 00291 V.y = P3.z; 00292 00293 WU.x = P12.y; 00294 WU.y = P12.z; 00295 00296 WV.x = P13.y; 00297 WV.y = P13.z; 00298 00299 UV.x = P23.y; 00300 UV.y = P23.z; 00301 00302 P.x = Pin.y; 00303 P.y = Pin.z; 00304 } 00305 00306 /* 00307 cout << "N = (" << N << ")\n"; 00308 cout << "P12 = (" << P12 << "), "; 00309 cout << "WU = (" << WU << ")\n"; 00310 cout << "P13 = (" << P13 << "), "; 00311 cout << "WV = (" << WV << ")\n"; 00312 */ 00313 00314 UVW = cross_product(WU,WV); 00315 aUVW = UVW.z; 00316 if( test(aUVW) < 0 ) aUVW = aUVW * one_neg; 00317 00318 WP = P-W; 00319 PVW = cross_product(WP,WV); 00320 aPVW = PVW.z; 00321 if( test(aPVW) < 0 ) aPVW = aPVW * one_neg; 00322 00323 *u = aPVW/aUVW; 00324 00325 PWU = cross_product(WP,WU); 00326 aPWU = PWU.z; 00327 if( test(aPWU) < 0 ) aPWU = aPWU *one_neg; 00328 00329 *v = aPWU/aUVW; 00330 00331 UP = P-U; 00332 PUV = cross_product(UV,UP); 00333 aPUV = PUV.z; 00334 if( test(aPUV) < 0 ) aPUV = aPUV * one_neg; 00335 00336 *w = aPUV/aUVW; 00337 } |
|
|
|
Definition at line 104 of file guar_intersect.cpp.
00108 { 00109 point2<T> W,U,V,P; 00110 point2<T> WU,WV,UV,WP,UP; 00111 point<T> UVW,PVW,PWU,PUV,P12,P13,N; 00112 T aUVW,aPVW,aPWU,aPUV; 00113 rational one_neg(ULong(1),-1); 00114 00115 P12 = P2 - P1; 00116 P13 = P3 - P1; 00117 N = cross_product( P12, P13 ); 00118 00119 // calculate barycentric coordinates in xy-plane 00120 if( test(N.z) ) 00121 { 00122 W.x = P1.x; 00123 W.y = P1.y; 00124 00125 U.x = P2.x; 00126 U.y = P2.y; 00127 00128 V.x = P3.x; 00129 V.y = P3.y; 00130 00131 WU.x = P12.x; 00132 WU.y = P12.y; 00133 00134 WV.x = P13.x; 00135 WV.y = P13.y; 00136 00137 P.x = Pin.x; 00138 P.y = Pin.y; 00139 } 00140 else if( test(N.y) ) // calculate barycentric coordinates in xz-plane 00141 { 00142 W.x = P1.x; 00143 W.y = P1.z; 00144 00145 U.x = P2.x; 00146 U.y = P2.z; 00147 00148 V.x = P3.x; 00149 V.y = P3.z; 00150 00151 WU.x = P12.x; 00152 WU.y = P12.z; 00153 00154 WV.x = P13.x; 00155 WV.y = P13.z; 00156 00157 P.x = Pin.x; 00158 P.y = Pin.z; 00159 } 00160 else // calculate barycentric coordinates in yz-plane 00161 { 00162 gul::Assert<InternalError>( ndebug || test(N.x) ); 00163 00164 W.x = P1.y; 00165 W.y = P1.z; 00166 00167 U.x = P2.y; 00168 U.y = P2.z; 00169 00170 V.x = P3.y; 00171 V.y = P3.z; 00172 00173 WU.x = P12.y; 00174 WU.y = P12.z; 00175 00176 WV.x = P13.y; 00177 WV.y = P13.z; 00178 00179 P.x = Pin.y; 00180 P.y = Pin.z; 00181 } 00182 00183 UVW = cross_product(WU,WV); 00184 aUVW = UVW.z; 00185 if( test(aUVW) < 0 ) aUVW = aUVW * one_neg; 00186 00187 WP = P-W; 00188 PVW = cross_product(WP,WV); 00189 aPVW = PVW.z; 00190 if( test(aPVW) < 0 ) aPVW = aPVW * one_neg; 00191 00192 *u = aPVW/aUVW; 00193 00194 PWU = cross_product(WP,WU); 00195 aPWU = PWU.z; 00196 if( test(aPWU) < 0 ) aPWU = aPWU *one_neg; 00197 00198 *v = aPWU/aUVW; 00199 00200 UV = V-U; 00201 UP = P-U; 00202 00203 PUV = cross_product(UV,UP); 00204 aPUV = PUV.z; 00205 if( test(aPUV) < 0 ) aPUV = aPUV * one_neg; 00206 00207 *w = aPUV/aUVW; 00208 } |
|
|
|
Definition at line 349 of file guar_exact.cpp.
00351 { 00352 double f,m; 00353 int i,sign,len; 00354 00355 if( d < 0.0 ) 00356 { 00357 sign = -1; 00358 m = fabs( d ); 00359 } 00360 else 00361 { 00362 sign = 0; 00363 m = d; 00364 } 00365 00366 len = 0; 00367 while( m >= 1.0 ) 00368 { 00369 m = m / (double)(LL(0x100000000)); 00370 len++; 00371 } 00372 for( i = len-1; i >= 0; i-- ) 00373 { 00374 m = m*(double)(LL(0x100000000)); 00375 f = floor(m); 00376 a[i] = (unsigned long)f; 00377 m -= f; 00378 } 00379 00380 *retLen = len; 00381 return(sign); 00382 } |
|
Definition at line 471 of file guar_exact.h.
00472 { 00473 double h,l; 00474 00475 h = a.m_high; 00476 l = a.m_low; 00477 00478 if( l < 0.0 ) 00479 { 00480 if( h >= 0.0 ) return gul::rtr<double>::giant(); // relative error = inf 00481 00482 h = -l; 00483 l = -h; 00484 } 00485 00486 if( l == 0.0 ) 00487 { 00488 if( h == 0.0 ) return 1.0; 00489 return gul::rtr<double>::giant(); 00490 } 00491 00492 return h/l; 00493 } |
|
Definition at line 37 of file guar_exact.cpp.
00040 { 00041 uint64 l,z=0; 00042 unsigned int i,len; 00043 00044 if( na < nb ) 00045 { 00046 len = nb+1; 00047 00048 for( i = 0; i < na; i++ ) 00049 { 00050 l = (uint64)a[i] + (uint64)b[i] + z; 00051 c[i] = (unsigned long)(l & 0xffffffff); 00052 z = (l >> 32) & 0xffffffff; 00053 } 00054 for( i = na; i < nb; i++ ) 00055 { 00056 l = (uint64)b[i] + z; 00057 c[i] = (unsigned long)(l & 0xffffffff); 00058 z = (l >> 32) & 0xffffffff; 00059 } 00060 if( (c[i] = (unsigned long)z) == 0 ) len -= 1; 00061 } 00062 else 00063 { 00064 len = na+1; 00065 00066 for( i = 0; i < nb; i++ ) 00067 { 00068 l = (uint64)a[i] + (uint64)b[i] + z; 00069 c[i] = (unsigned long)(l & 0xffffffff); 00070 z = (l >> 32) & 0xffffffff; 00071 } 00072 for( i = nb; i < na; i++ ) 00073 { 00074 l = (uint64)a[i] + z; 00075 c[i] = (unsigned long)(l & 0xffffffff); 00076 z = (l >> 32) & 0xffffffff; 00077 } 00078 if( (c[i] = (unsigned long)z) == 0 ) len -= 1; 00079 } 00080 00081 *nc = len; 00082 } |
|
Definition at line 235 of file guar_exact.cpp. Referenced by guar::rational::div_mod().
00239 { 00240 unsigned long *ad, *bd; 00241 uint64 d, z, l, b1, b2, m, ml, qh; 00242 unsigned int i,j; 00243 int sign; 00244 00245 if( na == 0 ) 00246 { 00247 *nq = 0; 00248 *nr = 0; 00249 return(-1); 00250 } 00251 00252 if( nb < 2 ) 00253 { 00254 if( nb == 0 ) return(0); 00255 00256 r[0] = IntDivShort( na, a, b[0], nq, q ); 00257 if( r[0] != 0 ) *nr = 1; else *nr = 0; 00258 return(-1); 00259 } 00260 00261 if( na < nb ) 00262 { 00263 memcpy( r, a, na*sizeof(unsigned long) ); 00264 *nr = na; 00265 *nq = 0; 00266 return(-1); 00267 } 00268 00269 ad = (unsigned long *)alloca( sizeof(unsigned long)*(na+1) ); 00270 if( ad == NULL ) return(0); 00271 bd = (unsigned long *)alloca( sizeof(unsigned long)*nb ); 00272 if( bd == NULL ) return(0); 00273 00274 d = LL(0x100000000)/(((uint64)b[nb-1]) + LL(1)); 00275 00276 ad[na] = IntMultShort( na, a, (unsigned long)d, ad ); 00277 IntMultShort( nb, b, (unsigned long)d, bd ); 00278 00279 b1 = bd[nb-1]; 00280 b2 = bd[nb-2]; 00281 00282 for( i = na; i >= nb; i-- ) 00283 { 00284 l = (((uint64)ad[i])<<32) + (uint64)ad[i-1]; 00285 00286 if( ad[i] == bd[nb-1] ) 00287 qh = 0xffffffff; 00288 else 00289 qh = l/b1; 00290 00291 while( b2*qh > ((l - b1*qh)<<32) + (uint64)ad[i-2] ) qh--; 00292 00293 z = 1; 00294 sign = 0; 00295 m = 0; 00296 for( j = 0; j < nb; j++ ) 00297 { 00298 m = qh*(uint64)bd[j] + m; 00299 ml = m & 0xffffffff; 00300 m = m >> 32; 00301 00302 l = 0xffffffff + (uint64)ad[i-nb+j] - ml + z; 00303 ad[i-nb+j] = (unsigned long)(l & 0xffffffff); 00304 z = (l >> 32) & 0xffffffff; 00305 } 00306 l = 0xffffffff + (uint64)ad[i] - m + z; 00307 ad[i] = (unsigned long)(l & 0xffffffff); 00308 z = (l >> 32) & 0xffffffff; 00309 sign = (z - LL(1) != 0 ? -1 : 0); 00310 00311 if( sign ) /* add borrow back */ 00312 { 00313 qh--; 00314 00315 z = 0; 00316 for( j = 0; j < nb; j++ ) 00317 { 00318 l = (uint64)ad[i-nb+j] + (uint64)bd[j] + z; 00319 ad[i-nb+j] = (unsigned long)(l & 0xffffffff); 00320 z = (l >> 32) & 0xffffffff; 00321 } 00322 l = (uint64)ad[i] + z; 00323 ad[i] = (unsigned long)(l & 0xffffffff); 00324 } 00325 00326 q[i-nb] = (unsigned long)qh; 00327 } 00328 00329 for( i = nb-1; (i > 0) && (ad[i]==0); i-- ); 00330 00331 if( (i > 0) || (ad[0] != 0) ) 00332 // IntDivShort( nb, ad, (unsigned long)d, nr, r ); 00333 IntDivShort( i+1, ad, (unsigned long)d, nr, r ); 00334 else 00335 *nr = 0; 00336 00337 if( q[na-nb] == 0 ) 00338 *nq = na-nb; 00339 else 00340 *nq = na-nb+1; 00341 00342 return(-1); 00343 } |
|
Definition at line 209 of file guar_exact.cpp.
00212 { 00213 uint64 l, z, d = b; 00214 int i; 00215 00216 z = 0; 00217 for( i = na-1; i >= 0; i-- ) 00218 { 00219 l = (z<<32) + ((uint64)a[i]); 00220 q[i] = (unsigned long)(l / d); 00221 z = l % d; 00222 } 00223 00224 if( q[na-1] == 0 ) 00225 *nq = na-1; 00226 else 00227 *nq = na; 00228 00229 return((unsigned long)z); 00230 } |
|
|
|
Definition at line 355 of file guar_intersect.cpp.
00359 { 00360 point<rational> v11,v12,v13,n,v21,v22,v23,g,t; 00361 point<rational> P1,P2,P3; 00362 rational A,B,C,R,a,b,c,r,N; 00363 rational one(ULong(1)),zero; 00364 rational lambda,mu,l1,r1,l2,r2,l; 00365 bool result,init; 00366 int dim; 00367 00368 // calculate plane equation for 1.triangle 00369 // (Ax + By + Cz = R) 00370 00371 v11 = tri0.P2 - tri0.P1; // 1. direction vector 00372 v12 = tri0.P3 - tri0.P1; // 2. direction vector 00373 v13 = tri0.P3 - tri0.P2; // (needed later) 00374 n = cross_product( v11, v12 ); // normal vector of the plane 00375 A = n.x; B = n.y; C = n.z; 00376 R = n * tri0.P1; // right side of plane equation 00377 00378 // calculate plane equation for 2.triangle 00379 // (ax + by + cz = r) 00380 v21 = tri1.P2 - tri1.P1; // 1. direction vector 00381 v22 = tri1.P3 - tri1.P1; // 2. direction vector 00382 v23 = tri1.P3 - tri1.P2; // (needed later) 00383 n = cross_product( v21, v22 ); // normal vector of the plane 00384 a = n.x; b = n.y; c = n.z; 00385 r = n * tri1.P1; // right side of plane equation 00386 00387 // calculate intersection line 00388 // (G : x = g + lambda * t) 00389 00390 // if intersection line is not parallel to the X-axis, 00391 // set g.x = 0 and t.x = 1 00392 // ==> g.y, g.z and t.x, t.z 00393 00394 N = B*c - b*C; // determinant 00395 dim = 1; // assume intersection has dimension 1 00396 00397 if( test(N) ) // if not parallel to the X-axis 00398 { 00399 g.x = zero; 00400 g.y = (R*c - r*C)/N; 00401 g.z = (B*r - b*R)/N; 00402 t.x = one; 00403 t.y = (C*a - c*A)/N; 00404 t.z = (A*b - a*B)/N; 00405 } 00406 else 00407 { 00408 N = A*c - a*C; 00409 00410 if( test(N) ) // if not parallel to the Y-axis 00411 { 00412 g.x = (R*c - r*C) / N; 00413 g.y = zero; 00414 g.z = (A*r - a*R) / N; 00415 t.x = (C*b - c*B) / N; 00416 t.y = one; 00417 t.z = (B*a - b*A) / N; 00418 } 00419 else 00420 { 00421 N = A*b - a*B; 00422 00423 if( test(N) ) // if not parallel to the Z-axis 00424 { 00425 g.x = (R*b - r*B) / N; 00426 g.y = (A*r - a*R) / N; 00427 g.z = zero; 00428 t.x = (B*c - b*C) / N; 00429 t.y = (C*a - c*A) / N; 00430 t.z = one; 00431 } 00432 else // normal vectors of the two planes are linear dependent 00433 { 00434 // check if one point of the second triangle lies within the plane 00435 // of the first triangle 00436 if( test(A*tri1.P1.x + B*tri1.P1.y + C*tri1.P1.z - R) ) 00437 return 0; // no intersection 00438 else 00439 dim = 2; 00440 } 00441 } 00442 } 00443 00444 if( dim == 1 ) 00445 { 00446 // intersect intersection line of the planes with the border of the first 00447 // triangle. the result is an interval [l1,r1] in the parametric domain 00448 // of the intersection line. 00449 00450 // convenient notation 00451 P1 = tri0.P1; 00452 P2 = tri0.P2; 00453 P3 = tri0.P3; 00454 00455 // intersection line: X = g + mu * t 00456 // line through triangle edge P1P2: X = P1 + lambda * v11 00457 00458 init = false; 00459 result = RegularIntersectLines( P1, v11, g, t, &lambda, &mu ); 00460 if( result && (test(lambda) >= 0) && (compare(lambda,one)<=0) ) 00461 { 00462 init = true; 00463 l1 = mu; 00464 r1 = mu; 00465 } 00466 00467 // line through triangle edge P1P3: X = P1 + lambda * v12 00468 00469 result = RegularIntersectLines( P1, v12, g, t, &lambda, &mu ); 00470 if( result && (test(lambda) >= 0) && (compare(lambda,one)<=0) ) 00471 { 00472 if( init ) 00473 { 00474 if( compare(mu,l1) < 0 ) l1 = mu; 00475 else if( compare(mu,r1) > 0 ) r1 = mu; 00476 } 00477 else 00478 { 00479 init = true; 00480 l1 = mu; 00481 r1 = mu; 00482 } 00483 } 00484 00485 // line through triangle edge P2P3: X = P2 + lambda * v13 00486 00487 result = RegularIntersectLines( P2, v13, g, t, &lambda, &mu ); 00488 if( result && (test(lambda) >= 0) && (compare(lambda,one)<=0) ) 00489 { 00490 if( init ) 00491 { 00492 if( compare(mu,l1) < 0 ) l1 = mu; 00493 else if( compare(mu,r1) > 0 ) r1 = mu; 00494 } 00495 else 00496 { 00497 init = true; 00498 l1 = mu; 00499 r1 = mu; 00500 } 00501 } 00502 00503 if( !init ) 00504 return 0; 00505 cout << "l1 = " << l1.dump() << ", r1 = " << r1.dump() << "\n"; 00506 00507 // intersect intersection line of the planes with the border of the second 00508 // triangle. the result is an interval [l2,r2] in the parametric domain 00509 // of the intersection line. 00510 00511 // convenient notation 00512 P1 = tri1.P1; 00513 P2 = tri1.P2; 00514 P3 = tri1.P3; 00515 00516 // intersection line: X = g + mu * t 00517 // line through triangle edge P1P2: X = P1 + lambda * v21 00518 00519 init = false; 00520 result = RegularIntersectLines( P1, v21, g, t, &lambda, &mu ); 00521 if( result && (test(lambda) >= 0) && (compare(lambda,one)<=0) ) 00522 { 00523 init = true; 00524 l2 = mu; 00525 r2 = mu; 00526 } 00527 00528 // line through triangle edge P1P3: X = P1 + lambda * v22 00529 00530 result = RegularIntersectLines( P1, v22, g, t, &lambda, &mu ); 00531 if( result && (test(lambda) >= 0) && (compare(lambda,one)<=0) ) 00532 { 00533 if( init ) 00534 { 00535 if( compare(mu,l2) < 0 ) l2 = mu; 00536 else if( compare(mu,r2) > 0 ) r2 = mu; 00537 } 00538 else 00539 { 00540 init = true; 00541 l2 = mu; 00542 r2 = mu; 00543 } 00544 } 00545 00546 // line through triangle edge P2P3: X = P2 + lambda * v23 00547 00548 result = RegularIntersectLines( P2, v23, g, t, &lambda, &mu ); 00549 if( result && (test(lambda) >= 0) && (compare(lambda,one)<=0) ) 00550 { 00551 if( init ) 00552 { 00553 if( compare(mu,l2) < 0 ) l2 = mu; 00554 else if( compare(mu,r2) > 0 ) r2 = mu; 00555 } 00556 else 00557 { 00558 init = true; 00559 l2 = mu; 00560 r2 = mu; 00561 } 00562 } 00563 00564 if( !init ) 00565 return 0; 00566 cout << "l2 = " << l2.dump() << ", r2 = " << r2.dump() << "\n"; 00567 00568 // intersection of the intervals [l1,r1] and [l2,r2] delivers the 00569 // resulting segment of the intersection line 00570 00571 if(compare(l1,l2)>0) l = l1; else l = l2; 00572 if(compare(r1,r2)<0) r = r1; else r = r2; 00573 if( compare(r,l) < 0 ) 00574 return 0; 00575 00576 // calculate the endpoints of the intersection segment 00577 retP[0] = g + l * t; 00578 retP[1] = g + r * t; 00579 return 2; 00580 } 00581 00582 return 0; 00583 } |
|
|
|
Definition at line 593 of file guar_intersect.cpp.
00599 { 00600 point<rational> v11,v12,v13,n,N,v21,v22,v23,g,t; 00601 point<rational> P1,P2,P3; 00602 rational A,B,C,R,a,b,c,r,T; 00603 rational one(ULong(1)),zero; 00604 rational lambda,mu,l1,r1,l2,r2,l; 00605 bool result,init; 00606 int dim; 00607 bool inter1_12, inter1_13, inter1_23; 00608 bool inter2_12, inter2_13, inter2_23; 00609 int mid1,mid2,t0,t1,sign,side; 00610 point<rational> Pc1,Pc2; 00611 rational u,v,w; 00612 point2<rational> Pc1uv, Pc2uv; 00613 00614 // calculate plane equation for 1.triangle 00615 // (Ax + By + Cz = R) 00616 00617 v11 = tri1.P2 - tri1.P1; // 1. direction vector 00618 v12 = tri1.P3 - tri1.P1; // 2. direction vector 00619 v13 = tri1.P3 - tri1.P2; // (needed later) 00620 N = cross_product( v11, v12 ); // normal vector of the plane 00621 A = N.x; B = N.y; C = N.z; 00622 R = N * tri1.P1; // right side of plane equation 00623 // cout << "N = (" << N << ")\n"; 00624 00625 // calculate plane equation for 2.triangle 00626 // (ax + by + cz = r) 00627 v21 = tri2.P2 - tri2.P1; // 1. direction vector 00628 v22 = tri2.P3 - tri2.P1; // 2. direction vector 00629 v23 = tri2.P3 - tri2.P2; // (needed later) 00630 n = cross_product( v21, v22 ); // normal vector of the plane 00631 a = n.x; b = n.y; c = n.z; 00632 r = n * tri2.P1; // right side of plane equation 00633 00634 // calculate intersection line 00635 // (G : x = g + lambda * t) 00636 00637 // if intersection line is not parallel to the X-axis, 00638 // set g.x = 0 and t.x = 1 00639 // ==> g.y, g.z and t.x, t.z 00640 00641 T = B*c - b*C; // determinant 00642 dim = 1; // assume intersection has dimension 1 00643 00644 if( test(T) ) // if not parallel to the X-axis 00645 { 00646 g.x = zero; 00647 g.y = (R*c - r*C)/T; 00648 g.z = (B*r - b*R)/T; 00649 t.x = one; 00650 t.y = (C*a - c*A)/T; 00651 t.z = (A*b - a*B)/T; 00652 } 00653 else 00654 { 00655 T = A*c - a*C; 00656 00657 if( test(T) ) // if not parallel to the Y-axis 00658 { 00659 g.x = (R*c - r*C) / T; 00660 g.y = zero; 00661 g.z = (A*r - a*R) / T; 00662 t.x = (C*b - c*B) / T; 00663 t.y = one; 00664 t.z = (B*a - b*A) / T; 00665 } 00666 else 00667 { 00668 T = A*b - a*B; 00669 00670 if( test(T) ) // if not parallel to the Z-axis 00671 { 00672 g.x = (R*b - r*B) / T; 00673 g.y = (A*r - a*R) / T; 00674 g.z = zero; 00675 t.x = (B*c - b*C) / T; 00676 t.y = (C*a - c*A) / T; 00677 t.z = one; 00678 } 00679 else // normal vectors of the two planes are linear dependent 00680 { 00681 // check if one point of the second triangle lies within the plane 00682 // of the first triangle 00683 if( test(A*tri2.P1.x + B*tri2.P1.y + C*tri2.P1.z - R) ) 00684 return false; // no intersection 00685 else 00686 dim = 2; 00687 } 00688 } 00689 } 00690 00691 if( dim == 1 ) 00692 { 00693 // intersect intersection line of the planes with the border of the first 00694 // triangle. the result is an interval [l1,r1] in the parametric domain 00695 // of the intersection line. 00696 00697 mid1 = false; 00698 inter1_12 = false; 00699 inter1_13 = false; 00700 inter1_23 = false; 00701 00702 // convenient notation 00703 P1 = tri1.P1; 00704 P2 = tri1.P2; 00705 P3 = tri1.P3; 00706 00707 // intersection line: X = g + mu * t 00708 // line through triangle edge P1P2: X = P1 + lambda * v11 00709 00710 init = false; 00711 result = RegularIntersectLines( P1, v11, g, t, &lambda, &mu ); 00712 if( result ) 00713 { 00714 t0 = test(lambda); 00715 if( t0 >= 0 ) 00716 { 00717 t1 = compare(lambda,one); 00718 if( t1 <= 0 ) 00719 { 00720 inter1_12 = true; 00721 00722 init = true; 00723 l1 = mu; 00724 r1 = mu; 00725 00726 if( (t0 > 0) && (t1 < 0) ) 00727 { 00728 mid1 = true; 00729 Pc1 = tri1.P1; // will be used to classify the two halves of 00730 // tri 0 left and right of the intersection line 00731 // as lying above or below tri2 00732 } 00733 } 00734 } 00735 } 00736 00737 // line through triangle edge P1P3: X = P1 + lambda * v12 00738 00739 result = RegularIntersectLines( P1, v12, g, t, &lambda, &mu ); 00740 if( result ) 00741 { 00742 t0 = test(lambda); 00743 if( t0 >= 0 ) 00744 { 00745 t1 = compare(lambda,one); 00746 if( t1 <= 0 ) 00747 { 00748 inter1_13 = true; 00749 00750 if( init ) 00751 { 00752 if( compare(mu,l1) < 0 ) l1 = mu; 00753 else if( compare(mu,r1) > 0 ) r1 = mu; 00754 } 00755 else 00756 { 00757 init = true; 00758 l1 = mu; 00759 r1 = mu; 00760 } 00761 00762 if( (t0 > 0) && (t1 < 0) ) 00763 { 00764 mid1 = true; 00765 Pc1 = tri1.P1; // will be used to classify the two halves of 00766 // tri 0 left and right of the intersection line 00767 // as lying above or below tri2 00768 } 00769 } 00770 } 00771 } 00772 00773 // line through triangle edge P2P3: X = P2 + lambda * v13 00774 00775 result = RegularIntersectLines( P2, v13, g, t, &lambda, &mu ); 00776 if( result ) 00777 { 00778 t0 = test(lambda); 00779 if( t0 >= 0 ) 00780 { 00781 t1 = compare(lambda,one); 00782 if( t1 <= 0 ) 00783 { 00784 inter1_23 = true; 00785 00786 if( init ) 00787 { 00788 if( compare(mu,l1) < 0 ) l1 = mu; 00789 else if( compare(mu,r1) > 0 ) r1 = mu; 00790 } 00791 else 00792 { 00793 init = true; 00794 l1 = mu; 00795 r1 = mu; 00796 } 00797 00798 if( (t0 > 0) && (t1 < 0) ) 00799 { 00800 mid1 = true; 00801 Pc1 = tri1.P2; // will be used to classify the two halves of 00802 // tri 0 left and right of the intersection line 00803 // as lying above or below tri2 00804 } 00805 } 00806 } 00807 } 00808 00809 if( !init ) 00810 return 0; 00811 // cout << "l1 = " << l1.dump() << ", r1 = " << r1.dump() << "\n"; 00812 00813 // intersect intersection line of the planes with the border of the second 00814 // triangle. the result is an interval [l2,r2] in the parametric domain 00815 // of the intersection line. 00816 00817 mid2 = false; 00818 inter2_12 = false; 00819 inter2_13 = false; 00820 inter2_23 = false; 00821 00822 // convenient notation 00823 P1 = tri2.P1; 00824 P2 = tri2.P2; 00825 P3 = tri2.P3; 00826 00827 // intersection line: X = g + mu * t 00828 // line through triangle edge P1P2: X = P1 + lambda * v21 00829 00830 init = false; 00831 result = RegularIntersectLines( P1, v21, g, t, &lambda, &mu ); 00832 if( result ) 00833 { 00834 t0 = test(lambda); 00835 if( t0 >= 0 ) 00836 { 00837 t1 = compare(lambda,one); 00838 if( t1 <= 0 ) 00839 { 00840 inter2_12 = true; 00841 00842 init = true; 00843 l2 = mu; 00844 r2 = mu; 00845 00846 if( (t0 > 0) && (t1 < 0) ) 00847 { 00848 mid2 = true; 00849 Pc2 = tri2.P1; // will be used to classify the two halves of 00850 // tri 0 left and right of the intersection line 00851 // as lying above or below tri2 00852 } 00853 } 00854 } 00855 } 00856 00857 // line through triangle edge P1P3: X = P1 + lambda * v22 00858 00859 result = RegularIntersectLines( P1, v22, g, t, &lambda, &mu ); 00860 if( result ) 00861 { 00862 t0 = test(lambda); 00863 if( t0 >= 0 ) 00864 { 00865 t1 = compare(lambda,one); 00866 if( t1 <= 0 ) 00867 { 00868 inter2_13 = true; 00869 00870 if( init ) 00871 { 00872 if( compare(mu,l2) < 0 ) l2 = mu; 00873 else if( compare(mu,r2) > 0 ) r2 = mu; 00874 } 00875 else 00876 { 00877 init = true; 00878 l2 = mu; 00879 r2 = mu; 00880 } 00881 00882 if( (t0 > 0) && (t1 < 0) ) 00883 { 00884 mid2 = true; 00885 Pc2 = tri2.P1; // will be used to classify the two halves of 00886 // tri 0 left and right of the intersection line 00887 // as lying above or below tri2 00888 } 00889 } 00890 } 00891 } 00892 00893 // line through triangle edge P2P3: X = P2 + lambda * v23 00894 00895 result = RegularIntersectLines( P2, v23, g, t, &lambda, &mu ); 00896 if( result ) 00897 { 00898 t0 = test(lambda); 00899 if( t0 >= 0 ) 00900 { 00901 t1 = compare(lambda,one); 00902 if( t1 <= 0 ) 00903 { 00904 inter2_23 = true; 00905 00906 if( init ) 00907 { 00908 if( compare(mu,l2) < 0 ) l2 = mu; 00909 else if( compare(mu,r2) > 0 ) r2 = mu; 00910 } 00911 else 00912 { 00913 init = true; 00914 l2 = mu; 00915 r2 = mu; 00916 } 00917 00918 if( (t0 > 0) && (t1 < 0) ) 00919 { 00920 mid2 = true; 00921 Pc2 = tri2.P2; // will be used to classify the two halves of 00922 // tri 0 left and right of the intersection line 00923 // as lying above or below tri2 00924 } 00925 } 00926 } 00927 } 00928 00929 if( !init ) 00930 return 0; 00931 // cout << "l2 = " << l2.dump() << ", r2 = " << r2.dump() << "\n"; 00932 00933 // intersection of the intervals [l1,r1] and [l2,r2] delivers the 00934 // resulting segment of the intersection line 00935 00936 if(compare(l1,l2)>0) l = l1; else l = l2; 00937 if(compare(r1,r2)<0) r = r1; else r = r2; 00938 t1 = compare(r,l); 00939 if( t1 < 0 ) return false; 00940 else if( t1 == 0 ) // single point intersection 00941 { 00942 // retP[0] = g + l * t; 00943 return false; 00944 } 00945 00946 // calculate the endpoints of the intersection segment 00947 S[0] = g + l * t; 00948 S[1] = g + r * t; 00949 00950 // in triangle coordinates of triangle 1 00951 BarycentricCoordinates( tri1.P1, tri1.P2, tri1.P3, v11, v12, v13, N, 00952 S[0], &u, &v, &w ); 00953 S1uv[0] = u*tri1uv.P1 + v*tri1uv.P2 + w*tri1uv.P3; 00954 00955 BarycentricCoordinates( tri1.P1, tri1.P2, tri1.P3, v11, v12, v13, N, 00956 S[1], &u, &v, &w ); 00957 S1uv[1] = u*tri1uv.P1 + v*tri1uv.P2 + w*tri1uv.P3; 00958 00959 // calculate the edge/side pairs of the intersection segment in tri1 00960 if( mid1 ) 00961 { 00962 sign = test(n * Pc1 - r); 00963 00964 // this is a bit of a overkill since the coordinates of 'Pc1' in the 00965 // parametric domain are known 00966 BarycentricCoordinates( tri1.P1, tri1.P2, tri1.P3, v11, v12, v13, N, 00967 Pc1, &u, &v, &w ); 00968 Pc1uv = u*tri1uv.P1 + v*tri1uv.P2 + w*tri1uv.P3; 00969 00970 side = test( cross_product(S1uv[1]-S1uv[0],Pc1uv-S1uv[0]).z ); 00971 00972 gul::Assert<InternalError>( ndebug || (side != 0) && (sign != 0)); 00973 if( side < 0 ) side = 0; 00974 else if( side > 0 ) side = 1; 00975 S1flag[side] = sign; 00976 S1flag[!side] = -sign; 00977 } 00978 else 00979 { 00980 if( inter1_12 && inter1_13 ) 00981 Pc1 = tri1.P1; 00982 else if( inter1_12 && inter1_23 ) 00983 Pc1 = tri1.P2; 00984 else 00985 { 00986 gul::Assert<InternalError>( ndebug || (inter1_13 && inter1_23)); 00987 Pc1 = tri1.P3; 00988 } 00989 00990 sign = test(n * Pc1 - r); 00991 00992 // this is a bit of a overkill since the coordinates of 'Pc1' in the 00993 // parametric domain are known 00994 BarycentricCoordinates( tri1.P1, tri1.P2, tri1.P3, v11, v12, v13, N, 00995 Pc1, &u, &v, &w ); 00996 Pc1uv = u*tri1uv.P1 + v*tri1uv.P2 + w*tri1uv.P3; 00997 00998 side = test( cross_product(S1uv[1]-S1uv[0],Pc1uv-S1uv[0]).z ); 00999 01000 gul::Assert<InternalError>( ndebug || (side != 0) && (sign != 0)); 01001 S1flag[side] = sign; 01002 S1flag[!side] = 0; // undetermined 01003 } 01004 01005 // in triangle coordinates of triangle 2 01006 BarycentricCoordinates( tri2.P1, tri2.P2, tri2.P3, v21, v22, v23, n, 01007 S[0], &u, &v, &w ); 01008 S2uv[0] = u*tri2uv.P1 + v*tri2uv.P2 + w*tri2uv.P3; 01009 01010 BarycentricCoordinates( tri2.P1, tri2.P2, tri2.P3, v21, v22, v23, n, 01011 S[1], &u, &v, &w ); 01012 S2uv[1] = u*tri2uv.P1 + v*tri2uv.P2 + w*tri2uv.P3; 01013 01014 // calculate the edge/side pairs of the intersection segment in tri2 01015 if( mid2 ) 01016 { 01017 sign = test(N * Pc2 - R); 01018 01019 // this is a bit of a overkill since the coordinates of 'Pc1' in the 01020 // parametric domain are known 01021 BarycentricCoordinates( tri2.P1, tri2.P2, tri2.P3, v21, v22, v23, n, 01022 Pc2, &u, &v, &w ); 01023 Pc2uv = u*tri2uv.P1 + v*tri2uv.P2 + w*tri2uv.P3; 01024 01025 side = test( cross_product(S2uv[1]-S2uv[0],Pc2uv-S2uv[0]).z ); 01026 01027 gul::Assert<InternalError>( ndebug || (side != 0) && (sign != 0)); 01028 if( side < 0 ) side = 0; 01029 else if( side > 0 ) side = 1; 01030 S2flag[side] = sign; 01031 S2flag[!side] = -sign; 01032 } 01033 else 01034 { 01035 if( inter2_12 && inter2_13 ) 01036 Pc2 = tri2.P1; 01037 else if( inter2_12 && inter2_23 ) 01038 Pc2 = tri2.P2; 01039 else 01040 { 01041 gul::Assert<InternalError>( ndebug || (inter2_13 && inter2_23)); 01042 Pc2 = tri1.P3; 01043 } 01044 01045 sign = test(N * Pc2 - R); 01046 01047 // this is a bit of a overkill since the coordinates of 'Pc1' in the 01048 // parametric domain are known 01049 BarycentricCoordinates( tri2.P1, tri2.P2, tri2.P3, v21, v22, v23, n, 01050 Pc2, &u, &v, &w ); 01051 Pc2uv = u*tri2uv.P1 + v*tri2uv.P2 + w*tri2uv.P3; 01052 01053 side = test( cross_product(S2uv[1]-S2uv[0],Pc2uv-S2uv[0]).z ); 01054 01055 gul::Assert<InternalError>( ndebug || (side != 0) && (sign != 0)); 01056 S2flag[side] = sign; 01057 S2flag[!side] = 0; // undetermined 01058 } 01059 01060 // two intersection points 01061 return true; 01062 } 01063 01064 return false; 01065 } |
|
Definition at line 176 of file guar_exact.cpp.
00179 { 00180 uint64 l,z; 00181 unsigned int i,j; 00182 00183 if( (na == 0) || (nb == 0) ) 00184 { *nc = 0; return; } 00185 00186 for( i = 0; i < na; i++ ) 00187 c[i] = 0; 00188 00189 for( j = 0; j < nb; j++ ) 00190 { 00191 z = 0; 00192 for( i = 0; i < na; i++ ) 00193 { 00194 l = (uint64)a[i]*(uint64)b[j] + 00195 (uint64)c[i+j] + z; 00196 c[i+j] = (unsigned long)(l & 0xffffffff); 00197 z = (l >> 32) & 0xffffffff; 00198 } 00199 c[i+j] = (unsigned long)z; 00200 } 00201 00202 if( c[na+nb-1] == 0 ) *nc = na+nb-1; 00203 else *nc = na+nb; 00204 } |
|
Definition at line 153 of file guar_exact.cpp.
00156 { 00157 uint64 z, l, m; 00158 unsigned int i; 00159 00160 z = 0; 00161 m = (uint64)b; 00162 00163 for( i = 0; i < na; i++ ) 00164 { 00165 l = (uint64)a[i]*m + z; 00166 c[i] = (unsigned long)(l & 0xffffffff); 00167 z = (l >> 32) & 0xffffffff; 00168 } 00169 return((unsigned long)z); 00170 } |
|
|
|
Definition at line 87 of file guar_exact.cpp.
00090 { 00091 uint64 l,z=1; 00092 unsigned int i,len; 00093 int sign; 00094 00095 /* test if b > a */ 00096 00097 if( nb > na ) 00098 sign = -1; 00099 else if( na > nb ) 00100 sign = 0; 00101 else /* na == nb */ 00102 { 00103 i = na-1; 00104 while( (a[i] == b[i]) && (i > 0) ) 00105 i--; 00106 sign = b[i] > a[i] ? -1 : 0; 00107 } 00108 00109 if( sign ) /* calc b - a, na <= nb */ 00110 { 00111 for( i = 0; i < na; i++ ) 00112 { 00113 l = 0xffffffff + (uint64)b[i] - (uint64)a[i] + z; 00114 c[i] = (unsigned long)(l & 0xffffffff); 00115 z = (l >> 32) & 0xffffffff; 00116 } 00117 for( i = na; i < nb; i++ ) 00118 { 00119 l = 0xffffffff + (uint64)b[i] + z; 00120 c[i] = (unsigned long)(l & 0xffffffff); 00121 z = (l >> 32) & 0xffffffff; 00122 } 00123 len = nb; 00124 } 00125 else /* calc a - b, na >= nb */ 00126 { 00127 for( i = 0; i < nb; i++ ) 00128 { 00129 l = 0xffffffff + (uint64)a[i] - (uint64)b[i] + z; 00130 c[i] = (unsigned long)(l & 0xffffffff); 00131 z = (l >> 32) & 0xffffffff; 00132 } 00133 for( i = nb; i < na; i++ ) 00134 { 00135 l = 0xffffffff + (uint64)a[i] + z; 00136 c[i] = (unsigned long)(l & 0xffffffff); 00137 z = (l >> 32) & 0xffffffff; 00138 } 00139 len = na; 00140 } 00141 00142 /* strip leading zeros */ 00143 00144 for( ; (len > 0) && (c[len-1] == 0); len-- ); 00145 00146 *nc = len; 00147 return( sign ); 00148 } |
|
Definition at line 38 of file guar_exact.h.
00039 { 00040 int i; 00041 00042 if( na == 0 ) 00043 { 00044 t = (T)0.0; 00045 return; 00046 } 00047 t = (T)a[na-1]; 00048 00049 for( i = na-2; i >= 0; i-- ) 00050 { 00051 t = t*(T)(LL(0x100000000)) + (T)a[i]; 00052 } 00053 } |
|
|
|
Definition at line 580 of file guar_exact.cpp.
00581 { 00582 if( (a.m->m_na == 0) || (b.m->m_na == 0) ) /* a = 0 or b = 0 */ 00583 { 00584 rational c; 00585 return(c); 00586 } 00587 else 00588 { 00589 rational c( a.m->m_sign ^ b.m->m_sign, 00590 a.m->m_na + b.m->m_na, a.m->m_nb + b.m->m_nb ); 00591 00592 IntMult( a.m->m_na, a.m->m_a, b.m->m_na, b.m->m_a, 00593 &c.m->m_na, c.m->m_a ); 00594 00595 if( (a.m->m_nb != 0) && (b.m->m_nb != 0) ) 00596 { 00597 IntMult( a.m->m_nb, a.m->m_b, b.m->m_nb, b.m->m_b, 00598 &c.m->m_nb, c.m->m_b ); 00599 } 00600 else 00601 { 00602 if( b.m->m_nb != 0 ) 00603 { 00604 memcpy( c.m->m_b, b.m->m_b, b.m->m_nb*sizeof(unsigned long) ); 00605 c.m->m_nb = b.m->m_nb; 00606 } 00607 else if( a.m->m_nb != 0 ) 00608 { 00609 memcpy( c.m->m_b, a.m->m_b, a.m->m_nb*sizeof(unsigned long) ); 00610 c.m->m_nb = a.m->m_nb; 00611 } 00612 } 00613 00614 return(c); 00615 } 00616 } |
|
Definition at line 387 of file guar_exact.cpp.
00388 { 00389 Interval c; 00390 double f1,f2; 00391 00392 if( a.m_low >= 0.0 ) /* 0 <= alo <= ahi */ 00393 { 00394 if( b.m_low >= 0.0 ) /* 0 <= alo <= ahi, 0 <= blo <= bhi */ 00395 { 00396 c.m_low = a.m_low * b.m_low; 00397 c.m_high = a.m_high * b.m_high; 00398 } 00399 else /* blo < 0 */ 00400 { 00401 if( b.m_high >= 0 ) /* 0 <= alo <= ahi, blo < 0 <= bhi */ 00402 { 00403 c.m_low = a.m_high * b.m_low; 00404 c.m_high = a.m_high * b.m_high; 00405 } 00406 else /* 0 <= alo <= ahi, blo <= bhi < 0 */ 00407 { 00408 c.m_low = a.m_high * b.m_low; 00409 c.m_high = a.m_low * b.m_high; 00410 } 00411 } 00412 } 00413 else /* alo < 0 */ 00414 { 00415 if( a.m_high < 0.0 ) /* alo <= ahi < 0 */ 00416 { 00417 if( b.m_low >= 0 ) /* alo <= ahi < 0, 0 <= blo <= bhi */ 00418 { 00419 c.m_low = a.m_low * b.m_high; 00420 c.m_high = a.m_high * b.m_low; 00421 } 00422 else /* alo <= ahi < 0, blo < 0 */ 00423 { 00424 if( b.m_high < 0 ) /* alo <= ahi < 0, blo <= bhi < 0 */ 00425 { 00426 c.m_low = a.m_high * b.m_high; 00427 c.m_high = a.m_low * b.m_low; 00428 } 00429 else /* alo <= ahi < 0, blo < 0 <= bhi */ 00430 { 00431 c.m_low = a.m_low * b.m_high; 00432 c.m_high = a.m_high * b.m_low; 00433 } 00434 } 00435 } 00436 else /* alo < 0 <= ahi */ 00437 { 00438 if( b.m_low >= 0 ) /* alo < 0 <= ahi, 0 <= blo <= bhi */ 00439 { 00440 c.m_low = a.m_low * b.m_high; 00441 c.m_high = a.m_high * b.m_high; 00442 } 00443 else /* alo < 0 <= ahi, blo < 0 */ 00444 { 00445 if( b.m_high < 0 ) /* alo < 0 <= ahi, blo <= bhi < 0 */ 00446 { 00447 c.m_low = a.m_high * b.m_low; 00448 c.m_high = a.m_low * b.m_high; 00449 } 00450 else /* alo < 0 <= ahi, blo < 0 <= bhi */ 00451 { 00452 f1 = a.m_low * b.m_high; 00453 f2 = a.m_high * b.m_low; 00454 c.m_low = f1 < f2 ? f1 : f2; 00455 00456 f1 = a.m_low * b.m_low; 00457 f2 = a.m_high * b.m_high; 00458 c.m_high = f1 > f2 ? f1 : f2; 00459 } 00460 } 00461 } 00462 } 00463 00464 c.m_low = c.m_low - DBL_EPSILON*fabs(c.m_low); 00465 c.m_high = c.m_high + DBL_EPSILON*fabs(c.m_high); 00466 00467 return( c ); 00468 } |
|
Definition at line 413 of file guar_exact.h.
00414 { 00415 Interval c; 00416 00417 c.m_low = a.m_low + b.m_low; 00418 c.m_low = c.m_low - DBL_EPSILON*fabs(c.m_low); 00419 00420 c.m_high = a.m_high + b.m_high; 00421 c.m_high = c.m_high + DBL_EPSILON*fabs(c.m_high); 00422 00423 return( c ); 00424 } |
|
Definition at line 618 of file guar_exact.cpp.
00619 { 00620 unsigned long *a1b2,*a2b1,*a1b2_a2b1,*b1b2; 00621 unsigned int na1b2,na2b1,n_a1b2_a2b1,nb1b2; 00622 size_t size_a1b2,size_a2b1,size_a1b2_a2b1,size_b1b2; 00623 int sign,sign2; 00624 00625 if( A.m->m_na == 0 ) return(B); 00626 if( B.m->m_na == 0 ) return(A); 00627 00628 rational c; 00629 00630 if( B.m->m_nb == 0 ) 00631 { 00632 a1b2 = A.m->m_a; 00633 na1b2 = A.m->m_na; 00634 size_a1b2 = 0; 00635 } 00636 else 00637 { 00638 a1b2 = (unsigned long *)gust::PoolAlloc( 00639 (A.m->m_na+B.m->m_nb)*sizeof(unsigned long), &size_a1b2 ); 00640 if( a1b2 == NULL ) throw gul::PoolAllocError(); 00641 IntMult( A.m->m_na, A.m->m_a, B.m->m_nb, B.m->m_b, 00642 &na1b2, a1b2 ); 00643 } 00644 00645 if( A.m->m_nb == 0 ) 00646 { 00647 a2b1 = B.m->m_a; 00648 na2b1 = B.m->m_na; 00649 size_a2b1 = 0; 00650 } 00651 else 00652 { 00653 a2b1 = (unsigned long *)gust::PoolAlloc( 00654 (B.m->m_na+A.m->m_nb)*sizeof(unsigned long), &size_a2b1 ); 00655 if( a2b1 == NULL ) throw gul::PoolAllocError(); 00656 IntMult( B.m->m_na, B.m->m_a, A.m->m_nb, A.m->m_b, 00657 &na2b1, a2b1 ); 00658 } 00659 00660 n_a1b2_a2b1 = na1b2 > na2b1 ? na1b2 : na2b1; 00661 if( n_a1b2_a2b1 == 0 ) 00662 { 00663 if( size_a1b2 ) gust::PoolFree( a1b2, size_a1b2 ); 00664 if( size_a2b1 ) gust::PoolFree( a2b1, size_a2b1 ); 00665 return(c); 00666 } 00667 00668 sign = A.m->m_sign ^ B.m->m_sign; 00669 if( !sign ) n_a1b2_a2b1++; 00670 00671 a1b2_a2b1 = (unsigned long *)gust::PoolAlloc( 00672 n_a1b2_a2b1*sizeof(unsigned long), &size_a1b2_a2b1 ); 00673 if( a1b2_a2b1 == NULL ) throw gul::PoolAllocError(); 00674 00675 if( sign ) 00676 { 00677 sign2 = IntSub( na1b2, a1b2, na2b1, a2b1, &n_a1b2_a2b1, a1b2_a2b1 ); 00678 if( n_a1b2_a2b1 == 0 ) 00679 { 00680 gust::PoolFree( a1b2_a2b1, size_a1b2_a2b1 ); 00681 a1b2_a2b1 = NULL; 00682 } 00683 } 00684 else 00685 { 00686 sign2 = 0; 00687 IntAdd( na1b2, a1b2, na2b1, a2b1, &n_a1b2_a2b1, a1b2_a2b1 ); 00688 } 00689 00690 if( size_a1b2 ) gust::PoolFree( a1b2, size_a1b2 ); 00691 if( size_a2b1 ) gust::PoolFree( a2b1, size_a2b1 ); 00692 00693 if( n_a1b2_a2b1 == 0 ) /* numerator = 0 */ 00694 { 00695 sign = 0; 00696 b1b2 = NULL; 00697 nb1b2 = 0; 00698 size_b1b2 = 0; 00699 } 00700 else /* numerator != 0 */ 00701 { 00702 if( A.m->m_sign ) 00703 sign = sign2 ^ -1; 00704 else 00705 sign = sign2; 00706 00707 if( A.m->m_nb == 0 ) 00708 { 00709 if( B.m->m_nb == 0 ) 00710 { 00711 b1b2 = NULL; 00712 nb1b2 = 0; 00713 size_b1b2 = 0; 00714 } 00715 else 00716 { 00717 nb1b2 = B.m->m_nb; 00718 b1b2 = (unsigned long *)gust::PoolAlloc( 00719 nb1b2*sizeof(unsigned long), &size_b1b2 ); 00720 if( b1b2 == NULL ) throw gul::PoolAllocError(); 00721 memcpy( b1b2, B.m->m_b, nb1b2*sizeof(unsigned long) ); 00722 } 00723 } 00724 else if( B.m->m_nb == 0 ) 00725 { 00726 nb1b2 = A.m->m_nb; 00727 b1b2 = (unsigned long *)gust::PoolAlloc( 00728 nb1b2*sizeof(unsigned long), &size_b1b2 ); 00729 if( b1b2 == NULL ) throw gul::PoolAllocError(); 00730 memcpy( b1b2, A.m->m_b, nb1b2*sizeof(unsigned long) ); 00731 } 00732 else 00733 { 00734 b1b2 = (unsigned long *)gust::PoolAlloc( 00735 (A.m->m_nb+B.m->m_nb)*sizeof(unsigned long), &size_b1b2 ); 00736 if( b1b2 == NULL ) throw gul::PoolAllocError(); 00737 00738 IntMult( A.m->m_nb, A.m->m_b, B.m->m_nb, B.m->m_b, 00739 &nb1b2, b1b2 ); 00740 } 00741 } 00742 00743 c.m->m_sign = sign; 00744 c.m->m_na = n_a1b2_a2b1; 00745 c.m->m_size_a = size_a1b2_a2b1; 00746 c.m->m_a = a1b2_a2b1; 00747 c.m->m_nb = nb1b2; 00748 c.m->m_size_b = size_b1b2; 00749 c.m->m_b = b1b2; 00750 return(c); 00751 } |
|
Definition at line 426 of file guar_exact.h.
00427 { 00428 Interval c(-b.m_high,-b.m_low); 00429 00430 return(a+c); 00431 } |
|
Definition at line 767 of file guar_exact.cpp.
00768 { 00769 rational c; // (= 0) 00770 00771 if( A.m == B.m ) 00772 return c; 00773 00774 if( A.m->m_na == 0 ) /* if A=0, A+B returns B !!! */ 00775 { 00776 if( B.m->m_na != 0 ) 00777 { 00778 c = B.get_copy(); 00779 c.m->m_sign = B.m->m_sign ^ -1; 00780 } 00781 return c; 00782 } 00783 00784 B.m->negative(); 00785 c = A + B; 00786 B.m->negative(); 00787 00788 return(c); 00789 } |
|
Definition at line 433 of file guar_exact.h.
00434 { 00435 if( (b.m_low < 0.0) && (b.m_high > 0.0) ) 00436 throw gul::IntervalDivZeroError(); 00437 00438 Interval c(1.0/b.m_high,1.0/b.m_low); 00439 00440 return(a*c); 00441 } |
|
Definition at line 753 of file guar_exact.cpp.
00754 { 00755 rational c; 00756 00757 if( A.m == B.m ) 00758 return rational(ULong(1)); 00759 00760 B.m->reciprocal(); 00761 c = A * B; 00762 B.m->reciprocal(); 00763 00764 return(c); 00765 } |
|
Definition at line 46 of file guar_intersect.cpp.
00054 { 00055 rational A0,A1,A2,B0,B1,B2; 00056 rational a0,a1,a2,b0,b1,b2; 00057 rational N1,N2,N3; 00058 00059 // more convenient notation 00060 A0 = A.x; A1 = A.y; A2 = A.z; 00061 B0 = B.x; B1 = B.y; B2 = B.z; 00062 a0 = a.x; a1 = a.y; a2 = a.z; 00063 b0 = b.x; b1 = b.y; b2 = b.z; 00064 00065 N1 = B1*b0 - b1*B0; 00066 00067 if( test(N1) ) // calculation without z (for exact arithmetic the 00068 { // goodness of N1 doesn't matter) 00069 *lambda = (b0*(a1-A1) - b1*(a0-A0)) / N1; 00070 *mu = (B0*(a1-A1) - B1*(a0-A0)) / N1; 00071 } 00072 else 00073 { 00074 N2 = B2*b0 - b2*B0; 00075 00076 if( test(N2) ) // calculation without y (for exact arithmetic the 00077 { // goodness of N2 doesn't matter) 00078 *lambda = (b0*(a2-A2) - b2*(a0-A0)) / N2; 00079 *mu = (B0*(a2-A2) - B2*(a0-A0)) / N2; 00080 } 00081 else 00082 { 00083 N3 = B2*b1 - b2*B1; 00084 00085 if( test(N3) ) // calculation without y (for exact arithmetic the 00086 { // goodness of N3 doesn't matter) 00087 *lambda = (b1*(a2-A2) - b2*(a1-A1)) / N3; 00088 *mu = (B1*(a2-A2) - B2*(a1-A1)) / N3; 00089 } 00090 else 00091 { 00092 return false; // no intersection point or lines colinear 00093 } 00094 } 00095 } 00096 return true; 00097 } |
|
Definition at line 444 of file guar_exact.h.
00445 { 00446 Interval c; 00447 00448 c.m_low = sqrt(a.m_low); 00449 c.m_low = c.m_low - DBL_EPSILON*fabs(c.m_low); 00450 00451 c.m_high = sqrt(a.m_high); 00452 c.m_high = c.m_high + DBL_EPSILON*fabs(c.m_high); 00453 00454 return( c ); 00455 } |
|
Definition at line 465 of file guar_exact.h.
00466 { 00467 Interval c = a-b; 00468 return Test(c); 00469 } |
|
Definition at line 457 of file guar_exact.h.
00458 { 00459 if( a.m_high < 0.0 ) return(-1); 00460 if( a.m_low > 0.0 ) return(+1); 00461 00462 return(0); /* dunno :) */ 00463 } |