00001
00002
00003
00004 #include <stdio.h>
00005 #include <math.h>
00006 #include "geo.h"
00007
00008 #ifndef real
00009 #define real double
00010 #endif
00011
00012 static real PFSGeoTolerance = 0.0001 ;
00013
00014 #define RAD(x) ((x)*(acos(-1.0)/180.0))
00015
00016 #define dsin(x) sin(RAD(x))
00017 #define dcos(x) cos(RAD(x))
00018 #define dtan(x) tan(RAD(x))
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 PFSGeoPredicate PFSGeoIntscPolyLine( line, spar )
00033
00034 PFSGeoSurfPar line[] ;
00035 PFSGeoSurfPar *spar ;
00036 {
00037 real u0,v0,u1,v1 ;
00038 real ua,va,ub,vb ;
00039 real max_u,min_u ;
00040 real max_v,min_v ;
00041
00042 u0 = line[0].u ;
00043 v0 = line[0].v ;
00044 u1 = line[1].u ;
00045 v1 = line[1].v ;
00046
00047
00048
00049 max_u = (u0 > u1) ? u0 : u1 ;
00050 min_u = (u0 < u1) ? u0 : u1 ;
00051 max_v = (v0 > v1) ? v0 : v1 ;
00052 min_v = (v0 < v1) ? v0 : v1 ;
00053
00054
00055
00056
00057
00058
00059
00060 if( v0 == v1 ) return( PFSGeoFalse ) ;
00061
00062
00063
00064
00065 if( (spar->v < min_v) || (spar->v >= max_v) ) return( PFSGeoFalse ) ;
00066
00067
00068
00069
00070 if( (u0 == u1) && (spar->u < u0) ) return( PFSGeoFalse ) ;
00071
00072
00073
00074
00075 if( u0 != u1 ) {
00076 if( ((u1 > u0) && (v1 > v0)) || ((u1 < u0) && (v1 > v0)) ) {
00077 ua = u0 ; va = v0 ;
00078 ub = u1 ; vb = v1 ;
00079 }
00080 else {
00081 ua = u1 ; va = v1 ;
00082 ub = u0 ; vb = v0 ;
00083 }
00084
00085 if( ((spar->v - va) * (ub - ua)) > ((spar->u - ua) * (vb - va)) ) {
00086 return( PFSGeoFalse ) ;
00087 }
00088 }
00089
00090
00091
00092
00093
00094
00095 return( PFSGeoTrue ) ;
00096 }
00097
00098
00099
00100
00101
00102
00103
00104 void PFSGeoSetTolerance( real tol )
00105 {
00106 PFSGeoTolerance = tol ;
00107 }
00108
00109 real PFSGeoGetTolerance()
00110 {
00111 return( PFSGeoTolerance ) ;
00112 }
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131 PFSGeoPredicate PFSGeoIsInsidePoly( poly, spar )
00132
00133 PFSGeoPoly *poly ;
00134 PFSGeoSurfPar *spar ;
00135 {
00136 PFSGeoSurfPar edge[2] ;
00137 PFSGeoPoint local_pt ;
00138
00139 int n_cross = 0 ;
00140 int i ;
00141
00142 for( i = 0; i < poly->n_verts; i++ ) {
00143
00144 local_pt.x = poly->verts[i].x - poly->nplane.a.x ;
00145 local_pt.y = poly->verts[i].y - poly->nplane.a.y ;
00146 local_pt.z = poly->verts[i].z - poly->nplane.a.z ;
00147 edge[0].u = PFSGeoDotProd( &local_pt, &poly->nplane.u ) ;
00148 edge[0].v = PFSGeoDotProd( &local_pt, &poly->nplane.v ) ;
00149
00150 local_pt.x = poly->verts[(i+1) % poly->n_verts].x - poly->nplane.a.x ;
00151 local_pt.y = poly->verts[(i+1) % poly->n_verts].y - poly->nplane.a.y ;
00152 local_pt.z = poly->verts[(i+1) % poly->n_verts].z - poly->nplane.a.z ;
00153 edge[1].u = PFSGeoDotProd( &local_pt, &poly->nplane.u ) ;
00154 edge[1].v = PFSGeoDotProd( &local_pt, &poly->nplane.v ) ;
00155
00156 if( PFSGeoIntscPolyLine( edge, spar ) == PFSGeoTrue ) n_cross++ ;
00157 }
00158
00159 if( (n_cross % 2) == 0 ) return( PFSGeoFalse ) ;
00160 else return( PFSGeoTrue ) ;
00161 }
00162
00163
00164
00165
00166
00167
00168
00169
00170 PFSGeoPredicate PFSGeoIsOnPolyBdry( poly, pt )
00171
00172 PFSGeoPoly *poly ;
00173 PFSGeoPoint *pt ;
00174 {
00175 PFSGeoLine edge ;
00176 PFSGeoPoint clst ;
00177 PFSGeoPointPar par ;
00178 int is_on_bdry = 0 ;
00179 int i ;
00180
00181 for( i = 0; i < poly->n_verts; i++ ) {
00182 PFSGeoGenLine( &poly->verts[i], &poly->verts[(i+1) % poly->n_verts],
00183 &edge ) ;
00184 PFSGeoClstPtLine( &edge, pt, &clst, &par ) ;
00185 if( ( (real)par > - PFSGeoTolerance )
00186 && ( (real)par < 1.0 + PFSGeoTolerance )
00187 && ( PFSGeoDist( pt, &clst ) < PFSGeoTolerance ) ) {
00188 is_on_bdry = 1 ;
00189 break ;
00190 }
00191 }
00192
00193 if( is_on_bdry == 0 ) return( PFSGeoFalse ) ;
00194 else return( PFSGeoTrue ) ;
00195 }
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277 void PFSGeoGenLine( pt0, pt1, line )
00278 PFSGeoPoint *pt0, *pt1 ;
00279 PFSGeoLine *line ;
00280 {
00281 line->d = *pt0 ;
00282 line->e.x = pt1->x - pt0->x ;
00283 line->e.y = pt1->y - pt0->y ;
00284 line->e.z = pt1->z - pt0->z ;
00285 }
00286
00287
00288 void PFSGeoGenPlane( pt0, pt1, pt2, plane )
00289 PFSGeoPoint *pt0, *pt1, *pt2 ;
00290 PFSGeoPlane *plane ;
00291 {
00292 plane->a = *pt0 ;
00293 plane->b.x = pt1->x - pt0->x ;
00294 plane->b.y = pt1->y - pt0->y ;
00295 plane->b.z = pt1->z - pt0->z ;
00296 plane->c.x = pt2->x - pt0->x ;
00297 plane->c.y = pt2->y - pt0->y ;
00298 plane->c.z = pt2->z - pt0->z ;
00299 }
00300
00301
00302 void PFSGeoGenPlanEqn( pt0, pt1, pt2, plan_eqn )
00303 PFSGeoPoint *pt0, *pt1, *pt2 ;
00304 PFSGeoPlanEqn *plan_eqn ;
00305 {
00306 PFSGeoPoint vec1, vec2, normal ;
00307 real length ;
00308
00309 vec1.x = pt1->x - pt0->x ;
00310 vec1.y = pt1->y - pt0->y ;
00311 vec1.z = pt1->z - pt0->z ;
00312 vec2.x = pt2->x - pt0->x ;
00313 vec2.y = pt2->y - pt0->y ;
00314 vec2.z = pt2->z - pt0->z ;
00315
00316 normal.x = (vec1.y * vec2.z) - (vec1.z * vec2.y) ;
00317 normal.y = (vec1.z * vec2.x) - (vec1.x * vec2.z) ;
00318 normal.z = (vec1.x * vec2.y) - (vec1.y * vec2.x) ;
00319
00320 length = sqrt( normal.x*normal.x
00321 + normal.y*normal.y
00322 + normal.z*normal.z ) ;
00323
00324 plan_eqn->a = normal.x / length ;
00325 plan_eqn->b = normal.y / length ;
00326 plan_eqn->c = normal.z / length ;
00327 plan_eqn->d = ( - plan_eqn->a * pt0->x
00328 - plan_eqn->b * pt0->y
00329 - plan_eqn->c * pt0->z ) ;
00330
00331 return;
00332 }
00333
00334
00335 PFSGeoStatus PFSGeoGenPoly( n_verts, verts, plane )
00336 int *n_verts ;
00337 PFSGeoPoint *verts ;
00338 PFSGeoNormPlane *plane ;
00339 {
00340 real e_size ;
00341
00342 if ( PFSGeoPolyNormal( n_verts, verts, &plane->n ) != PFSGeoValid )
00343 return( PFSGeoInvalid ) ;
00344
00345 e_size = PFSGeoDist( &verts[0], &verts[*n_verts-1] ) ;
00346 plane->a = verts[0] ;
00347
00348 plane->u.x = (verts[*n_verts-1].x - verts[0].x) / e_size ;
00349 plane->u.y = (verts[*n_verts-1].y - verts[0].y) / e_size ;
00350 plane->u.z = (verts[*n_verts-1].z - verts[0].z) / e_size ;
00351
00352 PFSGeoCrossProd( &plane->n, &plane->u, &plane->v ) ;
00353 return( PFSGeoValid );
00354 }
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390 void PFSGeoEvalLine( par, line, pt )
00391 PFSGeoPointPar *par ;
00392 PFSGeoLine *line ;
00393 PFSGeoPoint *pt ;
00394 {
00395 pt->x = line->d.x + (*par * line->e.x) ;
00396 pt->y = line->d.y + (*par * line->e.y) ;
00397 pt->z = line->d.z + (*par * line->e.z) ;
00398 return ;
00399 }
00400
00401
00402 void PFSGeoEvalPlane( par, plane, pt )
00403 PFSGeoSurfPar *par ;
00404 PFSGeoPlane *plane ;
00405 PFSGeoPoint *pt ;
00406 {
00407 pt->x = plane->a.x + (par->u * plane->b.x) + (par->v * plane->c.x) ;
00408 pt->y = plane->a.y + (par->u * plane->b.y) + (par->v * plane->c.y) ;
00409 pt->z = plane->a.z + (par->u * plane->b.z) + (par->v * plane->c.z) ;
00410 }
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531 real PFSGeoDotProd( vec0, vec1 )
00532 PFSGeoPoint *vec0, *vec1 ;
00533 {
00534 return ( (vec0->x * vec1->x) +
00535 (vec0->y * vec1->y) +
00536 (vec0->z * vec1->z) ) ;
00537 }
00538
00539 void PFSGeoCrossProd( in0, in1, out )
00540 PFSGeoPoint *in0, *in1, *out ;
00541 {
00542 out->x = (in0->y * in1->z) - (in0->z * in1->y) ;
00543 out->y = (in0->z * in1->x) - (in0->x * in1->z) ;
00544 out->z = (in0->x * in1->y) - (in0->y * in1->x) ;
00545 }
00546
00547 real PFSGeoTripleProd( vec0, vec1, vec2 )
00548 PFSGeoPoint *vec0, *vec1, *vec2 ;
00549 {
00550 PFSGeoPoint tmp ;
00551
00552 PFSGeoCrossProd( vec0, vec1, &tmp ) ;
00553 return( PFSGeoDotProd( &tmp, vec2 ) ) ;
00554 }
00555
00556 PFSGeoPredicate PFSGeoNullVec( vec, tolerance )
00557 PFSGeoPoint *vec ;
00558 real *tolerance ;
00559 {
00560 if (( fabs( vec->x ) < *tolerance ) &&
00561 ( fabs( vec->y ) < *tolerance ) &&
00562 ( fabs( vec->z ) < *tolerance ))
00563 return( PFSGeoTrue ) ;
00564 else
00565 return( PFSGeoFalse );
00566 }
00567
00568 real PFSGeoVecLen( vec )
00569 PFSGeoPoint *vec ;
00570 {
00571 return ( sqrt( (vec->x * vec->x) +
00572 (vec->y * vec->y) +
00573 (vec->z * vec->z) ) ) ;
00574 }
00575
00576
00577 void PFSGeoVecNormalize( vec, n )
00578 PFSGeoPoint *vec ;
00579 PFSGeoPoint *n ;
00580 {
00581 real len ;
00582
00583 len = PFSGeoVecLen( vec ) ;
00584
00585 n->x = vec->x / len ;
00586 n->y = vec->y / len ;
00587 n->z = vec->z / len ;
00588 }
00589
00590
00591 real PFSGeoDist( in0,in1 )
00592 PFSGeoPoint *in0 ;
00593 PFSGeoPoint *in1 ;
00594 {
00595 PFSGeoPoint tmp ;
00596
00597 tmp.x = in1->x - in0->x ;
00598 tmp.y = in1->y - in0->y ;
00599 tmp.z = in1->z - in0->z ;
00600
00601 return( PFSGeoVecLen( &tmp ) ) ;
00602 }
00603
00604 void PFSGeoDiffVec( in0, in1, out)
00605 PFSGeoPoint *in0, *in1, *out ;
00606
00607 {
00608 out->x = in0->x - in1->x ;
00609 out->y = in0->y - in1->y ;
00610 out->z = in0->z - in1->z ;
00611 return ;
00612 }
00613
00614 void PFSGeoSumVec( in0, in1, out)
00615 PFSGeoPoint *in0, *in1, *out ;
00616
00617 {
00618 out->x = in0->x + in1->x ;
00619 out->y = in0->y + in1->y ;
00620 out->z = in0->z + in1->z ;
00621 return ;
00622 }
00623
00624
00625 void PFSGeoProdScalVec ( in, csi, out )
00626 PFSGeoPoint *in, *out ;
00627 real *csi ;
00628 {
00629 out->x = in->x * (*csi) ;
00630 out->y = in->y * (*csi) ;
00631 out->z = in->z * (*csi) ;
00632 return ;
00633 }
00634
00635
00636 void PFSGeoLinCombVec( in0, csi0, in1, csi1, out )
00637 PFSGeoPoint *in0, *in1, *out ;
00638 real *csi0, *csi1 ;
00639 {
00640 out->x = in0->x * (*csi0) + in1->x * (*csi1) ;
00641 out->y = in0->y * (*csi0) + in1->y * (*csi1) ;
00642 out->z = in0->z * (*csi0) + in1->z * (*csi1) ;
00643
00644 return ;
00645
00646 }
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708 void PFSGeoRotateX( angle, in, out )
00709 real *angle ;
00710 PFSGeoPoint *in, *out ;
00711 {
00712 real s, c ;
00713
00714 s = dsin( *angle) ; c = dcos( *angle ) ;
00715 out->x = in->x ;
00716 out->y = (in->y * c) - (in->z * s) ;
00717 out->z = (in->y * s) + (in->z * c) ;
00718 }
00719
00720
00721 void PFSGeoRotateY( angle, in, out )
00722 real *angle ;
00723 PFSGeoPoint *in, *out ;
00724 {
00725 real s, c ;
00726
00727 s = dsin( *angle) ; c = dcos( *angle ) ;
00728 out->x = (in->x * c) - (in->z * s) ;
00729 out->y = in->y ;
00730 out->z = (in->x * s) + (in->z * c) ;
00731 }
00732
00733
00734 void PFSGeoRotateZ( angle, in, out )
00735 real *angle ;
00736 PFSGeoPoint *in, *out ;
00737 {
00738 real s, c ;
00739
00740 s = dsin( *angle ) ; c = dcos( *angle ) ;
00741 out->x = (in->x * c) - (in->y * s) ;
00742 out->y = (in->x * s) + (in->y * c) ;
00743 out->z = in->z ;
00744 }
00745
00746
00747 void PFSGeoRotateAxis( axis, angle, in, out )
00748 PFSGeoPoint *axis ;
00749 real *angle ;
00750 PFSGeoPoint *in, *out ;
00751 {
00752 PFSGeoPoint u ;
00753 real s, c ;
00754 real r[3][3] ;
00755
00756 s = dsin( *angle ) ; c = dcos( *angle ) ;
00757
00758 PFSGeoVecNormalize( axis, &u ) ;
00759
00760 r[0][0] = u.x*u.x + c * (1.0 - u.x*u.x) ;
00761 r[0][1] = u.x*u.y*(1.0 - c) - u.z*s ;
00762 r[0][2] = u.z*u.x*(1.0 - c) + u.y*s ;
00763
00764 r[1][0] = u.x*u.y*(1.0 - c) + u.z*s ;
00765 r[1][1] = u.y*u.y + c * (1.0 - u.y*u.y) ;
00766 r[1][2] = u.y*u.z*(1.0 - c) - u.x*s ;
00767
00768 r[2][0] = u.z*u.x*(1.0 - c) - u.y*s ;
00769 r[2][1] = u.y*u.z*(1.0 - c) + u.x*s ;
00770 r[2][2] = u.z*u.z + c * (1.0 - u.z*u.z) ;
00771
00772 out->x = r[0][0]*in->x + r[0][1]*in->y + r[0][2]*in->z ;
00773 out->y = r[1][0]*in->x + r[1][1]*in->y + r[1][2]*in->z ;
00774 out->z = r[2][0]*in->x + r[2][1]*in->y + r[2][2]*in->z ;
00775 }
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826 PFSGeoStatus PFSGeoIntscLinePlane( line, plane, pt, ptpar, spar )
00827 PFSGeoLine *line ;
00828 PFSGeoPlane *plane ;
00829 PFSGeoPoint *pt ;
00830 PFSGeoPointPar *ptpar ;
00831 PFSGeoSurfPar *spar ;
00832 {
00833 real size ;
00834 PFSGeoPoint b_cross_c, c_cross_e, b_cross_e ;
00835 real b_x_c_dot_e, c_x_e_dot_b, b_x_e_dot_c ;
00836
00837 size = PFSGeoVecLen( &plane->b ) ;
00838
00839 PFSGeoCrossProd( &plane->b, &plane->c, &b_cross_c ) ;
00840 PFSGeoCrossProd( &plane->c, &line->e, &c_cross_e ) ;
00841 PFSGeoCrossProd( &plane->b, &line->e, &b_cross_e ) ;
00842
00843 b_x_c_dot_e = PFSGeoDotProd( &b_cross_c, &line->e ) ;
00844 c_x_e_dot_b = PFSGeoDotProd( &c_cross_e, &plane->b ) ;
00845 b_x_e_dot_c = PFSGeoDotProd( &b_cross_e, &plane->c ) ;
00846
00847 if (( fabs(b_x_c_dot_e) < PFSGeoTolerance*size ) ||
00848 ( fabs(c_x_e_dot_b) < PFSGeoTolerance*size ) ||
00849 ( fabs(b_x_e_dot_c) < PFSGeoTolerance*size ))
00850 return( PFSGeoInvalid ) ;
00851 else {
00852 *ptpar = ( PFSGeoDotProd( &b_cross_c, &plane->a ) -
00853 PFSGeoDotProd( &b_cross_c, &line->d ) ) /
00854 b_x_c_dot_e ;
00855 PFSGeoEvalLine( ptpar, line, pt ) ;
00856 spar->u = ( PFSGeoDotProd( &c_cross_e, &line->d ) -
00857 PFSGeoDotProd( &c_cross_e, &plane->a ) ) /
00858 c_x_e_dot_b ;
00859 spar->v = ( PFSGeoDotProd( &b_cross_e, &line->d ) -
00860 PFSGeoDotProd( &b_cross_e, &plane->a ) ) /
00861 b_x_e_dot_c ;
00862 return( PFSGeoValid ) ;
00863 }
00864 }
00865
00866
00867
00868 PFSGeoStatus PFSGeoIntscLinePoly( line, poly, pt, ptpar, spar )
00869 PFSGeoLine *line ;
00870 PFSGeoPoly *poly ;
00871 PFSGeoPoint *pt ;
00872 PFSGeoPointPar *ptpar ;
00873 PFSGeoSurfPar *spar ;
00874 {
00875 PFSGeoPlane plane ;
00876
00877
00878
00879
00880 plane.a = poly->nplane.a ;
00881 plane.b = poly->nplane.u ;
00882 plane.c = poly->nplane.v ;
00883 if( PFSGeoIntscLinePlane( line, &plane, pt, ptpar, spar ) == PFSGeoValid ) {
00884
00885
00886
00887
00888 if( PFSGeoIsInsidePoly( poly, spar ) == PFSGeoTrue ) {
00889 return( PFSGeoValid ) ;
00890 }
00891 else {
00892 if( PFSGeoIsOnPolyBdry( poly, pt ) == PFSGeoTrue ) {
00893 return( PFSGeoValid ) ;
00894 }
00895 else {
00896 return( PFSGeoInvalid ) ;
00897 }
00898 }
00899 }
00900 else return( PFSGeoInvalid ) ;
00901 }
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954 PFSGeoStatus PFSGeoPolyNormal( n_verts, verts, n )
00955 int *n_verts ;
00956 PFSGeoPoint *verts ;
00957 PFSGeoPoint *n ;
00958 {
00959 real e_size;
00960 real n_size;
00961 int i;
00962
00963 n->x = 0.0 ; n->y = 0.0 ; n->z = 0.0 ;
00964
00965 for ( i=2 ; i < *n_verts ; i++ ) {
00966 n->x += (verts[i ].y - verts[0].y) *
00967 (verts[i-1].z - verts[0].z) -
00968 (verts[i ].z - verts[0].z) *
00969 (verts[i-1].y - verts[0].y) ;
00970
00971 n->y += -(verts[i ].x - verts[0].x) *
00972 (verts[i-1].z - verts[0].z) +
00973 (verts[i ].z - verts[0].z) *
00974 (verts[i-1].x - verts[0].x) ;
00975
00976 n->z += (verts[i ].x - verts[0].x) *
00977 (verts[i-1].y - verts[0].y) -
00978 (verts[i ].y - verts[0].y) *
00979 (verts[i-1].x - verts[0].x) ;
00980 }
00981
00982
00983
00984
00985 e_size = PFSGeoDist( &verts[0], &verts[1] ) ;
00986 n_size = PFSGeoVecLen( n ) ;
00987
00988 if (n_size/e_size > PFSGeoTolerance) {
00989 n->x /= n_size ;
00990 n->y /= n_size ;
00991 n->z /= n_size ;
00992 return( PFSGeoValid ) ;
00993 }
00994 else
00995 return( PFSGeoInvalid );
00996 }
00997
00998
00999 PFSGeoStatus PFSGeoLstSqrPlanEqn( num_pts, pts, plan_eqn )
01000 int *num_pts ;
01001 PFSGeoPoint *pts ;
01002 PFSGeoPlanEqn *plan_eqn ;
01003
01004 {
01005 real a11,a12,a13,a22,a23,a33 ;
01006 real b11,b12,b13,b22,b23,b33 ;
01007 real sum_x,sum_y,sum_z ;
01008 real div,norm ;
01009 PFSGeoPoint seg1, seg2, cross ;
01010 int i ;
01011
01012
01013
01014 a11 = 0.0 ; a12 = 0.0 ; a13 = 0.0 ;
01015 a22 = 0.0 ; a23 = 0.0 ; a33 = 0.0 ;
01016
01017 sum_x = 0.0 ; sum_y = 0.0 ; sum_z = 0.0 ;
01018
01019 for ( i = 0; i < *num_pts; i++ ) {
01020 a11 = a11 + pts[i].x * pts[i].x ;
01021 a12 = a12 + pts[i].x * pts[i].y ;
01022 a13 = a13 + pts[i].x * pts[i].z ;
01023 a22 = a22 + pts[i].y * pts[i].y ;
01024 a23 = a23 + pts[i].y * pts[i].z ;
01025 a33 = a33 + pts[i].z * pts[i].z ;
01026
01027 sum_x = sum_x + pts[i].x ;
01028 sum_y = sum_y + pts[i].y ;
01029 sum_z = sum_z + pts[i].z ;
01030 }
01031
01032
01033
01034 div = a11 * ( a22*a33 - a23*a23 ) + a12 * ( a13*a23 - a12*a33 ) +
01035 a13 * ( a12*a23 - a13*a22 ) ;
01036
01037
01038
01039
01040
01041
01042
01043 if ( fabs(div) < PFSGeoTolerance ) {
01044
01045
01046
01047
01048 for( i = 0; i < *num_pts - 2; i++ ) {
01049 PFSGeoDiffVec( &pts[i+1], &pts[i], &seg1 ) ;
01050 PFSGeoDiffVec( &pts[i+2], &pts[i+1], &seg2 ) ;
01051 PFSGeoCrossProd( &seg1, &seg2, &cross ) ;
01052 if( PFSGeoNullVec( &cross, &PFSGeoTolerance ) == PFSGeoFalse ) {
01053 PFSGeoGenPlanEqn( &pts[i], &pts[i+1], &pts[i+2], plan_eqn ) ;
01054 return( PFSGeoValid ) ;
01055 }
01056 }
01057
01058 return( PFSGeoInvalid ) ;
01059 }
01060 else {
01061
01062
01063 b11 = ( a22*a33 - a23*a23 ) / div ;
01064 b12 = ( a13*a23 - a12*a33 ) / div ;
01065 b13 = ( a12*a23 - a13*a22 ) / div ;
01066 b22 = ( a11*a33 - a13*a13 ) / div ;
01067 b23 = ( a12*a13 - a11*a23 ) / div ;
01068 b33 = ( a11*a22 - a12*a12 ) / div ;
01069
01070
01071
01072 plan_eqn->a = b11*sum_x + b12*sum_y + b13*sum_z ;
01073 plan_eqn->b = b12*sum_x + b22*sum_y + b23*sum_z ;
01074 plan_eqn->c = b13*sum_x + b23*sum_y + b33*sum_z ;
01075
01076
01077
01078 norm = sqrt( plan_eqn->a * plan_eqn->a + plan_eqn->b * plan_eqn->b +
01079 plan_eqn->c * plan_eqn->c ) ;
01080
01081 plan_eqn->a /= norm ;
01082 plan_eqn->b /= norm ;
01083 plan_eqn->c /= norm ;
01084 plan_eqn->d = - 1.0 / norm ;
01085 }
01086
01087 return( PFSGeoValid ) ;
01088 }
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167 void PFSGeoClstPtLine( line, pt, clst, par )
01168 PFSGeoLine *line ;
01169 PFSGeoPoint *pt, *clst ;
01170 PFSGeoPointPar *par ;
01171 {
01172 PFSGeoPoint local_pt ;
01173
01174 local_pt.x = pt->x - line->d.x ;
01175 local_pt.y = pt->y - line->d.y ;
01176 local_pt.z = pt->z - line->d.z ;
01177
01178 *par = PFSGeoDotProd( &local_pt, &line->e ) /
01179 PFSGeoDotProd( &line->e, &line->e ) ;
01180
01181 PFSGeoEvalLine( par, line, clst ) ;
01182 }
01183
01184
01185 void PFSGeoClstPtNormPlane( plane, pt, clst, spar )
01186 PFSGeoNormPlane *plane ;
01187 PFSGeoPoint *pt, *clst ;
01188 PFSGeoSurfPar *spar ;
01189 {
01190 PFSGeoPoint local_pt ;
01191
01192 local_pt.x = pt->x - plane->a.x ;
01193 local_pt.y = pt->y - plane->a.y ;
01194 local_pt.z = pt->z - plane->a.z ;
01195
01196 spar->u = - PFSGeoTripleProd( &local_pt, &plane->n, &plane->v ) ;
01197 spar->v = PFSGeoTripleProd( &local_pt, &plane->n, &plane->u ) ;
01198
01199 PFSGeoEvalPlane( spar, (PFSGeoPlane *)plane, clst ) ;
01200 }
01201
01202
01203
01204 PFSGeoStatus PFSGeoClstPtPoly( poly, pt, clst, spar )
01205 PFSGeoPoly *poly ;
01206 PFSGeoPoint *pt, *clst ;
01207 PFSGeoSurfPar *spar ;
01208 {
01209
01210
01211
01212 PFSGeoClstPtNormPlane( &(poly->nplane), pt, clst, spar ) ;
01213
01214
01215
01216
01217 if( PFSGeoIsInsidePoly( poly, spar ) == PFSGeoTrue ) {
01218 return( PFSGeoValid ) ;
01219 }
01220 else {
01221 if( PFSGeoIsOnPolyBdry( poly, pt ) == PFSGeoTrue ) {
01222 return( PFSGeoValid ) ;
01223 }
01224 else {
01225 return( PFSGeoInvalid ) ;
01226 }
01227 }
01228 }
01229
01230
01231
01232 PFSGeoPredicate PFSGeoIsOnPlane( pt, pla )
01233
01234 PFSGeoPoint *pt ;
01235 PFSGeoNormPlane *pla ;
01236
01237 {
01238 PFSGeoLine line ;
01239 real proj ;
01240 real toler ;
01241 real line_len ;
01242
01243
01244
01245
01246 PFSGeoGenLine( pt, &pla->a, &line ) ;
01247
01248 line_len = PFSGeoVecLen( &line.e ) ;
01249
01250
01251
01252
01253
01254
01255 if( fabs( line_len ) < PFSGeoTolerance ) return( PFSGeoTrue ) ;
01256 proj = fabs( PFSGeoDotProd( &pla->n, &line.e ) / line_len ) ;
01257
01258
01259
01260
01261 toler = 0.01 ;
01262 if( proj < toler ) {
01263 return( PFSGeoTrue ) ;
01264 }
01265 else {
01266 return( PFSGeoFalse ) ;
01267 }
01268 }
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365
01366
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434
01435
01436
01437
01438
01439
01440
01441
01442
01443
01444
01445
01446
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476
01477
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492
01493
01494
01495
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521
01522
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556 PFSGeoStatus PFSGeoInvert2x2( a, b )
01557 real a[2][2] ;
01558 real b[2][2] ;
01559 {
01560 real det ;
01561 int i,j ;
01562
01563
01564
01565 for( i = 0; i < 2; i++)
01566 for( j = 0; j < 2; j++) b[i][j] = 0.0 ;
01567
01568
01569
01570 det = a[0][0] * a[1][1] - a[0][1] * a[1][0] ;
01571
01572 if (det == 0.0)
01573 return( PFSGeoInvalid ) ;
01574 else {
01575 b[0][0] = a[1][1] / det ;
01576 b[0][1] = -a[0][1] / det ;
01577 b[1][0] = -a[1][0] / det ;
01578 b[1][1] = a[0][0] / det ;
01579 return( PFSGeoValid );
01580 }
01581 }
01582
01583
01584 PFSGeoStatus PFSGeoInvert3x3( a, b )
01585 real a[3][3] ;
01586 real b[3][3] ;
01587 {
01588 real det ;
01589 int i,j ;
01590
01591
01592
01593 for( i = 0; i < 3; i++)
01594 for( j = 0; j < 3; j++) b[i][j] = 0.0 ;
01595
01596
01597
01598 det = a[0][0] * (a[1][1] * a[2][2] - a[1][2] * a[2][1]) -
01599 a[0][1] * (a[1][0] * a[2][2] - a[1][2] * a[2][0]) +
01600 a[0][2] * (a[1][0] * a[2][1] - a[1][1] * a[2][0]) ;
01601
01602 if (det == 0.0)
01603 return( PFSGeoInvalid ) ;
01604 else {
01605 b[0][0] = (a[1][1] * a[2][2] - a[1][2] * a[2][1]) / det ;
01606 b[0][1] = -(a[0][1] * a[2][2] - a[0][2] * a[2][1]) / det ;
01607 b[0][2] = (a[0][1] * a[1][2] - a[0][2] * a[1][1]) / det ;
01608 b[1][0] = -(a[1][0] * a[2][2] - a[1][2] * a[2][0]) / det ;
01609 b[1][1] = (a[0][0] * a[2][2] - a[0][2] * a[2][0]) / det ;
01610 b[1][2] = -(a[0][0] * a[1][2] - a[0][2] * a[1][0]) / det ;
01611 b[2][0] = (a[1][0] * a[2][1] - a[1][1] * a[2][0]) / det ;
01612 b[2][1] = -(a[0][0] * a[2][1] - a[0][1] * a[2][0]) / det ;
01613 b[2][2] = (a[0][0] * a[1][1] - a[0][1] * a[1][0]) / det ;
01614 return( PFSGeoValid );
01615 }
01616 }
01617
01618
01619 PFSGeoStatus PFSGeodInvert3x3( a, b )
01620 double a[3][3] ;
01621 double b[3][3] ;
01622 {
01623 double det ;
01624 int i,j ;
01625
01626
01627
01628 for( i = 0; i < 3; i++)
01629 for( j = 0; j < 3; j++) b[i][j] = 0.0 ;
01630
01631
01632
01633 det = a[0][0] * (a[1][1] * a[2][2] - a[1][2] * a[2][1]) -
01634 a[0][1] * (a[1][0] * a[2][2] - a[1][2] * a[2][0]) +
01635 a[0][2] * (a[1][0] * a[2][1] - a[1][1] * a[2][0]) ;
01636
01637 if (det == 0.0)
01638 return( PFSGeoInvalid ) ;
01639 else {
01640 b[0][0] = (a[1][1] * a[2][2] - a[1][2] * a[2][1]) / det ;
01641 b[0][1] = -(a[0][1] * a[2][2] - a[0][2] * a[2][1]) / det ;
01642 b[0][2] = (a[0][1] * a[1][2] - a[0][2] * a[1][1]) / det ;
01643 b[1][0] = -(a[1][0] * a[2][2] - a[1][2] * a[2][0]) / det ;
01644 b[1][1] = (a[0][0] * a[2][2] - a[0][2] * a[2][0]) / det ;
01645 b[1][2] = -(a[0][0] * a[1][2] - a[0][2] * a[1][0]) / det ;
01646 b[2][0] = (a[1][0] * a[2][1] - a[1][1] * a[2][0]) / det ;
01647 b[2][1] = -(a[0][0] * a[2][1] - a[0][1] * a[2][0]) / det ;
01648 b[2][2] = (a[0][0] * a[1][1] - a[0][1] * a[1][0]) / det ;
01649 return( PFSGeoValid );
01650 }
01651 }
01652
01653
01654 void PFSGeoCentroid( num_pts, pts, cntrd )
01655 int *num_pts ;
01656 PFSGeoPoint pts[] ;
01657 PFSGeoPoint *cntrd ;
01658
01659 {
01660 PFSGeoPoint sum ;
01661 int i ;
01662
01663 sum.x = sum.y = sum.z = 0.0 ;
01664 for( i=0; i<(*num_pts); i++ ) {
01665
01666 sum.x += pts[i].x ;
01667 sum.y += pts[i].y ;
01668 sum.z += pts[i].z ;
01669 }
01670
01671 cntrd->x = sum.x / *num_pts ;
01672 cntrd->y = sum.y / *num_pts ;
01673 cntrd->z = sum.z / *num_pts ;
01674
01675 return ;
01676 }
01677
01678
01679 PFSGeoStatus PFSGeoPerpLine( pl1, pl2, pl3, u, v, w )
01680 PFSGeoLine *pl1, *pl2, *pl3 ;
01681 PFSGeoPointPar *u, *v, *w ;
01682 {
01683 real coef[3][3], cinv[3][3];
01684 PFSGeoPoint dvec ;
01685
01686
01687
01688 PFSGeoCrossProd( &pl1->e, &pl2->e, &pl3->e ) ;
01689
01690
01691
01692 coef[0][0] = pl1->e.x ; coef[0][1] = pl2->e.x ; coef[0][2] = pl3->e.x ;
01693 coef[1][0] = pl1->e.y ; coef[1][1] = pl2->e.y ; coef[1][2] = pl3->e.y ;
01694 coef[2][0] = pl1->e.z ; coef[2][1] = pl2->e.z ; coef[2][2] = pl3->e.z ;
01695
01696 if ( PFSGeoInvert3x3( coef, cinv ) != PFSGeoValid )
01697 return( PFSGeoInvalid ) ;
01698 else {
01699
01700
01701 dvec.x = pl2->d.x - pl1->d.x ;
01702 dvec.y = pl2->d.y - pl1->d.y ;
01703 dvec.z = pl2->d.z - pl1->d.z ;
01704
01705 *u = cinv[0][0]*dvec.x + cinv[0][1]*dvec.y + cinv[0][2]*dvec.z ;
01706 *v = cinv[1][0]*dvec.x + cinv[1][1]*dvec.y + cinv[1][2]*dvec.z ;
01707 *w = cinv[2][0]*dvec.x + cinv[2][1]*dvec.y + cinv[2][2]*dvec.z ;
01708 *v = -*v ;
01709
01710 PFSGeoEvalLine( u, pl1, &pl3->d ) ;
01711 return(PFSGeoValid) ;
01712 }
01713 }
01714
01715
01716 void PFSGeoPtNormToParPlan( pt, normal, plane )
01717 PFSGeoPoint *pt, *normal ;
01718 PFSGeoNormPlane *plane ;
01719
01720 {
01721 PFSGeoPoint x_dir ;
01722 PFSGeoPoint y_dir ;
01723 PFSGeoPoint z_dir ;
01724 real size ;
01725 real tolerance ;
01726
01727 x_dir.x = 1.0 ; x_dir.y = 0.0 ; x_dir.z = 0.0 ;
01728 y_dir.x = 0.0 ; y_dir.y = 1.0 ; y_dir.z = 0.0 ;
01729 z_dir.x = 0.0 ; z_dir.y = 0.0 ; z_dir.z = 1.0 ;
01730
01731
01732
01733 size = PFSGeoVecLen( normal ) ;
01734
01735 plane->n.x = normal->x / size ;
01736 plane->n.y = normal->y / size ;
01737 plane->n.z = normal->z / size ;
01738
01739
01740
01741 plane->a = *pt ;
01742
01743
01744
01745 tolerance = PFSGeoTolerance ;
01746 PFSGeoCrossProd( &plane->n, &x_dir, &plane->u ) ;
01747 if (PFSGeoNullVec( &plane->u, &tolerance ) == PFSGeoTrue) {
01748 PFSGeoCrossProd( &plane->n, &y_dir, &plane->u ) ;
01749 if (PFSGeoNullVec( &plane->u, &tolerance ) == PFSGeoTrue) {
01750 PFSGeoCrossProd( &plane->n, &z_dir, &plane->u ) ;
01751 }
01752 }
01753 size = PFSGeoVecLen( &plane->u ) ;
01754 plane->u.x /= size ; plane->u.y /= size ; plane->u.z /= size ;
01755 PFSGeoCrossProd( &plane->n, &plane->u, &plane->v ) ;
01756
01757 return ;
01758 }
01759
01760 void PFSGeoPlanToNormPlan( plane, normplane )
01761 PFSGeoPlane *plane ;
01762 PFSGeoNormPlane *normplane ;
01763
01764
01765 {
01766 normplane->a = plane->a ;
01767 PFSGeoVecNormalize( &plane->b, &normplane->u ) ;
01768 PFSGeoCrossProd( &normplane->u, &plane->c, &normplane->n ) ;
01769 PFSGeoVecNormalize( &normplane->n, &normplane->n) ;
01770 PFSGeoCrossProd( &normplane->n, &normplane->u, &normplane->v ) ;
01771 }
01772
01773 PFSGeoStatus PFSGeo3PointsToNormPlane( in0, in1, in2, plane )
01774 PFSGeoPoint *in0 ;
01775 PFSGeoPoint *in1 ;
01776 PFSGeoPoint *in2 ;
01777 PFSGeoNormPlane *plane ;
01778
01779 {
01780 plane->a = *in0 ;
01781 PFSGeoDiffVec( in1, in0, &plane->u ) ;
01782 PFSGeoDiffVec( in2, in0, &plane->v ) ;
01783
01784 PFSGeoCrossProd( &plane->u, &plane->v, &plane->n ) ;
01785
01786 if (PFSGeoNullVec( &plane->n, &PFSGeoTolerance ) ) return(PFSGeoInvalid) ;
01787
01788 PFSGeoPlanToNormPlan( (PFSGeoPlane *)plane, plane ) ;
01789
01790 return(PFSGeoValid) ;
01791 }
01792
01793
01794
01795 void PFSGeoPlanEqnToParPlan( plan_eqn, plane )
01796 PFSGeoPlanEqn *plan_eqn ;
01797 PFSGeoNormPlane *plane ;
01798
01799 {
01800 PFSGeoPoint x_dir ;
01801 PFSGeoPoint y_dir ;
01802 PFSGeoPoint z_dir ;
01803 real tolerance ;
01804 real size ;
01805
01806 x_dir.x = 1.0 ; x_dir.y = 0.0 ; x_dir.z = 0.0 ;
01807 y_dir.x = 0.0 ; y_dir.y = 1.0 ; y_dir.z = 0.0 ;
01808 z_dir.x = 0.0 ; z_dir.y = 0.0 ; z_dir.z = 1.0 ;
01809
01810
01811
01812 size = sqrt( plan_eqn->a * plan_eqn->a + plan_eqn->b * plan_eqn->b +
01813 plan_eqn->c * plan_eqn->c ) ;
01814
01815 plane->n.x = plan_eqn->a /size ;
01816 plane->n.y = plan_eqn->b /size ;
01817 plane->n.z = plan_eqn->c /size ;
01818
01819
01820
01821 if (fabs(plan_eqn->a) > PFSGeoTolerance) {
01822 plane->a.x = - plan_eqn->d / plan_eqn->a ;
01823 plane->a.y = 0.0 ;
01824 plane->a.z = 0.0 ;
01825 }
01826 else if (fabs(plan_eqn->b) > PFSGeoTolerance) {
01827 plane->a.x = 0.0 ;
01828 plane->a.y = - plan_eqn->d / plan_eqn->b ;
01829 plane->a.z = 0.0 ;
01830 }
01831 else {
01832 plane->a.x = 0.0 ;
01833 plane->a.y = 0.0 ;
01834 plane->a.z = - plan_eqn->d / plan_eqn->c ;
01835 }
01836
01837
01838
01839 if (fabs( plan_eqn->d ) == 0.0) tolerance = PFSGeoTolerance ;
01840 else tolerance = PFSGeoTolerance * fabs( plan_eqn->d ) ;
01841 PFSGeoCrossProd( &plane->n, &x_dir, &plane->u ) ;
01842 if (PFSGeoNullVec( &plane->u, &tolerance ) == PFSGeoTrue) {
01843 PFSGeoCrossProd( &plane->n, &y_dir, &plane->u ) ;
01844 if (PFSGeoNullVec( &plane->u, &tolerance ) == PFSGeoTrue) {
01845 PFSGeoCrossProd( &plane->n, &z_dir, &plane->u ) ;
01846 }
01847 }
01848 size = PFSGeoVecLen( &plane->u ) ;
01849 plane->u.x /= size ; plane->u.y /= size ; plane->u.z /= size ;
01850 PFSGeoCrossProd( &plane->n, &plane->u, &plane->v ) ;
01851
01852 return ;
01853 }
01854
01855
01856 PFSGeoPtTest PFSGeoSideofPlan( plan_eqn, pt )
01857 PFSGeoPlanEqn *plan_eqn ;
01858 PFSGeoPoint *pt ;
01859
01860 {
01861 real result ;
01862
01863 result = ( plan_eqn->a * pt->x
01864 + plan_eqn->b * pt->y
01865 + plan_eqn->c * pt->z
01866 + plan_eqn->d ) ;
01867
01868 if( result > PFSGeoTolerance )
01869 return( PFSGeoAbove ) ;
01870 else if( result < -PFSGeoTolerance )
01871 return( PFSGeoBelow ) ;
01872 else
01873 return( PFSGeoOn ) ;
01874 }
01875
01876
01877 void PFSGeoSurfInterp( num_pts, map_func, pts_val, interp_val )
01878 int *num_pts ;
01879 real map_func[] ;
01880 PFSGeoSurfPar pts_val[] ;
01881 PFSGeoSurfPar *interp_val ;
01882
01883 {
01884 int i;
01885
01886 interp_val->u = 0.0 ;
01887 interp_val->v = 0.0 ;
01888
01889 for( i = 0; i < *num_pts; i++ ) {
01890 interp_val->u += map_func[i] * pts_val[i].u ;
01891 interp_val->v += map_func[i] * pts_val[i].v ;
01892 }
01893
01894 return ;
01895 }
01896
01897
01898 void PFSGeoSurfJacob( num_pts, map_deriv_s, map_deriv_t, pts_val, jac )
01899 int *num_pts ;
01900 real map_deriv_s[] ;
01901 real map_deriv_t[] ;
01902 PFSGeoSurfPar pts_val[] ;
01903 real jac[2][2] ;
01904
01905 {
01906 int i;
01907
01908 jac[0][0] = 0.0 ; jac[0][1] = 0.0 ;
01909 jac[1][0] = 0.0 ; jac[1][1] = 0.0 ;
01910
01911 for( i = 0; i < *num_pts; i++ ) {
01912 jac[0][0] += map_deriv_s[i] * pts_val[i].u ;
01913 jac[0][1] += map_deriv_s[i] * pts_val[i].v ;
01914 jac[1][0] += map_deriv_t[i] * pts_val[i].u ;
01915 jac[1][1] += map_deriv_t[i] * pts_val[i].v ;
01916 }
01917
01918 return ;
01919 }
01920
01921
01922 real PFSGeoAngVecAboutLine( l, v0, v1 )
01923 PFSGeoLine *l ;
01924 PFSGeoPoint *v0, *v1 ;
01925 {
01926 real cosang ;
01927 PFSGeoPoint cross ;
01928 real pi = fabs( acos(-1.0) ) ;
01929 real len, toler ;
01930
01931
01932
01933 len = PFSGeoVecLen ( v0 ) ;
01934 if( len == 0.0 ) return( 0.0 ) ;
01935 v0->x /= len ; v0->y /= len ; v0->z /= len ;
01936 len = PFSGeoVecLen ( v1 ) ;
01937 if( len == 0.0 ) return( 0.0 ) ;
01938 v1->x /= len ; v1->y /= len ; v1->z /= len ;
01939
01940
01941
01942 cosang = PFSGeoDotProd( v1, v0 ) ;
01943
01944
01945
01946
01947
01948 PFSGeoCrossProd( v1, v0, &cross ) ;
01949
01950 toler = PFSGeoTolerance ;
01951 if( PFSGeoNullVec( &cross, &toler ) == PFSGeoFalse ) {
01952 if( PFSGeoDotProd( &l->e, &cross ) > 0.0 ) {
01953 return( acos( cosang ) ) ;
01954 }
01955 else {
01956 return( 2.0 * pi - acos( cosang ) ) ;
01957 }
01958 }
01959 else {
01960 if( cosang > 0.0 ) {
01961 return( 0.0 ) ;
01962 }
01963 else {
01964 return( pi ) ;
01965 }
01966 }
01967 }
01968
01969
01970 real PFSGeoAngPtAboutLine( l, p0, p1 )
01971 PFSGeoLine *l ;
01972 PFSGeoPoint *p0, *p1 ;
01973 {
01974 PFSGeoPoint clstp0, clstp1 ;
01975
01976 PFSGeoPoint v0, v1 ;
01977
01978 PFSGeoPointPar dum_par ;
01979
01980
01981
01982 PFSGeoClstPtLine ( l, p0, &clstp0, &dum_par ) ;
01983 PFSGeoClstPtLine ( l, p1, &clstp1, &dum_par ) ;
01984
01985
01986
01987 v0.x = p0->x - clstp0.x ;
01988 v0.y = p0->y - clstp0.y ;
01989 v0.z = p0->z - clstp0.z ;
01990 v1.x = p1->x - clstp1.x ;
01991 v1.y = p1->y - clstp1.y ;
01992 v1.z = p1->z - clstp1.z ;
01993
01994 return( PFSGeoAngVecAboutLine( l, &v0, &v1 ) ) ;
01995 }
01996
01997
01998 real PFSGeoAngPtAboutPt( pivot, p0, p1 )
01999 PFSGeoPoint *pivot ;
02000 PFSGeoPoint *p0, *p1 ;
02001 {
02002 PFSGeoLine l ;
02003 PFSGeoPoint v0, v1 ;
02004 real pi = fabs( acos(-1.0) ) ;
02005 real toler ;
02006
02007
02008
02009
02010 v0.x = p0->x - pivot->x; v0.y = p0->y - pivot->y; v0.z = p0->z - pivot->z;
02011 v1.x = p1->x - pivot->x; v1.y = p1->y - pivot->y; v1.z = p1->z - pivot->z;
02012
02013
02014
02015
02016 l.d = *pivot ;
02017 PFSGeoCrossProd( &v1, &v0, &l.e ) ;
02018
02019 toler = PFSGeoTolerance ;
02020 if( PFSGeoNullVec( &l.e, &toler ) == PFSGeoTrue ) {
02021 if( PFSGeoDotProd( &v0, &v1 ) > 0.0 ) {
02022 return( 0.0 ) ;
02023 }
02024 else {
02025 return( pi ) ;
02026 }
02027 }
02028 else {
02029
02030
02031
02032 return( PFSGeoAngVecAboutLine( &l, &v0, &v1 ) ) ;
02033 }
02034 }
02035
02036
02037 PFSGeoStatus PFSGeoProjVecPlane( vec, plane, proj )
02038 PFSGeoPoint *vec ;
02039 PFSGeoPlane *plane ;
02040 PFSGeoPoint *proj ;
02041 {
02042 real vec_dot_b, vec_dot_c ;
02043
02044 vec_dot_b = PFSGeoDotProd( vec, &plane->b ) ;
02045 vec_dot_c = PFSGeoDotProd( vec, &plane->c ) ;
02046
02047 proj->x = vec_dot_b * plane->b.x + vec_dot_c * plane->c.x ;
02048 proj->y = vec_dot_b * plane->b.y + vec_dot_c * plane->c.y ;
02049 proj->z = vec_dot_b * plane->b.z + vec_dot_c * plane->c.z ;
02050
02051 if( (fabs(vec_dot_b) < PFSGeoTolerance) && (fabs(vec_dot_c) < PFSGeoTolerance) ) {
02052 return( PFSGeoInvalid ) ;
02053 }
02054 else {
02055 return( PFSGeoValid ) ;
02056 }
02057 }
02058
02059 real PFSGeoDistPtNormPlane( plane, pt )
02060 PFSGeoNormPlane *plane ;
02061 PFSGeoPoint *pt ;
02062
02063 {
02064 PFSGeoPoint clst ;
02065 PFSGeoSurfPar spar ;
02066
02067 PFSGeoClstPtNormPlane( plane, pt, &clst, &spar ) ;
02068
02069 return( PFSGeoDist( pt, &clst ) ) ;
02070 }
02071
02072 void PFSGeoDyadProd( vec0, vec1, matr )
02073
02074 PFSGeoPoint *vec0, *vec1 ;
02075 real matr[3][3] ;
02076 {
02077
02078 matr[0][0] = vec0->x * vec1->x ;
02079 matr[0][1] = vec0->x * vec1->y ;
02080 matr[0][2] = vec0->x * vec1->z ;
02081 matr[1][0] = vec0->y * vec1->x ;
02082 matr[1][1] = vec0->y * vec1->y ;
02083 matr[1][2] = vec0->y * vec1->z ;
02084 matr[2][0] = vec0->z * vec1->x ;
02085 matr[2][1] = vec0->z * vec1->y ;
02086 matr[2][2] = vec0->z * vec1->z ;
02087
02088 return ;
02089 }
02090
02091 void PFSGeoProdMatrVec( matr, vec0, vec1 )
02092 real matr[3][3] ;
02093 PFSGeoPoint *vec0 ;
02094 PFSGeoPoint *vec1 ;
02095
02096 {
02097 vec1->x = matr[0][0] * vec0->x + matr[0][1] * vec0->y +
02098 matr[0][2] * vec0->z ;
02099 vec1->y = matr[1][0] * vec0->x + matr[1][1] * vec0->y +
02100 matr[1][2] * vec0->z ;
02101 vec1->z = matr[2][0] * vec0->x + matr[2][1] * vec0->y +
02102 matr[2][2] * vec0->z ;
02103 return ;
02104 }
02105
02106
02107
02108