00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #include "G4ReduciblePolygon.hh"
00044 #include "globals.hh"
00045
00046
00047
00048
00049 G4ReduciblePolygon::G4ReduciblePolygon( const G4double a[],
00050 const G4double b[],
00051 G4int n )
00052 : aMin(0.), aMax(0.), bMin(0.), bMax(0.),
00053 vertexHead(0)
00054 {
00055
00056
00057
00058 Create( a, b, n );
00059 }
00060
00061
00062
00063
00064
00065 G4ReduciblePolygon::G4ReduciblePolygon( const G4double rmin[],
00066 const G4double rmax[],
00067 const G4double z[], G4int n )
00068 : aMin(0.), aMax(0.), bMin(0.), bMax(0.),
00069 vertexHead(0)
00070 {
00071
00072
00073
00074 G4double *a = new G4double[n*2];
00075 G4double *b = new G4double[n*2];
00076
00077 G4double *rOut = a + n,
00078 *zOut = b + n,
00079 *rIn = rOut-1,
00080 *zIn = zOut-1;
00081
00082 G4int i;
00083 for( i=0; i < n; i++, rOut++, zOut++, rIn--, zIn-- )
00084 {
00085 *rOut = rmax[i];
00086 *rIn = rmin[i];
00087 *zOut = *zIn = z[i];
00088 }
00089
00090 Create( a, b, n*2 );
00091
00092 delete [] a;
00093 delete [] b;
00094 }
00095
00096
00097
00098
00099
00100
00101
00102
00103 void G4ReduciblePolygon::Create( const G4double a[],
00104 const G4double b[], G4int n )
00105 {
00106 if (n<3)
00107 G4Exception("G4ReduciblePolygon::Create()", "GeomSolids0002",
00108 FatalErrorInArgument, "Less than 3 vertices specified.");
00109
00110 const G4double *anext = a, *bnext = b;
00111 ABVertex *prev = 0;
00112 do
00113 {
00114 ABVertex *newVertex = new ABVertex;
00115 newVertex->a = *anext;
00116 newVertex->b = *bnext;
00117 newVertex->next = 0;
00118 if (prev==0)
00119 {
00120 vertexHead = newVertex;
00121 }
00122 else
00123 {
00124 prev->next = newVertex;
00125 }
00126
00127 prev = newVertex;
00128 } while( ++anext, ++bnext < b+n );
00129
00130 numVertices = n;
00131
00132 CalculateMaxMin();
00133 }
00134
00135
00136
00137
00138
00139
00140 G4ReduciblePolygon::G4ReduciblePolygon( __void__& )
00141 : aMin(0.), aMax(0.), bMin(0.), bMax(0.), numVertices(0), vertexHead(0)
00142 {
00143 }
00144
00145
00146
00147
00148
00149 G4ReduciblePolygon::~G4ReduciblePolygon()
00150 {
00151 ABVertex *curr = vertexHead;
00152 while( curr )
00153 {
00154 ABVertex *toDelete = curr;
00155 curr = curr->next;
00156 delete toDelete;
00157 }
00158 }
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168 void G4ReduciblePolygon::CopyVertices( G4double a[], G4double b[] ) const
00169 {
00170 G4double *anext = a, *bnext = b;
00171 ABVertex *curr = vertexHead;
00172 while( curr )
00173 {
00174 *anext++ = curr->a;
00175 *bnext++ = curr->b;
00176 curr = curr->next;
00177 }
00178 }
00179
00180
00181
00182
00183
00184
00185
00186 void G4ReduciblePolygon::ScaleA( G4double scale )
00187 {
00188 ABVertex *curr = vertexHead;
00189 while( curr )
00190 {
00191 curr->a *= scale;
00192 curr = curr->next;
00193 }
00194 }
00195
00196
00197
00198
00199
00200
00201
00202 void G4ReduciblePolygon::ScaleB( G4double scale )
00203 {
00204 ABVertex *curr = vertexHead;
00205 while( curr )
00206 {
00207 curr->b *= scale;
00208 curr = curr->next;
00209 }
00210 }
00211
00212
00213
00214
00215
00216
00217
00218
00219 G4bool G4ReduciblePolygon::RemoveDuplicateVertices( G4double tolerance )
00220 {
00221 ABVertex *curr = vertexHead,
00222 *prev = 0, *next = 0;
00223 while( curr )
00224 {
00225 next = curr->next;
00226 if (next == 0) next = vertexHead;
00227
00228 if (std::fabs(curr->a-next->a) < tolerance &&
00229 std::fabs(curr->b-next->b) < tolerance )
00230 {
00231
00232
00233
00234 if (numVertices <= 3)
00235 {
00236 CalculateMaxMin();
00237 return false;
00238 }
00239
00240
00241
00242
00243 ABVertex *toDelete = curr;
00244 curr = curr->next;
00245 delete toDelete;
00246
00247 numVertices--;
00248
00249 if (prev) prev->next = curr; else vertexHead = curr;
00250 }
00251 else
00252 {
00253 prev = curr;
00254 curr = curr->next;
00255 }
00256 }
00257
00258
00259
00260
00261 CalculateMaxMin();
00262
00263 return true;
00264 }
00265
00266
00267
00268
00269
00270
00271
00272
00273 G4bool G4ReduciblePolygon::RemoveRedundantVertices( G4double tolerance )
00274 {
00275
00276
00277
00278 if (numVertices <= 2) return false;
00279
00280 G4double tolerance2 = tolerance*tolerance;
00281
00282
00283
00284
00285 ABVertex *curr = vertexHead, *next = 0;
00286 while( curr )
00287 {
00288 next = curr->next;
00289 if (next == 0) next = vertexHead;
00290
00291 G4double da = next->a - curr->a,
00292 db = next->b - curr->b;
00293
00294
00295
00296
00297 for(;;)
00298 {
00299
00300
00301
00302 ABVertex *test = next->next;
00303 if (test == 0) test = vertexHead;
00304
00305
00306
00307
00308 if (test==curr) break;
00309
00310
00311
00312
00313 G4double dat = test->a - curr->a,
00314 dbt = test->b - curr->b;
00315
00316 if (std::fabs(dat*db-dbt*da)>tolerance2) break;
00317
00318
00319
00320
00321 if (numVertices <= 3)
00322 {
00323 CalculateMaxMin();
00324 return false;
00325 }
00326
00327
00328
00329
00330 if (curr->next)
00331 {
00332 if (next->next)
00333 curr->next = test;
00334 else
00335 curr->next = 0;
00336 }
00337 else
00338 vertexHead = test;
00339
00340 if ((curr != next) && (next != test)) delete next;
00341
00342 numVertices--;
00343
00344
00345
00346
00347
00348 next = test;
00349 da = dat; db = dbt;
00350 }
00351 curr = curr->next;
00352 }
00353
00354
00355
00356
00357 CalculateMaxMin();
00358
00359 return true;
00360 }
00361
00362
00363
00364
00365
00366
00367
00368 void G4ReduciblePolygon::ReverseOrder()
00369 {
00370
00371
00372
00373 ABVertex *prev = vertexHead;
00374 if (prev==0) return;
00375
00376 ABVertex *curr = prev->next;
00377 if (curr==0) return;
00378
00379
00380
00381
00382 vertexHead->next = 0;
00383
00384 for(;;)
00385 {
00386
00387
00388
00389 ABVertex *save = curr->next;
00390
00391
00392
00393
00394
00395 curr->next = prev;
00396
00397
00398
00399
00400 if (save == 0) break;
00401
00402
00403
00404
00405 prev = curr;
00406 curr = save;
00407 }
00408
00409
00410
00411
00412 vertexHead = curr;
00413 }
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423 G4bool G4ReduciblePolygon::CrossesItself( G4double tolerance )
00424 {
00425 G4double tolerance2 = tolerance*tolerance;
00426 G4double one = 1.0-tolerance,
00427 zero = tolerance;
00428
00429
00430
00431
00432 ABVertex *curr1 = vertexHead, *next1=0;
00433 while (curr1->next)
00434 {
00435 next1 = curr1->next;
00436 G4double da1 = next1->a-curr1->a,
00437 db1 = next1->b-curr1->b;
00438
00439
00440
00441
00442 ABVertex *curr2 = next1->next;
00443 while( curr2 )
00444 {
00445 ABVertex *next2 = curr2->next;
00446 if (next2==0) next2 = vertexHead;
00447 G4double da2 = next2->a-curr2->a,
00448 db2 = next2->b-curr2->b;
00449 G4double a12 = curr2->a-curr1->a,
00450 b12 = curr2->b-curr1->b;
00451
00452
00453
00454
00455 G4double deter = da1*db2 - db1*da2;
00456 if (std::fabs(deter) > tolerance2)
00457 {
00458 G4double s1, s2;
00459 s1 = (a12*db2-b12*da2)/deter;
00460
00461 if (s1 >= zero && s1 < one)
00462 {
00463 s2 = -(da1*b12-db1*a12)/deter;
00464 if (s2 >= zero && s2 < one) return true;
00465 }
00466 }
00467 curr2 = curr2->next;
00468 }
00469 curr1 = next1;
00470 }
00471 return false;
00472 }
00473
00474
00475
00476
00477
00478
00479
00480
00481 G4bool G4ReduciblePolygon::BisectedBy( G4double a1, G4double b1,
00482 G4double a2, G4double b2,
00483 G4double tolerance )
00484 {
00485 G4int nNeg = 0, nPos = 0;
00486
00487 G4double a12 = a2-a1, b12 = b2-b1;
00488 G4double len12 = std::sqrt( a12*a12 + b12*b12 );
00489 a12 /= len12; b12 /= len12;
00490
00491 ABVertex *curr = vertexHead;
00492 do
00493 {
00494 G4double av = curr->a - a1,
00495 bv = curr->b - b1;
00496
00497 G4double cross = av*b12 - bv*a12;
00498
00499 if (cross < -tolerance)
00500 {
00501 if (nPos) return true;
00502 nNeg++;
00503 }
00504 else if (cross > tolerance)
00505 {
00506 if (nNeg) return true;
00507 nPos++;
00508 }
00509 curr = curr->next;
00510 } while( curr );
00511
00512 return false;
00513 }
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526 G4double G4ReduciblePolygon::Area()
00527 {
00528 G4double answer = 0;
00529
00530 ABVertex *curr = vertexHead, *next;
00531 do
00532 {
00533 next = curr->next;
00534 if (next==0) next = vertexHead;
00535
00536 answer += curr->a*next->b - curr->b*next->a;
00537 curr = curr->next;
00538 } while( curr );
00539
00540 return 0.5*answer;
00541 }
00542
00543
00544
00545
00546
00547 void G4ReduciblePolygon::Print()
00548 {
00549 ABVertex *curr = vertexHead;
00550 do
00551 {
00552 G4cerr << curr->a << " " << curr->b << G4endl;
00553 curr = curr->next;
00554 } while( curr );
00555 }
00556
00557
00558
00559
00560
00561
00562
00563
00564 void G4ReduciblePolygon::CalculateMaxMin()
00565 {
00566 ABVertex *curr = vertexHead;
00567 aMin = aMax = curr->a;
00568 bMin = bMax = curr->b;
00569 curr = curr->next;
00570 while( curr )
00571 {
00572 if (curr->a < aMin)
00573 aMin = curr->a;
00574 else if (curr->a > aMax)
00575 aMax = curr->a;
00576
00577 if (curr->b < bMin)
00578 bMin = curr->b;
00579 else if (curr->b > bMax)
00580 bMax = curr->b;
00581
00582 curr = curr->next;
00583 }
00584 }