00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "geom.h"
00021 #include "geomprocs.h"
00022
00023 point pointof(int x, int y)
00024 {
00025 point rv;
00026 rv.x = x, rv.y = y;
00027 return rv;
00028 }
00029
00030 pointf pointfof(double x, double y)
00031 {
00032 pointf rv;
00033 rv.x = x, rv.y = y;
00034 return rv;
00035 }
00036
00037 point cvt2pt(pointf p)
00038 {
00039 point rv;
00040 rv.x = POINTS(p.x);
00041 rv.y = POINTS(p.y);
00042 return rv;
00043 }
00044
00045 pointf cvt2ptf(point p)
00046 {
00047 pointf rv;
00048 rv.x = PS2INCH(p.x);
00049 rv.y = PS2INCH(p.y);
00050 return rv;
00051 }
00052
00053 box boxof(int llx, int lly, int urx, int ury)
00054 {
00055 box b;
00056
00057 b.LL.x = llx, b.LL.y = lly;
00058 b.UR.x = urx, b.UR.y = ury;
00059 return b;
00060 }
00061
00062 boxf boxfof(double llx, double lly, double urx, double ury)
00063 {
00064 boxf b;
00065
00066 b.LL.x = llx, b.LL.y = lly;
00067 b.UR.x = urx, b.UR.y = ury;
00068 return b;
00069 }
00070
00071 box mkbox(point p0, point p1)
00072 {
00073 box rv;
00074
00075 if (p0.x < p1.x) {
00076 rv.LL.x = p0.x;
00077 rv.UR.x = p1.x;
00078 } else {
00079 rv.LL.x = p1.x;
00080 rv.UR.x = p0.x;
00081 }
00082 if (p0.y < p1.y) {
00083 rv.LL.y = p0.y;
00084 rv.UR.y = p1.y;
00085 } else {
00086 rv.LL.y = p1.y;
00087 rv.UR.y = p0.y;
00088 }
00089 return rv;
00090 }
00091
00092 boxf mkboxf(pointf p0, pointf p1)
00093 {
00094 boxf rv;
00095
00096 if (p0.x < p1.x) {
00097 rv.LL.x = p0.x;
00098 rv.UR.x = p1.x;
00099 } else {
00100 rv.LL.x = p1.x;
00101 rv.UR.x = p0.x;
00102 }
00103 if (p0.y < p1.y) {
00104 rv.LL.y = p0.y;
00105 rv.UR.y = p1.y;
00106 } else {
00107 rv.LL.y = p1.y;
00108 rv.UR.y = p0.y;
00109 }
00110 return rv;
00111 }
00112
00113 point add_points(point p0, point p1)
00114 {
00115 p0.x += p1.x;
00116 p0.y += p1.y;
00117 return p0;
00118 }
00119
00120 point sub_points(point p0, point p1)
00121 {
00122 p0.x -= p1.x;
00123 p0.y -= p1.y;
00124 return p0;
00125 }
00126
00127 pointf add_pointfs(pointf p0, pointf p1)
00128 {
00129 p0.x += p1.x;
00130 p0.y += p1.y;
00131 return p0;
00132 }
00133
00134 pointf sub_pointfs(pointf p0, pointf p1)
00135 {
00136 p0.x -= p1.x;
00137 p0.y -= p1.y;
00138 return p0;
00139 }
00140
00141 point exch_xy(point p)
00142 {
00143 int t;
00144 t = p.x;
00145 p.x = p.y;
00146 p.y = t;
00147 return p;
00148 }
00149
00150 pointf exch_xyf(pointf p)
00151 {
00152 double t;
00153 t = p.x;
00154 p.x = p.y;
00155 p.y = t;
00156 return p;
00157 }
00158
00159 box box_bb(box b0, box b1)
00160 {
00161 box b;
00162
00163 b.LL.x = MIN(b0.LL.x, b1.LL.x);
00164 b.LL.y = MIN(b0.LL.y, b1.LL.y);
00165 b.UR.x = MAX(b0.UR.x, b1.UR.x);
00166 b.UR.y = MAX(b0.UR.y, b1.UR.y);
00167
00168 return b;
00169 }
00170
00171 boxf boxf_bb(boxf b0, boxf b1)
00172 {
00173 boxf b;
00174
00175 b.LL.x = MIN(b0.LL.x, b1.LL.x);
00176 b.LL.y = MIN(b0.LL.y, b1.LL.y);
00177 b.UR.x = MAX(b0.UR.x, b1.UR.x);
00178 b.UR.y = MAX(b0.UR.y, b1.UR.y);
00179
00180 return b;
00181 }
00182
00183 box box_intersect(box b0, box b1)
00184 {
00185 box b;
00186
00187 b.LL.x = MAX(b0.LL.x, b1.LL.x);
00188 b.LL.y = MAX(b0.LL.y, b1.LL.y);
00189 b.UR.x = MIN(b0.UR.x, b1.UR.x);
00190 b.UR.y = MIN(b0.UR.y, b1.UR.y);
00191
00192 return b;
00193 }
00194
00195 boxf boxf_intersect(boxf b0, boxf b1)
00196 {
00197 boxf b;
00198
00199 b.LL.x = MAX(b0.LL.x, b1.LL.x);
00200 b.LL.y = MAX(b0.LL.y, b1.LL.y);
00201 b.UR.x = MIN(b0.UR.x, b1.UR.x);
00202 b.UR.y = MIN(b0.UR.y, b1.UR.y);
00203
00204 return b;
00205 }
00206
00207 int box_overlap(box b0, box b1)
00208 {
00209 return OVERLAP(b0, b1);
00210 }
00211
00212 int boxf_overlap(boxf b0, boxf b1)
00213 {
00214 return OVERLAP(b0, b1);
00215 }
00216
00217 int box_contains(box b0, box b1)
00218 {
00219 return CONTAINS(b0, b1);
00220 }
00221
00222 int boxf_contains(boxf b0, boxf b1)
00223 {
00224 return CONTAINS(b0, b1);
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 int lineToBox(pointf p1, pointf p2, boxf b)
00250 {
00251 int inside1, inside2;
00252
00253
00254
00255
00256
00257
00258 inside1 = (p1.x >= b.LL.x) && (p1.x <= b.UR.x)
00259 && (p1.y >= b.LL.y) && (p1.y <= b.UR.y);
00260 inside2 = (p2.x >= b.LL.x) && (p2.x <= b.UR.x)
00261 && (p2.y >= b.LL.y) && (p2.y <= b.UR.y);
00262 if (inside1 != inside2) {
00263 return 0;
00264 }
00265 if (inside1 & inside2) {
00266 return 1;
00267 }
00268
00269
00270
00271
00272
00273
00274
00275
00276 if (p1.x == p2.x) {
00277
00278
00279
00280
00281 if (((p1.y >= b.LL.y) ^ (p2.y >= b.LL.y))
00282 && (p1.x >= b.LL.x)
00283 && (p1.x <= b.UR.x)) {
00284 return 0;
00285 }
00286 } else if (p1.y == p2.y) {
00287
00288
00289
00290 if (((p1.x >= b.LL.x) ^ (p2.x >= b.LL.x))
00291 && (p1.y >= b.LL.y)
00292 && (p1.y <= b.UR.y)) {
00293 return 0;
00294 }
00295 } else {
00296 double m, x, y, low, high;
00297
00298
00299
00300
00301
00302
00303
00304 m = (p2.y - p1.y)/(p2.x - p1.x);
00305 if (p1.x < p2.x) {
00306 low = p1.x; high = p2.x;
00307 } else {
00308 low = p2.x; high = p1.x;
00309 }
00310
00311
00312
00313
00314
00315 y = p1.y + (b.LL.x - p1.x)*m;
00316 if ((b.LL.x >= low) && (b.LL.x <= high)
00317 && (y >= b.LL.y) && (y <= b.UR.y)) {
00318 return 0;
00319 }
00320
00321
00322
00323
00324
00325 y += (b.UR.x - b.LL.x)*m;
00326 if ((y >= b.LL.y) && (y <= b.UR.y)
00327 && (b.UR.x >= low) && (b.UR.x <= high)) {
00328 return 0;
00329 }
00330
00331
00332
00333
00334
00335 if (p1.y < p2.y) {
00336 low = p1.y; high = p2.y;
00337 } else {
00338 low = p2.y; high = p1.y;
00339 }
00340 x = p1.x + (b.LL.y - p1.y)/m;
00341 if ((x >= b.LL.x) && (x <= b.UR.x)
00342 && (b.LL.y >= low) && (b.LL.y <= high)) {
00343 return 0;
00344 }
00345
00346
00347
00348
00349
00350 x += (b.UR.y - b.LL.y)/m;
00351 if ((x >= b.LL.x) && (x <= b.UR.x)
00352 && (b.UR.y >= low) && (b.UR.y <= high)) {
00353 return 0;
00354 }
00355 }
00356 return -1;
00357 }
00358
00359 void rect2poly(pointf *p)
00360 {
00361 p[3].x = p[2].x = p[1].x;
00362 p[2].y = p[1].y;
00363 p[3].y = p[0].y;
00364 p[1].x = p[0].x;
00365 }
00366
00367 static pointf rotatepf(pointf p, int cwrot)
00368 {
00369 static double sina, cosa;
00370 static int last_cwrot;
00371 pointf P;
00372
00373
00374
00375 if (cwrot != last_cwrot) {
00376 sincos(cwrot / (2 * M_PI), &sina, &cosa);
00377 last_cwrot = cwrot;
00378 }
00379 P.x = p.x * cosa - p.y * sina;
00380 P.y = p.y * cosa + p.x * sina;
00381 return P;
00382 }
00383
00384 static point rotatep(point p, int cwrot)
00385 {
00386 pointf pf;
00387
00388 P2PF(p, pf);
00389 pf = rotatepf(pf, cwrot);
00390 PF2P(pf, p);
00391 return p;
00392 }
00393
00394 point cwrotatep(point p, int cwrot)
00395 {
00396 int x = p.x, y = p.y;
00397 switch (cwrot) {
00398 case 0:
00399 break;
00400 case 90:
00401 p.x = y;
00402 p.y = -x;
00403 break;
00404 case 180:
00405 p.x = x;
00406 p.y = -y;
00407 break;
00408 case 270:
00409 p.x = y;
00410 p.y = x;
00411 break;
00412 default:
00413 if (cwrot < 0)
00414 return ccwrotatep(p, -cwrot);
00415 if (cwrot > 360)
00416 return cwrotatep(p, cwrot%360);
00417 return rotatep(p, cwrot);
00418 }
00419 return p;
00420 }
00421
00422 pointf cwrotatepf(pointf p, int cwrot)
00423 {
00424 double x = p.x, y = p.y;
00425 switch (cwrot) {
00426 case 0:
00427 break;
00428 case 90:
00429 p.x = y;
00430 p.y = -x;
00431 break;
00432 case 180:
00433 p.x = x;
00434 p.y = -y;
00435 break;
00436 case 270:
00437 p.x = y;
00438 p.y = x;
00439 break;
00440 default:
00441 if (cwrot < 0)
00442 return ccwrotatepf(p, -cwrot);
00443 if (cwrot > 360)
00444 return cwrotatepf(p, cwrot%360);
00445 return rotatepf(p, cwrot);
00446 }
00447 return p;
00448 }
00449
00450 point ccwrotatep(point p, int ccwrot)
00451 {
00452 int x = p.x, y = p.y;
00453 switch (ccwrot) {
00454 case 0:
00455 break;
00456 case 90:
00457 p.x = -y;
00458 p.y = x;
00459 break;
00460 case 180:
00461 p.x = x;
00462 p.y = -y;
00463 break;
00464 case 270:
00465 p.x = y;
00466 p.y = x;
00467 break;
00468 default:
00469 if (ccwrot < 0)
00470 return cwrotatep(p, -ccwrot);
00471 if (ccwrot > 360)
00472 return ccwrotatep(p, ccwrot%360);
00473 return rotatep(p, 360-ccwrot);
00474 }
00475 return p;
00476 }
00477
00478 pointf ccwrotatepf(pointf p, int ccwrot)
00479 {
00480 double x = p.x, y = p.y;
00481 switch (ccwrot) {
00482 case 0:
00483 break;
00484 case 90:
00485 p.x = -y;
00486 p.y = x;
00487 break;
00488 case 180:
00489 p.x = x;
00490 p.y = -y;
00491 break;
00492 case 270:
00493 p.x = y;
00494 p.y = x;
00495 break;
00496 default:
00497 if (ccwrot < 0)
00498 return cwrotatepf(p, -ccwrot);
00499 if (ccwrot > 360)
00500 return ccwrotatepf(p, ccwrot%360);
00501 return rotatepf(p, 360-ccwrot);
00502 }
00503 return p;
00504 }
00505
00506 box flip_rec_box(box b, point p)
00507 {
00508 box rv;
00509
00510 rv.UR.x = b.UR.y;
00511 rv.UR.y = b.UR.x;
00512 rv.LL.x = b.LL.y;
00513 rv.LL.y = b.LL.x;
00514
00515 rv.LL.x += p.x;
00516 rv.LL.y += p.y;
00517 rv.UR.x += p.x;
00518 rv.UR.y += p.y;
00519 return rv;
00520 }
00521
00522
00523
00524
00525 double ptToLine2 (pointf a, pointf b, pointf p)
00526 {
00527 double dx = b.x-a.x;
00528 double dy = b.y-a.y;
00529 double a2 = (p.y-a.y)*dx - (p.x-a.x)*dy;
00530 a2 *= a2;
00531 if (a2 < .00001) return 0.;
00532 return a2 / (dx*dx + dy*dy);
00533 }