001/* 002 * To change this template, choose Tools | Templates 003 * and open the template in the editor. 004 */ 005package armyc2.c2sd.JavaLineArray; 006 007/** 008 * A class to provide the utility functions required for calculating the line 009 * points. 010 * 011 * @author Michael Deutch 012 */ 013import java.util.ArrayList; 014import armyc2.c2sd.renderer.utilities.ErrorLogger; 015import armyc2.c2sd.renderer.utilities.RendererException; 016import armyc2.c2sd.renderer.utilities.RendererSettings; 017import java.io.*; 018import armyc2.c2sd.graphics2d.*; 019import armyc2.c2sd.renderer.utilities.IPointConversion; 020import armyc2.c2sd.JavaTacticalRenderer.mdlGeodesic; 021public final class lineutility { 022 023 private static final String _className = "lineutility"; 024 public static final int extend_left = 0; 025 public static final int extend_right = 1; 026 public static final int extend_above = 2; 027 public static final int extend_below = 3; 028 029 /** 030 * Resizes the array to the length speicifed, called by the Channels class. 031 * 032 * @param pLinePoints the array to resize 033 * @param length the length to which to resize the array. 034 * @return the resized array 035 */ 036 protected static POINT2[] ResizeArray(POINT2[] pLinePoints, int length) { 037 POINT2[] array = new POINT2[length]; 038 try { 039 if (pLinePoints.length <= length) { 040 return pLinePoints; 041 } 042 043 int j = 0; 044 for (j = 0; j < length; j++) { 045 array[j] = new POINT2(pLinePoints[j]); 046 } 047 } catch (Exception exc) { 048 ErrorLogger.LogException(_className, "ResizeArray", 049 new RendererException("Failed inside ResizeArray", exc)); 050 } 051 return array; 052 } 053 054 /** 055 * post-segments a line segment into 50 pixel intervals 056 * 057 * @param pt0 058 * @param pt1 059 * @param shape 060 */ 061 protected static void SegmentLineShape(POINT2 pt0, POINT2 pt1, Shape2 shape) { 062 try { 063 if (pt0 == null || pt1 == null) { 064 return; 065 } 066 067 int j = 0, n = 0; 068 double dist = CalcDistanceDouble(pt0, pt1); 069 n = (int) (dist / 25d); 070 POINT2 pt = null; 071 shape.lineTo(pt0); 072 for (j = 1; j <= n; j++) { 073 pt = lineutility.ExtendAlongLineDouble(pt0, pt1, 25); 074 shape.lineTo(pt); 075 } 076 shape.lineTo(pt1); 077 } catch (Exception exc) { 078 ErrorLogger.LogException(_className, "SegmentLineShape", 079 new RendererException("Failed inside SegmentLineShape", exc)); 080 } 081 } 082 083 /** 084 * Calculates the middle segment for the Direction of Attack Aviation symbol 085 * 086 * @param pLinePoints the point array 087 * @param vblSaveCounter the size of the point array 088 * @return the middle segment 089 */ 090 public static int GetDirAtkAirMiddleSegment(POINT2[] pLinePoints, 091 int vblSaveCounter) { 092 int middleSegment = -1; 093 try { 094 double d = 0; 095 int k = 0; 096 for (k = vblSaveCounter - 1; k > 0; k--) { 097 d += lineutility.CalcDistanceDouble(pLinePoints[k], pLinePoints[k - 1]); 098 if (d > 60) { 099 break; 100 } 101 } 102 if (d > 60) { 103 middleSegment = k; 104 } else { 105 if (vblSaveCounter <= 3) { 106 middleSegment = 1; 107 } else { 108 middleSegment = 2; 109 } 110 } 111 } catch (Exception exc) { 112 ErrorLogger.LogException(_className, "GetDirAtkAirMiddleSegment", 113 new RendererException("Failed inside GetDirAtkAirMiddleSegment", exc)); 114 } 115 return middleSegment; 116 } 117 118 /** 119 * Computes the angle in radians between two points 120 * 121 * @param pt0 the first point 122 * @param pt1 the last point 123 * 124 * @return the angle in radians 125 */ 126 protected static double CalcSegmentAngleDouble(POINT2 pt0, 127 POINT2 pt1) { 128 double dAngle = 0; 129 try { 130 //declarations 131 int nTemp = 0; 132 ref<double[]> m = new ref(); 133 //end declarations 134 135 nTemp = CalcTrueSlopeDouble(pt0, pt1, m); 136 if (nTemp == 0) { 137 dAngle = Math.PI / 2; 138 } else { 139 dAngle = Math.atan(m.value[0]); 140 } 141 142 } catch (Exception exc) { 143 ErrorLogger.LogException(_className, "CalcSegmentAngleDouble", 144 new RendererException("Failed inside CalcSegmentAngleDouble", exc)); 145 } 146 return dAngle; 147 } 148 149 /** 150 * POINT2 in previous applications has been a struct that did not require 151 * initialization. 152 * 153 * @param pts array of points to instantiate. 154 */ 155 protected static void InitializePOINT2Array(POINT2[] pts) { 156 //int j=0; 157 if (pts == null || pts.length == 0) { 158 return; 159 } 160 int n=pts.length; 161 //for (int j = 0; j < pts.length; j++) 162 for (int j = 0; j < n; j++) 163 { 164 pts[j] = new POINT2(); 165 } 166 } 167 168 /** 169 * Calculates the center point of an area using the first vblCounter points 170 * in the array. 171 * 172 * @param pLinePoints the client points 173 * @param vblCounter the number of points in the array to use 174 * 175 * @return the center point 176 */ 177 protected static POINT2 CalcCenterPointDouble(POINT2[] pLinePoints, 178 int vblCounter) { 179 POINT2 CenterLinePoint = new POINT2(pLinePoints[0]); 180 try { 181 //declarations 182 int j = 0; 183 double dMinX = pLinePoints[0].x, 184 dMinY = pLinePoints[0].y, 185 dMaxX = pLinePoints[0].x, 186 dMaxY = pLinePoints[0].y; 187 188 //end declarations 189 dMinX = pLinePoints[0].x; 190 dMinY = pLinePoints[0].y; 191 dMaxX = pLinePoints[0].x; 192 dMaxY = pLinePoints[0].y; 193 194 for (j = 0; j < vblCounter; j++) { 195 if (pLinePoints[j].x < dMinX) { 196 dMinX = pLinePoints[j].x; 197 } 198 199 if (pLinePoints[j].y < dMinY) { 200 dMinY = pLinePoints[j].y; 201 } 202 203 if (pLinePoints[j].x > dMaxX) { 204 dMaxX = pLinePoints[j].x; 205 } 206 207 if (pLinePoints[j].y > dMaxY) { 208 dMaxY = pLinePoints[j].y; 209 } 210 211 } //end for 212 213 CenterLinePoint.x = (dMinX + dMaxX) / 2; 214 CenterLinePoint.y = (dMinY + dMaxY) / 2; 215 } catch (Error exc) { 216 ErrorLogger.LogException(_className, "CalcCenterPointDouble", 217 new RendererException("Failed inside CalcCenterPointDouble", exc)); 218 } 219 return CenterLinePoint; 220 } 221 222 /** 223 * Called by renderer Modifier2 class after ArrayList.ToArray was called, 224 * which produces an array of objects. 225 * 226 * @param pLinePoints 227 * @param vblCounter 228 * @return 229 */ 230 public static POINT2 CalcCenterPointDouble2(Object[] pLinePoints, 231 int vblCounter) { 232 POINT2 pt0 = (POINT2) pLinePoints[0]; 233 POINT2 CenterLinePoint = new POINT2(); 234 try { 235 //declarations 236 int j = 0; 237 double dMinX = pt0.x, 238 dMinY = pt0.y, 239 dMaxX = pt0.x, 240 dMaxY = pt0.y; 241 242 //end declarations 243 dMinX = pt0.x; 244 dMinY = pt0.y; 245 dMaxX = pt0.x; 246 dMaxY = pt0.y; 247 248 POINT2 pt; 249 250 for (j = 0; j < vblCounter; j++) { 251 pt = (POINT2) pLinePoints[j]; 252 if (pt.x < dMinX) { 253 dMinX = pt.x; 254 } 255 256 if (pt.y < dMinY) { 257 dMinY = pt.y; 258 } 259 260 if (pt.x > dMaxX) { 261 dMaxX = pt.x; 262 } 263 264 if (pt.y > dMaxY) { 265 dMaxY = pt.y; 266 } 267 268 } //end for 269 270 CenterLinePoint.x = (dMinX + dMaxX) / 2; 271 CenterLinePoint.y = (dMinY + dMaxY) / 2; 272 } catch (Error exc) { 273 ErrorLogger.LogException(_className, "CalcCenterPointDouble2", 274 new RendererException("Failed inside CalcCenterPointDouble2", exc)); 275 } 276 return CenterLinePoint; 277 } 278 279 /** 280 * Calculates the distance in pixels between two points 281 * 282 * @param p1 the first point 283 * @param p2 the last point 284 * 285 * @return the distance between p1 and p2 in pixels 286 */ 287 public static double CalcDistanceDouble(POINT2 p1, 288 POINT2 p2) { 289 double returnValue = 0; 290 try { 291 returnValue = Math.sqrt((p1.x - p2.x) 292 * (p1.x - p2.x) 293 + (p1.y - p2.y) 294 * (p1.y - p2.y)); 295 296 //sanity check 297 //return x or y distance if returnValue is 0 or infinity 298 double xdist = Math.abs(p1.x - p2.x); 299 double ydist = Math.abs(p1.y - p2.y); 300 double max = xdist; 301 if (ydist > xdist) { 302 max = ydist; 303 } 304 305 if (returnValue == 0 || Double.isInfinite(returnValue)) { 306 if (max > 0) { 307 returnValue = max; 308 } 309 } 310 } catch (Exception exc) { 311 ErrorLogger.LogException(_className, "CalcDistanceDouble", 312 new RendererException("Failed inside CalcDistanceDouble", exc)); 313 } 314 return returnValue; 315 } 316 317 /** 318 * Computes the slope of a line 319 * 320 * @param firstLinePoint the first line point 321 * @param lastLinePoint the last line point 322 * @param slope OUT - object with member to hold the slope of the line 323 * 324 * @return 1 if successful, else return 0 325 */ 326 protected static int CalcTrueSlopeDouble(POINT2 firstLinePoint, 327 POINT2 lastLinePoint, 328 ref<double[]> slope)//ref is a double 329 { 330 int result = 1; 331 try { 332 if (slope.value == null) { 333 slope.value = new double[1]; 334 } 335 336 double deltaX = 0, deltaY = 0; 337 deltaX = firstLinePoint.x - lastLinePoint.x; 338 //if (deltaX == 0) 339 if (Math.abs(deltaX) < 1) 340 { 341 //deltaX = 1; 342 if(deltaX>=0) 343 deltaX=1; 344 else 345 deltaX=-1; 346 result = 1; 347 } 348 deltaY = firstLinePoint.y - lastLinePoint.y; 349 350 slope.value[0] = deltaY / deltaX; //cannot blow up 351 } catch (Error exc) { 352 ErrorLogger.LogException(_className, "CalcTrueSlopeDouble", 353 new RendererException("Failed inside CalcTrueSlopeDouble", exc)); 354 } 355 return result; 356 } 357 358 public static void WriteFile(String str) { 359 try { 360 BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("Test.txt")); 361 bufferedWriter.write(str); 362 bufferedWriter.close(); 363 bufferedWriter = null; 364 } catch (Exception exc) { 365 ErrorLogger.LogException(_className, "WriteFile", 366 new RendererException("Failed inside WriteFile", exc)); 367 } 368 } 369 370 /** 371 * reverses the first vblCounter points 372 * 373 * @param pLowerLinePoints OUT - points to reverse 374 * @param vblCounter 375 */ 376 protected static void ReversePointsDouble2(POINT2[] pLowerLinePoints, 377 int vblCounter) { 378 try { 379 POINT2[] pResultPoints = new POINT2[vblCounter]; 380 int k = 0; 381 for (k = 0; k < vblCounter; k++) { 382 pResultPoints[k] = new POINT2(pLowerLinePoints[vblCounter - k - 1]); 383 } 384 for (k = 0; k < vblCounter; k++) { 385 pLowerLinePoints[k] = new POINT2(pResultPoints[k]); 386 } 387 pResultPoints = null; 388 } catch (Exception exc) { 389 ErrorLogger.LogException(_className, "ReversePointsDouble2", 390 new RendererException("Failed inside ReversePointsDouble2", exc)); 391 } 392 } 393 394 public static boolean CalcTrueSlopeDoubleForRoutes(POINT2 firstLinePoint, 395 POINT2 lastLinePoint, 396 ref<double[]> slope) { 397 try { 398 double deltaX = 0, deltaY = 0; 399 deltaX = (double) (firstLinePoint.x) - (double) (lastLinePoint.x); 400 if (Math.abs(deltaX) < 2) //was 2,infinite slope 401 { 402 return (false); 403 } 404 405 deltaY = (double) (firstLinePoint.y) - (double) (lastLinePoint.y); 406 if (slope.value == null) { 407 slope.value = new double[1]; 408 } 409 410 slope.value[0] = deltaY / deltaX; 411 } catch (Exception exc) { 412 ErrorLogger.LogException(_className, "CalcTrueSlopeDoubleForRoutes", 413 new RendererException("Failed inside CalcTrueSlopeDoubleForRoutes", exc)); 414 } 415 return true; 416 } 417 418 /** 419 * Computes the slope of a line 420 * 421 * @param firstLinePoint the first line point 422 * @param lastLinePoint the last line point 423 * @param slope OUT - object with member to hold the slope of the line 424 * 425 * @return true if successful 426 */ 427 public static boolean CalcTrueSlopeDouble2(POINT2 firstLinePoint, 428 POINT2 lastLinePoint, 429 ref<double[]> slope) { 430 Boolean result = true; 431 try { 432 double deltaX = 0, deltaY = 0; 433 deltaX = (double) (firstLinePoint.x) - (double) (lastLinePoint.x); 434 //if (deltaX == 0) 435 if (Math.abs(deltaX) < 1) 436 { 437 //deltaX = 1; 438 if(deltaX>=0) 439 deltaX=1; 440 else 441 deltaX=-1; 442 result = false; 443 } 444 445 deltaY = (double) (firstLinePoint.y) - (double) (lastLinePoint.y); 446 if (slope.value == null) { 447 slope.value = new double[1]; 448 } 449 450 slope.value[0] = deltaY / deltaX; 451 } catch (Exception exc) { 452 ErrorLogger.LogException(_className, "CalcTrueSlopeDouble2", 453 new RendererException("Failed inside CalcTrueSlopeDouble2", exc)); 454 } 455 return result; 456 } 457 458 /** 459 * Calculates the slopes and y intercepts in pixels for the line from pt1 to 460 * pt2 and a parallel line a vertical distance from the line 461 * 462 * @param nDistance the distance in pixels 463 * @param linePoint1 first point on the line 464 * @param linePoint2 last point on the line 465 * @param pdResult OUT - array to hold m, b for both lines 466 * 467 * @return 1 if the lines are not vertical, else return 0 468 */ 469 protected static int CalcTrueLinesDouble(long nDistance, 470 POINT2 linePoint1, 471 POINT2 linePoint2, 472 ref<double[]> pdResult) //for vertical line e.g. if line equation is x=7 473 { 474 try { 475 //declarations 476 int nTemp = 0; 477 double b = 0; 478 double delta = 0; 479 ref<double[]> m = new ref(); 480 //end declarations 481 nTemp = CalcTrueSlopeDouble(linePoint1, linePoint2, m); 482 pdResult.value = new double[6]; 483 //Fill the result array with the line parameters 484 if (nTemp == 0) //vertical lines 485 { 486 pdResult.value[3] = linePoint1.x + (double) nDistance; //the lower line eqn, e.g. x=7 487 pdResult.value[5] = linePoint1.x - (double) nDistance; //the upper line eqn, 488 return 0; 489 } else { 490 b = linePoint2.y - m.value[0] * linePoint2.x; 491 delta = Math.sqrt(m.value[0] * m.value[0] * ((double) (nDistance) * (double) (nDistance)) 492 + ((double) (nDistance) * (double) (nDistance))); 493 pdResult.value[0] = m.value[0]; //original line eq'n: y = mx + b 494 pdResult.value[1] = b; 495 pdResult.value[2] = m.value[0]; //lower line eq'n: y = mx + (b+dDistance) 496 pdResult.value[3] = b + delta; 497 pdResult.value[4] = m.value[0]; //upper line eq'n: y = mx + (b-dDistance) 498 pdResult.value[5] = b - delta; 499 } 500 } catch (Exception exc) { 501 ErrorLogger.LogException(_className, "CalcTrueLinesDouble", 502 new RendererException("Failed inside CalcTrueLinesDouble", exc)); 503 } 504 return 1; 505 } 506 507 /** 508 * Calculates the intersection of two lines. 509 * 510 * @param m1 slope of first line 511 * @param b1 Y intercept of first line 512 * @param m2 slope of second line 513 * @param b2 Y intercept of second line 514 * @param bolVertical1 0 if first line is vertical, else 1 515 * @param bolVertical2 0 if second line is vertical, else 1 516 * @param X1 X intercept if first line is vertical 517 * @param X2 X intercept if 2nd line is vertical. 518 * 519 * @return intersection point 520 */ 521 public static POINT2 CalcTrueIntersectDouble2(double m1, 522 double b1, 523 double m2, 524 double b2, 525 int bolVertical1, 526 int bolVertical2, 527 double X1, //x intercept if line1 is vertical 528 double X2) { 529 POINT2 ptIntersect = new POINT2(); 530 try { 531 //declarations 532 double x = 0, y = 0; 533 //end declarations 534 535 //initialize ptIntersect 536 ptIntersect.x = X1; 537 ptIntersect.y = X2; 538 if (bolVertical1 == 0 && bolVertical2 == 0) //both lines vertical 539 { 540 return ptIntersect; 541 } 542 //the following 3 if blocks are the only ways to get an intersection 543 if (bolVertical1 == 0 && bolVertical2 == 1) //line1 vertical, line2 not 544 { 545 ptIntersect.x = X1; 546 ptIntersect.y = m2 * X1 + b2; 547 return ptIntersect; 548 } 549 if (bolVertical1 == 1 && bolVertical2 == 0) //line2 vertical, line1 not 550 { 551 ptIntersect.x = X2; 552 ptIntersect.y = m1 * X2 + b1; 553 return ptIntersect; 554 } 555 //if either of the lines is vertical function has already returned 556 //so both m1 and m2 should be valid 557 if (m1 != m2) { 558 x = (b2 - b1) / (m1 - m2); //cannot blow up 559 y = (m1 * x + b1); 560 ptIntersect.x = x; 561 ptIntersect.y = y; 562 return ptIntersect; 563 } 564 } catch (Exception exc) { 565 ErrorLogger.LogException(_className, "CalcTrueIntersectDouble2", 566 new RendererException("Failed inside CalcTrueIntersectDouble2", exc)); 567 } 568 return ptIntersect; 569 } 570 571 /** 572 * Calculates an offset point for channel types which require arrows. 573 * 574 * @param startLinePoint the first point 575 * @param endLinePoint the last point 576 * @param nOffset the offset in pixels 577 * 578 * @return the offset point 579 */ 580 protected static POINT2 GetOffsetPointDouble(POINT2 startLinePoint, 581 POINT2 endLinePoint, 582 long nOffset) { 583 POINT2 tempLinePoint = new POINT2(startLinePoint); 584 try { 585 //declarations 586 double dx = endLinePoint.x - startLinePoint.x, 587 dy = endLinePoint.y - startLinePoint.y, 588 dOffset = (double) nOffset, 589 dHypotenuse = 0, 590 dAngle = 0; 591 592 //end declarations 593 if (dx == 0) { 594 if (dy > 0) { 595 tempLinePoint.x = endLinePoint.x; 596 tempLinePoint.y = endLinePoint.y + dOffset; 597 } else { 598 tempLinePoint.x = endLinePoint.x; 599 tempLinePoint.y = endLinePoint.y - dOffset; 600 } 601 return tempLinePoint; 602 } 603 if (dy == 0) { 604 if (dx > 0) { 605 tempLinePoint.x = endLinePoint.x + dOffset; 606 tempLinePoint.y = endLinePoint.y; 607 } else { 608 tempLinePoint.x = endLinePoint.x - dOffset; 609 tempLinePoint.y = endLinePoint.y; 610 } 611 return tempLinePoint; 612 } 613 614 if (dy == 0) { 615 dAngle = 0; 616 } else { 617 dAngle = Math.atan(dx / dy) + Math.PI / 2;//1.570795; 618 } 619 dHypotenuse = (double) nOffset; 620 if (endLinePoint.x > startLinePoint.x) { 621 tempLinePoint.x = endLinePoint.x + dHypotenuse * Math.abs(Math.cos(dAngle)); 622 } else { 623 tempLinePoint.x = endLinePoint.x - dHypotenuse * Math.abs(Math.cos(dAngle)); 624 } 625 if (endLinePoint.y > startLinePoint.y) { 626 tempLinePoint.y = endLinePoint.y + dHypotenuse * Math.abs(Math.sin(dAngle)); 627 } else { 628 tempLinePoint.y = endLinePoint.y - dHypotenuse * Math.abs(Math.sin(dAngle)); 629 } 630 631 } catch (Exception exc) { 632 ErrorLogger.LogException(_className, "GetOffsetPointDouble", 633 new RendererException("Failed inside GetOffsetPointDouble", exc)); 634 } 635 return (tempLinePoint); 636 } 637 638 /** 639 * Computes the arc points for FEBA Assumes pResultLinePoints has been 640 * allocated. 641 * 642 * @param dRadius the arc radius in pixels 643 * @param pLinePoints the client points, each one is a center for a computed 644 * arc (cricle) 645 * @param vblCounter number of client points to use 646 * @param pResultLinePoints OUT - the arc points to return 647 */ 648 protected static POINT2[] GetArcFEBADouble(double dRadius, 649 POINT2[] pLinePoints, 650 int vblCounter, 651 POINT2[] pResultLinePoints) { 652 try { 653 //declarations 654 double dStartAngle = 0, 655 dEndAngle = 2 * Math.PI, 656 dIncrement = (dEndAngle - dStartAngle) / 25.0; 657 658 int i = 0, j = 0, nArcCounter = 0; 659 double x = 0, y = 0; 660 POINT2 CenterLinePoint = new POINT2(pLinePoints[0]); 661 POINT2[] pArcLinePoints = new POINT2[26]; 662 //end declarations 663 InitializePOINT2Array(pArcLinePoints); 664 665 for (i = 0; i < vblCounter; i++) //stuff the pArcLinePoints collector 666 { 667 CenterLinePoint = new POINT2(pLinePoints[i]); 668 CalcCircleDouble(CenterLinePoint, dRadius, 26, pArcLinePoints, 0); 669 for (j = 0; j < 26; j++) { 670 pResultLinePoints[nArcCounter] = new POINT2(pArcLinePoints[j]); 671 nArcCounter++; 672 } 673 674 pResultLinePoints[nArcCounter - 1].style = 5; 675 } //end for 676 677 pResultLinePoints[26 * vblCounter - 1].style = 5; 678 pArcLinePoints = null; 679 } catch (Exception exc) { 680 ErrorLogger.LogException(_className, "GetArcFEBADouble", 681 new RendererException("Failed inside GetArcFEBADouble", exc)); 682 } 683 return pResultLinePoints; 684 } 685 686 /** 687 * Used for DMAF 688 * 689 * @param pLinePoints the client points 690 * @return ArrayList of X points 691 */ 692 protected static ArrayList LineOfXPoints(POINT2[] pLinePoints) { 693 ArrayList xPoints = new ArrayList(); 694 try { 695 int j = 0, k = 0; 696 double dist = 0; 697 int iterations = 0; 698 POINT2 frontPt = null, backPt = null; 699 POINT2 extendFrontAbove = null, extendFrontBelow = null; 700 POINT2 extendBackAbove = null, extendBackBelow = null; 701 POINT2 xPoint1 = null, xPoint2 = null; 702 int n=pLinePoints.length; 703 //for (j = 0; j < pLinePoints.length - 1; j++) 704 for (j = 0; j < n - 1; j++) 705 { 706 dist = CalcDistanceDouble(pLinePoints[j], pLinePoints[j + 1]); 707 iterations = (int) ((dist - 5.0) / 20.0); 708 if (dist - iterations * 20 > 10) { 709 iterations += 1; 710 } 711 712 for (k = 0; k < iterations; k++) { 713 frontPt = ExtendAlongLineDouble(pLinePoints[j], pLinePoints[j + 1], k * 20 - 5); 714 backPt = ExtendAlongLineDouble(pLinePoints[j], pLinePoints[j + 1], k * 20 + 5); 715 extendFrontAbove = ExtendDirectedLine(pLinePoints[j], pLinePoints[j + 1], frontPt, 2, 5); 716 extendFrontBelow = ExtendDirectedLine(pLinePoints[j], pLinePoints[j + 1], frontPt, 3, 5); 717 extendBackAbove = ExtendDirectedLine(pLinePoints[j], pLinePoints[j + 1], backPt, 2, 5); 718 extendBackBelow = ExtendDirectedLine(pLinePoints[j], pLinePoints[j + 1], backPt, 3, 5); 719 xPoints.add(extendFrontAbove); 720 extendBackBelow.style = 5; 721 xPoints.add(extendBackBelow); 722 xPoints.add(extendBackAbove); 723 extendFrontBelow.style = 5; 724 xPoints.add(extendFrontBelow); 725 } 726 } 727 } catch (Exception exc) { 728 ErrorLogger.LogException(_className, "LineOfXPoints", 729 new RendererException("Failed inside LineOfXPoints", exc)); 730 } 731 return xPoints; 732 } 733 734 /** 735 * Computes the "X" points for FEBA Assumes pResultLinePoints has been 736 * allocated. 737 * 738 * @param pLinePoints the client points 739 * @param dSize size in pixels to use for X 740 * @param vblCounter number of client points to use 741 * @param pResultLinePoints OUT - the points to return 742 */ 743 protected static void GetXFEBADouble(POINT2[] pLinePoints, 744 double dSize, 745 long vblCounter, 746 POINT2[] pResultLinePoints 747 ) { 748 try { 749 //declarations 750 int j = 0, nXcounter = 0; 751 752 POINT2 upperLeftLinePoint = new POINT2(pLinePoints[0]), 753 lowerLeftLinePoint = new POINT2(pLinePoints[0]), 754 upperRightLinePoint = new POINT2(pLinePoints[0]), 755 lowerRightLinePoint = new POINT2(pLinePoints[0]); 756 //end declarations 757 758 for (j = 0; j < vblCounter; j++) { 759 upperRightLinePoint.x = pLinePoints[j].x + dSize; 760 upperRightLinePoint.y = pLinePoints[j].y + dSize; 761 lowerRightLinePoint.x = pLinePoints[j].x + dSize; 762 lowerRightLinePoint.y = pLinePoints[j].y - dSize; 763 upperLeftLinePoint.x = pLinePoints[j].x - dSize; 764 upperLeftLinePoint.y = pLinePoints[j].y + dSize; 765 lowerLeftLinePoint.x = pLinePoints[j].x - dSize; 766 lowerLeftLinePoint.y = pLinePoints[j].y - dSize; 767 pResultLinePoints[nXcounter] = new POINT2(lowerLeftLinePoint); 768 769 nXcounter++; 770 pResultLinePoints[nXcounter] = new POINT2(upperRightLinePoint); 771 pResultLinePoints[nXcounter].style = 5; 772 773 nXcounter++; 774 pResultLinePoints[nXcounter] = new POINT2(upperLeftLinePoint); 775 776 nXcounter++; 777 pResultLinePoints[nXcounter] = new POINT2(lowerRightLinePoint); 778 pResultLinePoints[nXcounter].style = 5; 779 780 nXcounter++; 781 } //end for 782 } catch (Exception exc) { 783 ErrorLogger.LogException(_className, "GetXFEBADouble", 784 new RendererException("Failed inside GetXFEBADouble", exc)); 785 } 786 } 787 788 /** 789 * Reorders points for HOLD, BRDGHD 790 * 791 * @param pLinePoints OUT - client points also reordered points 792 */ 793 protected static void ReorderPoints(POINT2[] pLinePoints) { 794 try { 795 //int n = 3;//pLinePoints.length; 796 int n = pLinePoints.length; 797 POINT2 pt = new POINT2(); 798 POINT2 pt1 = new POINT2(pLinePoints[1]); 799 //reorder the points 800 for (int j = 1; j < n - 1; j++) { 801 pt = new POINT2(pLinePoints[j + 1]); 802 pLinePoints[j] = new POINT2(pt); 803 } 804 pLinePoints[n - 1] = new POINT2(pt1); 805 } catch (Exception exc) { 806 ErrorLogger.LogException(_className, "ReorderPoints", 807 new RendererException("Failed inside ReorderPoints", exc)); 808 } 809 } 810 811 /** 812 * Computes the distance in pixels of pt3 to the line from pt1 to pt2. 813 * 814 * @param pt1 first line point 815 * @param pt2 last line point 816 * @param pt3 point distance to compute 817 * @return distance to pt3 818 */ 819 public static double CalcDistanceToLineDouble(POINT2 pt1, 820 POINT2 pt2, 821 POINT2 pt3) { 822 double dResult = 0; 823 try { 824 //declarations 825 double m1 = 1, b = 0, b1 = 0; 826 POINT2 ptIntersect = new POINT2(pt1); 827 int bolVertical = 0; 828 ref<double[]> m = new ref(); 829 //end declarations 830 831 bolVertical = CalcTrueSlopeDouble(pt1, pt2, m); 832 833 //get line y intercepts 834 if (bolVertical != 0 && m.value[0] != 0) { 835 m1 = -1 / m.value[0]; 836 b = pt1.y - m.value[0] * pt1.x; 837 b1 = pt3.y - m1 * pt3.x; 838 ptIntersect = CalcTrueIntersectDouble2(m.value[0], b, m1, b1, 1, 1, ptIntersect.x, ptIntersect.y); 839 } 840 if (bolVertical != 0 && m.value[0] == 0) //horizontal line 841 { 842 ptIntersect.y = pt1.y; 843 ptIntersect.x = pt3.x; 844 } 845 if (bolVertical == 0) //vertical line 846 { 847 ptIntersect.y = pt3.y; 848 ptIntersect.x = pt1.x; 849 } 850 851 dResult = CalcDistanceDouble(pt3, ptIntersect); 852 } catch (Exception exc) { 853 //System.out.println(e.getMessage()); 854 ErrorLogger.LogException(_className, "CaclDistanceToLineDouble", 855 new RendererException("Failed inside CalcDistanceToLineDouble", exc)); 856 } 857 return dResult; 858 } 859 860 /** 861 * Calculates a point along a line. Returns the past point if the distance 862 * is 0. 863 * 864 * @param pt1 first line point 865 * @param pt2 last line point 866 * @param dist extension distance in pixels from the beginning of the line 867 * 868 * @return the extension point 869 */ 870 public static POINT2 ExtendLineDouble(POINT2 pt1, 871 POINT2 pt2, 872 double dist) { 873 POINT2 pt3 = new POINT2(); 874 try { 875 double dOriginalDistance = CalcDistanceDouble(pt1, pt2); 876 if (dOriginalDistance == 0 || dist == 0) { 877 return pt2; 878 } 879 880 pt3.x = (dOriginalDistance + dist) / dOriginalDistance * (pt2.x - pt1.x) + pt1.x; 881 pt3.y = (dOriginalDistance + dist) / dOriginalDistance * (pt2.y - pt1.y) + pt1.y; 882 } catch (Exception exc) { 883 //System.out.println(e.getMessage()); 884 ErrorLogger.LogException(_className, "ExtendLineDouble", 885 new RendererException("Failed inside ExtendLineDouble", exc)); 886 } 887 return pt3; 888 } 889 890 /** 891 * Extends a point along a line. If dist is 0 returns last point. 892 * 893 * @param pt1 first point on the line 894 * @param pt2 last point on the line 895 * @param dist the distance in pixels from pt1 896 * 897 * @return the extended point 898 */ 899 public static POINT2 ExtendAlongLineDouble(POINT2 pt1, POINT2 pt2, double dist) { 900 POINT2 pt3 = new POINT2(); 901 try { 902 double dOriginalDistance = CalcDistanceDouble(pt1, pt2); 903 if (dOriginalDistance == 0 || dist == 0) { 904 return pt2; 905 } 906 907 pt3.x = ((dist / dOriginalDistance) * (pt2.x - pt1.x) + pt1.x); 908 pt3.y = ((dist / dOriginalDistance) * (pt2.y - pt1.y) + pt1.y); 909 } catch (Exception exc) { 910 //System.out.println(e.getMessage()); 911 ErrorLogger.LogException(_className, "ExtendAlongLineDouble", 912 new RendererException("Failed inside ExtendAlongLineDouble", exc)); 913 } 914 return pt3; 915 } 916 917 public static POINT2 ExtendAlongLineDouble2(POINT2 pt1, POINT2 pt2, double dist) { 918 POINT2 pt3 = new POINT2(); 919 try { 920 double dOriginalDistance = CalcDistanceDouble(pt1, pt2); 921 if (dOriginalDistance == 0 || dist == 0) { 922 return pt1; 923 } 924 925 pt3.x = (dist / dOriginalDistance * (pt2.x - pt1.x) + pt1.x); 926 pt3.y = (dist / dOriginalDistance * (pt2.y - pt1.y) + pt1.y); 927 } catch (Exception exc) { 928 //System.out.println(e.getMessage()); 929 ErrorLogger.LogException(_className, "ExtendAlongLineDouble2", 930 new RendererException("Failed inside ExtendAlongLineDouble2", exc)); 931 } 932 return pt3; 933 } 934 935 public static POINT2 ExtendAlongLineDouble(POINT2 pt1, POINT2 pt2, double dist, int styl) { 936 POINT2 pt3 = new POINT2(); 937 try { 938 double dOriginalDistance = CalcDistanceDouble(pt1, pt2); 939 if (dOriginalDistance == 0 || dist == 0) { 940 return pt2; 941 } 942 943 pt3.x = (dist / dOriginalDistance * (pt2.x - pt1.x) + pt1.x); 944 pt3.y = (dist / dOriginalDistance * (pt2.y - pt1.y) + pt1.y); 945 pt3.style = styl; 946 } catch (Exception exc) { 947 //System.out.println(e.getMessage()); 948 ErrorLogger.LogException(_className, "ExtendAlongLineDouble", 949 new RendererException("Failed inside ExtendAlongLineDouble", exc)); 950 } 951 return pt3; 952 } 953 954 /** 955 * Extends a point above a line 956 * 957 * @param pt1 first line point 958 * @param pt2 last line point 959 * @param pt3 point at which to extend 960 * @param d distance in pixels to extend above the line 961 * @param X OUT - extended point x value 962 * @param Y OUT - extended point y value 963 * @param direction direction to extend the line 964 * 965 * @return 1 if successful, else return 0 966 */ 967 protected static int ExtendLineAbove(POINT2 pt1, 968 POINT2 pt2, 969 POINT2 pt3, 970 double d, 971 ref<double[]> X, 972 ref<double[]> Y, 973 int direction) { 974 try { 975 ref<double[]> m = new ref(); 976 double dx = 0, dy = 0; 977 int bolVertical = 0; 978 979 X.value = new double[1]; 980 Y.value = new double[1]; 981 982 bolVertical = CalcTrueSlopeDouble(pt1, pt2, m); 983 if (bolVertical == 0) { 984 return 0; //cannot extend above a vertical line 985 } 986 if (m.value[0] == 0) { 987 X.value[0] = pt3.x; 988 if (direction == 0) //extend above the line 989 { 990 Y.value[0] = pt3.y - Math.abs(d); 991 } else //extend below the line 992 { 993 Y.value[0] = pt3.y + Math.abs(d); 994 } 995 return 1; 996 } 997 //the line is neither vertical nor horizontal 998 //else function would already have returned 999 if (direction == 0) //extend above the line 1000 { 1001 dy = -Math.abs(d / (m.value[0] * Math.sqrt(1 + 1 / (m.value[0] * m.value[0])))); 1002 } else //extend below the line 1003 { 1004 dy = Math.abs(d / (m.value[0] * Math.sqrt(1 + 1 / (m.value[0] * m.value[0])))); 1005 } 1006 1007 dx = -m.value[0] * dy; 1008 X.value[0] = pt3.x + dx; 1009 Y.value[0] = pt3.y + dy; 1010 } catch (Exception exc) { 1011 //System.out.println(e.getMessage()); 1012 ErrorLogger.LogException(_className, "ExtendLineAbove", 1013 new RendererException("Failed inside ExtendLineAbove", exc)); 1014 } 1015 return 1; 1016 } 1017 1018 /** 1019 * Extends a point to the left of a line 1020 * 1021 * @param pt1 first line point 1022 * @param pt2 last line point 1023 * @param pt3 point at which to extend 1024 * @param d distance in pixels to extend above the line 1025 * @param X OUT - extended point x value 1026 * @param Y OUT - extended point y value 1027 * @param direction direction to extend the line 1028 * 1029 * @return 1 if successful, else return 0 1030 */ 1031 protected static int ExtendLineLeft(POINT2 pt1, 1032 POINT2 pt2, 1033 POINT2 pt3, 1034 double d, 1035 ref<double[]> X, 1036 ref<double[]> Y, 1037 int direction) { 1038 try { 1039 ref<double[]> m = new ref(); 1040 double dx = 0, dy = 0; 1041 int bolVertical = 0; 1042 1043 X.value = new double[1]; 1044 Y.value = new double[1]; 1045 1046 bolVertical = CalcTrueSlopeDouble(pt1, pt2, m); 1047 if (bolVertical != 0 && m.value[0] == 0) { 1048 return 0; //cannot left of horiz line 1049 } 1050 if (bolVertical == 0) //vertical line 1051 { 1052 Y.value[0] = pt3.y; 1053 if (direction == 0) //extend left of the line 1054 { 1055 X.value[0] = pt3.x - Math.abs(d); 1056 } else //extend right of the line 1057 { 1058 X.value[0] = pt3.x + Math.abs(d); 1059 } 1060 1061 return 1; 1062 } 1063 //the line is neither vertical nor horizontal 1064 //else function would already have returned 1065 if (direction == 0) //extend left of the line 1066 { 1067 dx = -Math.abs(d / Math.sqrt(1 + 1 / (m.value[0] * m.value[0]))); 1068 } else //extend right of the line 1069 { 1070 dx = Math.abs(d / Math.sqrt(1 + 1 / (m.value[0] * m.value[0]))); 1071 } 1072 1073 dy = -(1 / m.value[0]) * dx; 1074 1075 X.value[0] = pt3.x + dx; 1076 Y.value[0] = pt3.y + dy; 1077 } catch (Exception exc) { 1078 //System.out.println(e.getMessage()); 1079 ErrorLogger.LogException(_className, "ExtendLineLeft", 1080 new RendererException("Failed inside ExtendLineLeft", exc)); 1081 } 1082 return 1; 1083 } 1084 1085 /** 1086 * Calculates the direction of a point relative to a line 1087 * 1088 * @param pt0 first point fo the line 1089 * @param pt1 last point of the line 1090 * @param pt2 relative point 1091 * @deprecated 1092 * @return 0 if left, 1 if right, 2 if above, 3 if below 1093 */ 1094 protected static int CalcDirectionFromLine(POINT2 pt0, 1095 POINT2 pt1, 1096 POINT2 pt2) { 1097 int result = -1; 1098 try { 1099 double m2 = 0, b1 = 0, b2 = 0; 1100 ref<double[]> m1 = new ref(); 1101 POINT2 ptIntersect = new POINT2(); 1102 //int direction=-1; 1103 //handle vertical line 1104 if (pt0.x == pt1.x) { 1105 if (pt2.x < pt0.x) { 1106 return 0; 1107 } else { 1108 return 1; 1109 } 1110 } 1111 //handle horizontal line so that we do not have slope = 0. 1112 if (pt0.y == pt1.y) { 1113 if (pt2.y < pt0.y) { 1114 return 2; 1115 } else { 1116 return 3; 1117 } 1118 } 1119 CalcTrueSlopeDouble(pt0, pt1, m1); 1120 m2 = -1 / m1.value[0]; //slope for the perpendicular line from the line to pt2 1121 //b=mx-y line equation for line 1122 b1 = pt0.y - m1.value[0] * pt0.x; 1123 //b=mx-y line equation for perpendicular line which contains pt2 1124 b2 = pt2.y - m2 * pt2.x; 1125 ptIntersect = CalcTrueIntersectDouble2(m1.value[0], b1, m2, b2, 1, 1, 0, 0); 1126 //compare the intersection point with pt2 to get the direction, 1127 //i.e. the direction from the line is the same as the direction 1128 //from the interseciton point. 1129 if (m1.value[0] > 1) //line is steep, use left/right 1130 { 1131 if (pt2.x < ptIntersect.x) { 1132 return 0; 1133 } else { 1134 return 1; 1135 } 1136 } else //line is not steep, use above/below 1137 { 1138 if (pt2.y < ptIntersect.y) { 1139 return 2; 1140 } else { 1141 return 3; 1142 } 1143 } 1144 //should not reach this point 1145 //return direction; 1146 } catch (Exception e) { 1147 System.out.println(e.getMessage()); 1148 } 1149 return result; 1150 } 1151 1152 /** 1153 * Returns a point extended perpendicularly from a line at a given direction 1154 * 1155 * @param pt1 first line point 1156 * @param pt2 last line point 1157 * @param pt0 on line from which to extend 1158 * @param direction the direction to extend: above, below, left, right 1159 * @param d the length to extend in pixels 1160 * 1161 */ 1162 public static POINT2 ExtendDirectedLine(POINT2 pt1, 1163 POINT2 pt2, 1164 POINT2 pt0, 1165 int direction, 1166 double d) { 1167 POINT2 ptResult = new POINT2(); 1168 try { 1169 ref<double[]> X = new ref(), Y = new ref(); 1170 ptResult = new POINT2(pt0); 1171 switch (direction) { 1172 case 0: //extend left 1173 ExtendLineLeft(pt1, pt2, pt0, d, X, Y, 0); 1174 break; 1175 case 1: //extend right 1176 ExtendLineLeft(pt1, pt2, pt0, d, X, Y, 1); 1177 break; 1178 case 2: //extend above 1179 ExtendLineAbove(pt1, pt2, pt0, d, X, Y, 0); 1180 break; 1181 case 3: //extend below 1182 ExtendLineAbove(pt1, pt2, pt0, d, X, Y, 1); 1183 break; 1184 default: 1185 break; 1186 } 1187 ptResult.x = X.value[0]; 1188 ptResult.y = Y.value[0]; 1189 } catch (Exception exc) { 1190 //System.out.println(e.getMessage()); 1191 ErrorLogger.LogException(_className, "ExtendDirectedLine", 1192 new RendererException("Failed inside ExtendDirectedLine", exc)); 1193 } 1194 return ptResult; 1195 } 1196 1197 /** 1198 * @deprecated Returns a point extended perpendicularly from a line at a 1199 * given direction same as original function except it accounts for vertical 1200 * lines and negative d values 1201 * 1202 * @param pt1 first line point 1203 * @param pt2 last line point 1204 * @param pt0 on line from which to extend 1205 * @param direction the direction to extend: above, below, left, right 1206 * @param d the length to extend in pixels 1207 * 1208 */ 1209 public static POINT2 ExtendDirectedLineText(POINT2 pt1, 1210 POINT2 pt2, 1211 POINT2 pt0, 1212 int direction, 1213 double d) { 1214 POINT2 ptResult = new POINT2(); 1215 try { 1216 ref<double[]> X = new ref(), Y = new ref(); 1217 ptResult = new POINT2(pt0); 1218 if (d < 0) { 1219 switch (direction) { 1220 case 0: 1221 direction = extend_right; 1222 break; 1223 case 1: 1224 direction = extend_left; 1225 break; 1226 case 2: 1227 direction = extend_below; 1228 break; 1229 case 3: 1230 direction = extend_above; 1231 break; 1232 default: 1233 break; 1234 } 1235 d = Math.abs(d); 1236 } 1237 if (pt1.y == pt2.y)//horizontal segment 1238 { 1239 switch (direction) { 1240 case 0://left means above 1241 direction = extend_above; 1242 case 1://right means below 1243 direction = extend_below; 1244 default: 1245 break; 1246 } 1247 } 1248 if (pt1.x == pt2.x)//vertical segment 1249 { 1250 switch (direction) { 1251 case 2://above means left 1252 direction = extend_left; 1253 case 3://below means right 1254 direction = extend_right; 1255 default: 1256 break; 1257 } 1258 } 1259 switch (direction) { 1260 case 0: //extend left 1261 ExtendLineLeft(pt1, pt2, pt0, d, X, Y, 0); 1262 break; 1263 case 1: //extend right 1264 ExtendLineLeft(pt1, pt2, pt0, d, X, Y, 1); 1265 break; 1266 case 2: //extend above 1267 ExtendLineAbove(pt1, pt2, pt0, d, X, Y, 0); 1268 break; 1269 case 3: //extend below 1270 ExtendLineAbove(pt1, pt2, pt0, d, X, Y, 1); 1271 break; 1272 default: 1273 break; 1274 } 1275 ptResult.x = X.value[0]; 1276 ptResult.y = Y.value[0]; 1277 } catch (Exception exc) { 1278 //System.out.println(e.getMessage()); 1279 ErrorLogger.LogException(_className, "ExtendDirectedLine", 1280 new RendererException("Failed inside ExtendDirectedLine", exc)); 1281 } 1282 return ptResult; 1283 } 1284 1285 /** 1286 * Returns a point extended perpendicularly from a line at a given direction 1287 * 1288 * @param pt1 first line point 1289 * @param pt2 last line point 1290 * @param pt0 on line from which to extend 1291 * @param direction the direction to extend: above, below, left, right 1292 * @param d the length to extend in pixels 1293 * @param style the style to assign the return point 1294 * 1295 */ 1296 public static POINT2 ExtendDirectedLine(POINT2 pt1, 1297 POINT2 pt2, 1298 POINT2 pt0, 1299 int direction, 1300 double d, 1301 int style) { 1302 POINT2 ptResult = new POINT2(pt0); 1303 try { 1304 ref<double[]> X = new ref(), Y = new ref(); 1305 //int bolResult=0; 1306 //handle parallel, perpendicular cases 1307 if (pt1.x == pt2.x) { 1308 if (direction == 2) { 1309 direction = 0; 1310 } 1311 if (direction == 3) { 1312 direction = 1; 1313 } 1314 } 1315 if (pt1.y == pt2.y) { 1316 if (direction == 0) { 1317 direction = 2; 1318 } 1319 if (direction == 1) { 1320 direction = 3; 1321 } 1322 } 1323 switch (direction) { 1324 case 0: //extend left 1325 ExtendLineLeft(pt1, pt2, pt0, d, X, Y, 0); 1326 break; 1327 case 1: //extend right 1328 ExtendLineLeft(pt1, pt2, pt0, d, X, Y, 1); 1329 break; 1330 case 2: //extend above 1331 ExtendLineAbove(pt1, pt2, pt0, d, X, Y, 0); 1332 break; 1333 case 3: //extend below 1334 ExtendLineAbove(pt1, pt2, pt0, d, X, Y, 1); 1335 break; 1336 } 1337 ptResult.x = X.value[0]; 1338 ptResult.y = Y.value[0]; 1339 ptResult.style = style; 1340 } catch (Exception exc) { 1341 ErrorLogger.LogException(_className, "ExtendDirectedLine", 1342 new RendererException("Failed inside ExtendDirectedLine", exc)); 1343 } 1344 return ptResult; 1345 } 1346 1347 /** 1348 * Calculates a point along a line 1349 * 1350 * @param pt1 first line point 1351 * @param pt2 last line point 1352 * @param dist extension distance in pixels from the beginning of the line 1353 * @param styl the line style to assign the point 1354 * 1355 * @return the extension point 1356 */ 1357 protected static POINT2 ExtendLine2Double(POINT2 pt1, 1358 POINT2 pt2, 1359 double dist, 1360 int styl) { 1361 POINT2 pt3 = new POINT2(); 1362 try { 1363 double dOriginalDistance = CalcDistanceDouble(pt1, pt2); 1364 1365 pt3.x = pt2.x; 1366 pt3.y = pt2.y; 1367 if (dOriginalDistance > 0) { 1368 pt3.x = ((dOriginalDistance + dist) / dOriginalDistance * (pt2.x - pt1.x) + pt1.x); 1369 pt3.y = ((dOriginalDistance + dist) / dOriginalDistance * (pt2.y - pt1.y) + pt1.y); 1370 pt3.style = styl; 1371 } 1372 } catch (Exception exc) { 1373 ErrorLogger.LogException(_className, "ExtendLine2Double", 1374 new RendererException("Failed inside ExtendLine2Double", exc)); 1375 } 1376 return pt3; 1377 } 1378 1379 /** 1380 * Extends a point at an angle from a line. 1381 * 1382 * @param pt0 the first line point 1383 * @param pt1 the second line point 1384 * @param pt2 point on line from which to extend 1385 * @param alpha angle of extension in degrees 1386 * @param d the distance in pixels to extend 1387 * 1388 * @return the extension point 1389 */ 1390 public static POINT2 ExtendAngledLine(POINT2 pt0, 1391 POINT2 pt1, 1392 POINT2 pt2, 1393 double alpha, 1394 double d) { 1395 POINT2 pt = new POINT2(); 1396 try { 1397 //first get the angle psi between pt0 and pt1 1398 double psi = Math.atan((pt1.y - pt0.y) / (pt1.x - pt0.x)); 1399 //convert alpha to radians 1400 double alpha1 = Math.PI * alpha / 180; 1401 1402 //theta is the angle of extension from the x axis 1403 double theta = psi + alpha1; 1404 //dx is the x extension from pt2 1405 double dx = d * Math.cos(theta); 1406 //dy is the y extension form pt2 1407 double dy = d * Math.sin(theta); 1408 pt.x = pt2.x + dx; 1409 pt.y = pt2.y + dy; 1410 } catch (Exception exc) { 1411 ErrorLogger.LogException(_className, "ExtendAngledLine", 1412 new RendererException("Failed inside ExtendAngledLine", exc)); 1413 } 1414 return pt; 1415 } 1416 1417 /** 1418 * Returns an integer indicating the quadrant for the direction of the line 1419 * from pt1 to pt2 1420 * 1421 * @param pt1 first line point 1422 * @param pt2 second line point 1423 * 1424 * @return the quadrant 1425 */ 1426 public static int GetQuadrantDouble(POINT2 pt1, 1427 POINT2 pt2) { 1428 int nQuadrant = 1; 1429 try { 1430 if (pt2.x >= pt1.x && pt2.y <= pt1.y) { 1431 nQuadrant = 1; 1432 } 1433 if (pt2.x >= pt1.x && pt2.y >= pt1.y) { 1434 nQuadrant = 2; 1435 } 1436 if (pt2.x <= pt1.x && pt2.y >= pt1.y) { 1437 nQuadrant = 3; 1438 } 1439 if (pt2.x <= pt1.x && pt2.y <= pt1.y) { 1440 nQuadrant = 4; 1441 } 1442 1443 } catch (Exception exc) { 1444 ErrorLogger.LogException(_className, "GetQuadrantDouble", 1445 new RendererException("Failed inside GetQuadrantDouble", exc)); 1446 } 1447 return nQuadrant; 1448 } 1449 1450 public static int GetQuadrantDouble(double x1, double y1, 1451 double x2, double y2) { 1452 int nQuadrant = 1; 1453 try { 1454// if(pt2.x>=pt1.x && pt2.y<=pt1.y) 1455// nQuadrant=1; 1456// if(pt2.x>=pt1.x && pt2.y>=pt1.y) 1457// nQuadrant=2; 1458// if(pt2.x<=pt1.x && pt2.y>=pt1.y) 1459// nQuadrant=3; 1460// if(pt2.x<=pt1.x && pt2.y<=pt1.y) 1461// nQuadrant=4; 1462 1463 if (x2 >= x1 && y2 <= y1) { 1464 nQuadrant = 1; 1465 } 1466 if (x2 >= x1 && y2 >= y1) { 1467 nQuadrant = 2; 1468 } 1469 if (x2 <= x1 && y2 >= y1) { 1470 nQuadrant = 3; 1471 } 1472 if (x2 <= x1 && y2 <= y1) { 1473 nQuadrant = 4; 1474 } 1475 } catch (Exception exc) { 1476 ErrorLogger.LogException(_className, "GetQuadrantDouble", 1477 new RendererException("Failed inside GetQuadrantDouble", exc)); 1478 } 1479 return nQuadrant; 1480 } 1481 1482 /** 1483 * Returns the smallest x and y pixel values from an array of points 1484 * 1485 * @param ptsSeize array of points from which to find minimum vaules 1486 * @param vblCounter the number of points to test in the array 1487 * @param x OUT - an object with a member to hold the xminimum 1488 * @param y OUT - an object with a member to hold the y minimum value 1489 * 1490 */ 1491 protected static void GetPixelsMin(POINT2[] ptsSeize, 1492 int vblCounter, 1493 ref<double[]> x, 1494 ref<double[]> y) { 1495 try { 1496 double xmin = Double.POSITIVE_INFINITY; 1497 double ymin = Double.POSITIVE_INFINITY; 1498 int j = 0; 1499 1500 for (j = 0; j < vblCounter; j++) { 1501 if (ptsSeize[j].x < xmin) { 1502 xmin = ptsSeize[j].x; 1503 } 1504 if (ptsSeize[j].y < ymin) { 1505 ymin = ptsSeize[j].y; 1506 } 1507 } 1508 x.value = new double[1]; 1509 y.value = new double[1]; 1510 x.value[0] = xmin; 1511 y.value[0] = ymin; 1512 } catch (Exception exc) { 1513 ErrorLogger.LogException(_className, "GetPixelsMin", 1514 new RendererException("Failed inside GetPixelsMin", exc)); 1515 } 1516 } 1517 1518 /** 1519 * Returns center point for a clockwise arc to connect pts 1 and 2. Also 1520 * returns an extended point on the line between pt1 and the new center 1521 * Caller passes a POINT1 array of size 2 for ptsSeize, passes pt1 and pt2 1522 * in ptsSeize Returns the radius of the 90 degree arc between C (arc 1523 * center) and pt1 1524 * 1525 * @param ptsSeize OUT - two point array also used for the returned two 1526 * points 1527 * 1528 * @return the radius 1529 */ 1530 protected static double CalcClockwiseCenterDouble(POINT2[] ptsSeize) { 1531 double dRadius = 0; 1532 try { 1533 //declarations 1534 POINT2 pt1 = new POINT2(ptsSeize[0]); 1535 POINT2 pt2 = new POINT2(ptsSeize[1]); 1536 POINT2 C = new POINT2(pt1), midPt = new POINT2(pt1); //the center to calculate 1537 POINT2 E = new POINT2(pt1); //the extended point to calculate 1538 POINT2 ptYIntercept = new POINT2(pt1); 1539 int nQuadrant = 1; 1540 double b = 0, b1 = 0, b2 = 0, dLength = 0; 1541 ref<double[]> m = new ref(); 1542 int bolVertical = 0; 1543 ref<double[]> offsetX = new ref(), offsetY = new ref(); 1544 POINT2[] ptsTemp = new POINT2[2]; 1545 //end declarations 1546 1547 //must offset the points if necessary because there will be calculations 1548 //extending from the Y Intercept 1549 ptsTemp[0] = new POINT2(pt1); 1550 ptsTemp[1] = new POINT2(pt2); 1551 GetPixelsMin(ptsTemp, 2, offsetX, offsetY); 1552 if (offsetX.value[0] < 0) { 1553 offsetX.value[0] = offsetX.value[0] - 100; 1554 } else { 1555 offsetX.value[0] = 0; 1556 } 1557 //end section 1558 1559 midPt.x = (pt1.x + pt2.x) / 2; 1560 midPt.y = (pt1.y + pt2.y) / 2; 1561 dLength = CalcDistanceDouble(pt1, pt2); 1562 dRadius = dLength / Math.sqrt(2); 1563 nQuadrant = GetQuadrantDouble(pt1, pt2); 1564 1565 bolVertical = CalcTrueSlopeDouble(pt1, pt2, m); 1566 if (bolVertical != 0 && m.value[0] != 0) //line not vertical or horizontal 1567 { 1568 b = pt1.y - m.value[0] * pt1.x; 1569 //y intercept of line perpendicular to midPt of pt,p2 1570 b1 = midPt.y + (1 / m.value[0]) * midPt.x; 1571 //we want to shift the Y axis to the left by offsetX 1572 //so we get the new Y intercept at x=offsetX 1573 b2 = (-1 / m.value[0]) * offsetX.value[0] + b1; 1574 ptYIntercept.x = offsetX.value[0]; 1575 ptYIntercept.y = b2; 1576 switch (nQuadrant) { 1577 case 1: 1578 case 4: 1579 C = ExtendLineDouble(ptYIntercept, midPt, dLength / 2); 1580 break; 1581 case 2: 1582 case 3: 1583 C = ExtendLineDouble(ptYIntercept, midPt, -dLength / 2); 1584 break; 1585 default: 1586 break; 1587 } 1588 } 1589 if (bolVertical != 0 && m.value[0] == 0) //horizontal line 1590 { 1591 C.x = midPt.x; 1592 if (pt1.x < pt2.x) { 1593 C.y = midPt.y + dLength / 2; 1594 } else { 1595 C.y = midPt.y - dLength / 2; 1596 } 1597 } 1598 if (bolVertical == 0) //vertical line 1599 { 1600 ptYIntercept.x = offsetX.value[0]; 1601 ptYIntercept.y = midPt.y; 1602 switch (nQuadrant) { 1603 case 1: 1604 case 4: 1605 C = ExtendLineDouble(ptYIntercept, midPt, dLength / 2); 1606 break; 1607 case 2: 1608 case 3: 1609 C = ExtendLineDouble(ptYIntercept, midPt, -dLength / 2); 1610 break; 1611 default: 1612 break; 1613 } 1614 } 1615 1616 E = ExtendLineDouble(C, pt1, 50); 1617 ptsSeize[0] = new POINT2(C); 1618 ptsSeize[1] = new POINT2(E); 1619 1620 ptsTemp = null; 1621 } catch (Exception exc) { 1622 ErrorLogger.LogException(_className, "CalcClockwiseCenterDouble", 1623 new RendererException("Failed inside CalcClockwiseCenterDouble", exc)); 1624 } 1625 return dRadius; 1626 } 1627 1628 /** 1629 * Computes the points for an arrowhead based on a line segment 1630 * 1631 * @param startLinePoint segment start point 1632 * @param endLinePoint segment end point 1633 * @param nBiSector bisecotr in pixels 1634 * @param nBase base size in pixels 1635 * @param pResultLinePoints OUT - the arrowhead points 1636 * @param styl the line style to assign the last aroowhead point 1637 */ 1638 protected static void GetArrowHead4Double(POINT2 startLinePoint, 1639 POINT2 endLinePoint, 1640 int nBiSector, 1641 int nBase, 1642 POINT2[] pResultLinePoints, 1643 int styl) { 1644 try { 1645 //declarations 1646 int j = 0; 1647 double dy = (double) (endLinePoint.y - startLinePoint.y), 1648 dx = (double) (endLinePoint.x - startLinePoint.x), 1649 dSign = 1.0, 1650 AHBY = 0, 1651 AHBX = 0, 1652 AHBLY = 0, 1653 AHBLX = 0, 1654 AHBRY = 0, 1655 AHBRX = 0, 1656 dAngle = 0, 1657 dHypotenuse = 0; 1658 1659 POINT2 tempLinePoint = new POINT2(startLinePoint); 1660 //end declarations 1661 1662 if (dy == 0) { 1663 if (dx > 0) { 1664 dAngle = Math.PI; 1665 } else { 1666 dAngle = 0; 1667 } 1668 } else { 1669 dAngle = Math.atan(dx / dy) + Math.PI / 2; 1670 } 1671 1672 tempLinePoint.style = 0;//PS_SOLID; 1673 1674 if (dx <= 0.0 && dy <= 0.0) { 1675 dSign = -1.0; 1676 } 1677 if (dx >= 0.0 && dy <= 0.0) { 1678 dSign = -1.0; 1679 } 1680 if (dx <= 0.0 && dy >= 0.0) { 1681 dSign = 1.0; 1682 } 1683 if (dx >= 0.0 && dy >= 0.0) { 1684 dSign = 1.0; 1685 } 1686 1687 dHypotenuse = dSign * (double) nBiSector; 1688 1689 //Find x, y for Arrow Head nBase startLinePoint POINT1 1690 AHBX = (double) endLinePoint.x + dHypotenuse * Math.cos(dAngle); 1691 AHBY = (double) endLinePoint.y - dHypotenuse * Math.sin(dAngle); 1692 1693 //Half of the arrow head's length will be 10 units 1694 dHypotenuse = dSign * (double) (nBase / 2.0); 1695 1696 //Find x, y of Arrow Head nBase Left side end POINT1 1697 AHBLX = AHBX - dHypotenuse * Math.sin(dAngle); 1698 AHBLY = AHBY - dHypotenuse * Math.cos(dAngle); 1699 1700 //Find x, y of Arrow Head nBase Right side end POINT1 1701 AHBRX = AHBX + dHypotenuse * Math.sin(dAngle); 1702 AHBRY = AHBY + dHypotenuse * Math.cos(dAngle); 1703 1704 //replacement, just trying to return the POINT1s 1705 tempLinePoint.x = (int) AHBLX; 1706 tempLinePoint.y = (int) AHBLY; 1707 pResultLinePoints[0] = new POINT2(tempLinePoint); 1708 pResultLinePoints[1] = new POINT2(endLinePoint); 1709 tempLinePoint.x = (int) AHBRX; 1710 tempLinePoint.y = (int) AHBRY; 1711 pResultLinePoints[2] = new POINT2(tempLinePoint); 1712 switch (styl) { 1713 case 0: 1714 for (j = 0; j < 2; j++) { 1715 pResultLinePoints[j].style = 0; 1716 } 1717 pResultLinePoints[2].style = 5; 1718 break; 1719 case 9: 1720 for (j = 0; j < 2; j++) { 1721 pResultLinePoints[j].style = 9; 1722 } 1723 pResultLinePoints[2].style = 10; 1724 break; 1725 case 18: 1726 for (j = 0; j < 2; j++) { 1727 pResultLinePoints[j].style = 18; 1728 } 1729 pResultLinePoints[2].style = 5; 1730 break; 1731 default: 1732 for (j = 0; j < 2; j++) { 1733 pResultLinePoints[j].style = styl; 1734 } 1735 pResultLinePoints[2].style = 5; 1736 break; 1737 } 1738 } catch (Exception exc) { 1739 ErrorLogger.LogException(_className, "GetArrowhead4Double", 1740 new RendererException("Failed inside GetArrowhead4Double", exc)); 1741 } 1742 } 1743 1744 /** 1745 * Returns the midpoint between two points. 1746 * 1747 * @param pt0 the first point 1748 * @param pt1 the second point 1749 * @param styl the style to assign the mid point 1750 * 1751 * @return the mid point 1752 */ 1753 public static POINT2 MidPointDouble(POINT2 pt0, 1754 POINT2 pt1, 1755 int styl) { 1756 POINT2 ptResult = new POINT2(pt0); 1757 try { 1758 ptResult.x = (pt0.x + pt1.x) / 2; 1759 ptResult.y = (pt0.y + pt1.y) / 2; 1760 ptResult.style = styl; 1761 } catch (Exception exc) { 1762 ErrorLogger.LogException(_className, "MidPointDouble", 1763 new RendererException("Failed inside MidPointDouble", exc)); 1764 } 1765 return ptResult; 1766 } 1767 1768 /** 1769 * Rotates an the first vblCounter points in the array about its first point 1770 * 1771 * @param pLinePoints OUT - the points to rotate 1772 * @param vblCounter the number of points to rotate 1773 * @param lAngle the angle in degrees to rotate 1774 * 1775 * @return pLinePoints 1776 */ 1777 protected static POINT2[] RotateGeometryDoubleOrigin(POINT2[] pLinePoints, 1778 int vblCounter, 1779 int lAngle) { 1780 try { 1781 //declarations 1782 int j = 0; 1783 double dRotate = 0, 1784 dTheta = 0, 1785 dGamma = 0, 1786 x = 0, 1787 y = 0; 1788 //end declarations 1789 1790 if (lAngle != 0) { 1791 POINT2 pdCenter = new POINT2(); 1792 dRotate = (double) lAngle * Math.PI / 180d; 1793 //pdCenter = CalcCenterPointDouble(pLinePoints,vblCounter); 1794 pdCenter = new POINT2(pLinePoints[0]); 1795 1796 for (j = 0; j < vblCounter; j++) { 1797 dGamma = Math.PI + Math.atan((pLinePoints[j].y - pdCenter.y) 1798 / (pLinePoints[j].x - pdCenter.x)); 1799 1800 if (pLinePoints[j].x >= pdCenter.x) { 1801 dGamma = dGamma + Math.PI; 1802 } 1803 1804 dTheta = dRotate + dGamma; 1805 y = CalcDistanceDouble(pLinePoints[j], pdCenter) * Math.sin(dTheta); 1806 x = CalcDistanceDouble(pLinePoints[j], pdCenter) * Math.cos(dTheta); 1807 pLinePoints[j].y = pdCenter.y + y; 1808 pLinePoints[j].x = pdCenter.x + x; 1809 } //end for 1810 1811 return pLinePoints; 1812 } //end if 1813 } catch (Exception exc) { 1814 ErrorLogger.LogException(_className, "RotateGeometryDoubleOrigin", 1815 new RendererException("Failed inside RotateGeometryDoubleOrigin", exc)); 1816 } 1817 return pLinePoints; 1818 } // end function 1819 1820 /** 1821 * Returns a point a distance d pixels perpendicular to the pt0-pt1 line and 1822 * going toward pt2 1823 * 1824 * @param pt0 the first line point 1825 * @param pt1 the second line point 1826 * @param pt2 the relative line point 1827 * @param d the distance in pixels 1828 * @param styl the linestyle to assign the computed point 1829 * 1830 * @return the extended point 1831 */ 1832 public static POINT2 ExtendTrueLinePerpDouble(POINT2 pt0, 1833 POINT2 pt1, 1834 POINT2 pt2, 1835 double d, 1836 int styl) { 1837 POINT2 ptResult = new POINT2(pt0); 1838 try { 1839 POINT2 ptYIntercept = new POINT2(pt0); 1840 ref<double[]> m = new ref(); 1841 double b = 0, b1 = 0; //b is the normal Y intercept (at 0) 1842 int nTemp = 0; //b1 is the y intercept at offsetX 1843 1844 //must obtain x minimum to get the y-intercept to the left of 1845 //the left-most point 1846 ref<double[]> offsetX = new ref(), offsetY = new ref(); 1847 POINT2[] pts = new POINT2[3]; 1848 pts[0] = new POINT2(pt0); 1849 pts[1] = new POINT2(pt1); 1850 pts[2] = new POINT2(pt2); 1851 GetPixelsMin(pts, 3, offsetX, offsetY); 1852 1853 if (offsetX.value[0] <= 0) //was < 0 1854 { 1855 offsetX.value[0] = offsetX.value[0] - 100; 1856 } else { 1857 offsetX.value[0] = 0; 1858 } 1859 //end section 1860 1861 nTemp = CalcTrueSlopeDouble(pt0, pt1, m); 1862 switch (nTemp) { 1863 case 0: //vertical line 1864 if (pt0.y < pt1.y) { 1865 ptResult.x = pt2.x - d; 1866 ptResult.y = pt2.y; 1867 } else { 1868 ptResult.x = pt2.x + d; 1869 ptResult.y = pt2.y; 1870 } 1871 break; 1872 default: //non-vertical line 1873 if (m.value[0] == 0) { 1874 ptResult.x = pt2.x; 1875 ptResult.y = pt2.y + d; 1876 } else { 1877 b = (double) pt2.y + (1 / m.value[0]) * (double) pt2.x; 1878 //we need the y-intercept at the -offset 1879 b1 = (-1 / m.value[0]) * offsetX.value[0] + b; 1880 ptYIntercept.x = offsetX.value[0]; 1881 ptYIntercept.y = b1; 1882 ptResult = ExtendLineDouble(ptYIntercept, pt2, d); 1883 } 1884 break; 1885 } 1886 ptResult.style = styl; 1887 pts = null; 1888 } catch (Exception exc) { 1889 ErrorLogger.LogException(_className, "ExtendTrueLinePerpDouble", 1890 new RendererException("Failed inside ExtendTrueLinePerpDouble", exc)); 1891 } 1892 return ptResult; 1893 } 1894 1895 /** 1896 * Calculates the intersection of 2 lines pelative to a point. if one of the 1897 * lines is vertical use a distance dWidth above or below the line. pass 1898 * bolVertical1 = 1, or bolVertical2 = 1 if either line segment is vertical, 1899 * else pass 0. return the unique intersection in X,Y pointers. p2 is the 1900 * point that connects the 2 line segments to which the intersecting lines 1901 * are related, i.e. the intersecting lines are a distance dWidth pixels 1902 * above or below p2. uses dWidth and lOrient for cases in which at least 1903 * one of the lines is vertical. for normal lines this function assumes the 1904 * caller has passed the m, b for the appropriate upper or lower lines to 1905 * get the desired intgercept. this function is used for calculating the 1906 * upper and lower channel lines for channel types. For lOrient: see 1907 * comments in Channels.ConnectTrueDouble2 1908 * 1909 * @param m1 slope of the first line 1910 * @param b1 intercept of the first line 1911 * @param m2 slope of the second line 1912 * @param b2 y intercept of the second line 1913 * @param p2 point that connects the 2 line segments to which the 1914 * intersecting lines are related 1915 * @param bolVerticalSlope1 1 if first segment is vertical, else 0 1916 * @param bolVerticalSlope2 1 if second line segment is vertical, else 0 1917 * @param dWidth the distance of the intersecting lines from p2 in pixels 1918 * @param lOrient the orientation of the intersecting lines relative to the 1919 * segments connecting p2 1920 * @param X OUT - object holds the x value of the intersection point 1921 * @param Y OUT - object holds the y value of the intersection point 1922 */ 1923 protected static int CalcTrueIntersectDouble(double m1, 1924 double b1, 1925 double m2, 1926 double b2, 1927 POINT2 p2, //can use for vertical lines 1928 int bolVerticalSlope1, 1929 int bolVerticalSlope2, 1930 double dWidth, //use for vertical lines, use + for upper line, - for lower line 1931 int lOrient, 1932 ref<double[]> X, //intersection x value 1933 ref<double[]> Y) //intersection y value 1934 { 1935 1936 try { 1937 //case both lines are vertical 1938 double dWidth2 = Math.abs(dWidth); 1939 double b = 0; 1940 double dx = 0, dy = 0, m = 0; 1941 X.value = new double[1]; 1942 Y.value = new double[1]; 1943 1944 //cannot get out of having to do this 1945 //the problem is caused by inexact slopes which are created by 1946 //clsLineUtility.DisplayIntersectPixels. This occurs when setting 1947 //pt2 or pt3 with X or Y on the boundary +/-maxPixels 1948 //if you try to walk out until you get exactly the same slope 1949 //it can be thousands of pixels, so you have to accept an arbitrary 1950 //and, unfortuantely, inexact slope 1951 if (m1 != m2 && Math.abs(m1 - m2) <= Double.MIN_VALUE) { 1952 m1 = m2; 1953 } 1954 if (b1 != b2 && Math.abs(b1 - b2) <= Double.MIN_VALUE) { 1955 b1 = b2; 1956 } 1957 1958 //M. Deutch 10-24-11 1959 if (b1 == b2 && m1 + b1 == m2 + b2) { 1960 m1 = m2; 1961 } 1962 1963 if (bolVerticalSlope1 == 0 && bolVerticalSlope2 == 0) //both lines vertical 1964 { 1965 switch (lOrient) { 1966 case 0: 1967 X.value[0] = p2.x - dWidth2; 1968 Y.value[0] = p2.y; 1969 break; 1970 case 3: 1971 X.value[0] = p2.x + dWidth2; 1972 Y.value[0] = p2.y; 1973 break; 1974 default: //can never occur 1975 X.value[0] = p2.x; 1976 Y.value[0] = p2.y; 1977 break; 1978 } 1979 return 1; 1980 } 1981 if (bolVerticalSlope1 == 0 && bolVerticalSlope2 != 0) //line1 vertical, line2 is not 1982 { //there is a unique intersection 1983 switch (lOrient) { 1984 case 0: //Line1 above segment1 1985 case 1: 1986 X.value[0] = p2.x - dWidth2; 1987 Y.value[0] = m2 * X.value[0] + b2; 1988 break; 1989 case 2: //Line1 below segment1 1990 case 3: 1991 X.value[0] = p2.x + dWidth2; 1992 Y.value[0] = m2 * X.value[0] + b2; 1993 break; 1994 default: //can not occur 1995 X.value[0] = p2.x; 1996 Y.value[0] = p2.y; 1997 break; 1998 } 1999 return 1; 2000 } 2001 if (bolVerticalSlope2 == 0 && bolVerticalSlope1 != 0) //line2 vertical, line1 is not 2002 { //there is a unique intersection 2003 switch (lOrient) { 2004 case 0: //Line1 above segment2 2005 case 2: 2006 X.value[0] = p2.x - dWidth2; 2007 Y.value[0] = m1 * (X.value[0]) + b1; 2008 break; 2009 case 1: //Line1 below segment2 2010 case 3: 2011 X.value[0] = p2.x + dWidth2; 2012 Y.value[0] = m1 * (X.value[0]) + b1; 2013 break; 2014 default: //can not occur 2015 X.value[0] = p2.x; 2016 Y.value[0] = p2.y; 2017 break; 2018 } 2019 return 1; 2020 }//end if 2021 2022 //must deal with this case separately because normal lines use m1-m2 as a denominator 2023 //but we've handled all the vertical cases above so can assume it's not vertical 2024 //if the b's are different then one is an upper line, the other is a lower, no intersection 2025 //m and b will be used to build the perpendicular line thru p2 which we will use to 2026 //build the intersection, so must assume slopes are not 0, handle separately 2027 if (m1 == m2 && m1 != 0) { 2028 if (b1 == b2) //then the intercept is the point joining the 2 segments 2029 { 2030 //build the perpendicular line 2031 m = -1 / m1; 2032 b = p2.y - m * p2.x; 2033 X.value[0] = (b2 - b) / (m - m2); //intersect the lines (cannot blow up, m = m2 not possible) 2034 Y.value[0] = (m1 * (X.value[0]) + b1); 2035 return 1; 2036 } else //can not occur 2037 { 2038 X.value[0] = p2.x; 2039 Y.value[0] = p2.y; 2040 return 1; 2041 } 2042 } 2043 //slope is zero 2044 if (m1 == m2 && m1 == 0) { 2045 switch (lOrient) { 2046 case 0: //Line1 above the line 2047 case 1: //should never happen 2048 X.value[0] = p2.x; 2049 Y.value[0] = p2.y - dWidth2; 2050 break; 2051 case 3: //Line1 below the line 2052 case 2: //should never happen 2053 X.value[0] = p2.x; 2054 Y.value[0] = p2.y + dWidth2; 2055 break; 2056 default: //can not occur 2057 X.value[0] = p2.x; 2058 Y.value[0] = p2.y; 2059 break; 2060 } 2061 return 1; 2062 } 2063 2064 if (m1 == m2 && b1 == b2 && bolVerticalSlope1 != 0 && bolVerticalSlope2 != 0) { 2065 switch (lOrient) { 2066 case 0: //Line1 is above the line 2067 if (m1 < 0) { 2068 dy = m1 * dWidth / Math.sqrt(1 + m1 * m1); //dy is negative 2069 dx = dy / m1; //dx is negative 2070 X.value[0] = p2.x + dx; 2071 Y.value[0] = p2.y + dy; 2072 } 2073 if (m1 > 0) //slope is positive 2074 { 2075 dy = -m1 * dWidth / Math.sqrt(1 + m1 * m1); //dy is negative 2076 dx = -dy / m1; //dx is positive 2077 X.value[0] = p2.x + dx; 2078 Y.value[0] = p2.y + dy; 2079 } 2080 break; 2081 case 3: //Line1 is below the line 2082 if (m1 <= 0) { 2083 dy = -m1 * dWidth / Math.sqrt(1 + m1 * m1); //dy is positive 2084 dx = dy / m1; //dx is positive 2085 X.value[0] = p2.x + dx; 2086 Y.value[0] = p2.y + dy; 2087 } else { 2088 dy = m1 * dWidth / Math.sqrt(1 + m1 * m1); //dy is positive 2089 dx = -dy / m1; //dx is negative 2090 X.value[0] = p2.x + dx; 2091 Y.value[0] = p2.y + dy; 2092 } 2093 break; 2094 default: 2095 X.value[0] = p2.x; 2096 Y.value[0] = p2.y; 2097 break; 2098 } 2099 return 1; 2100 }//end if 2101 2102 //a normal line. no vertical or identical slopes 2103 //if m1=m2 function will not reach this point 2104 X.value[0] = (b2 - b1) / (m1 - m2); //intersect the lines 2105 Y.value[0] = (m1 * (X.value[0]) + b1); 2106 return 1; 2107 }//end try 2108 catch (Exception exc) { 2109 X.value[0] = p2.x; 2110 Y.value[0] = p2.y; 2111 ErrorLogger.LogException(_className, "CalcTrueIntersectDouble", 2112 new RendererException("Failed inside ExtendTrueIntersectDouble", exc)); 2113 } 2114 return 1; 2115 } 2116 2117 /** 2118 * Returns the distance in pixels from x1,y1 to x2,y2 2119 * 2120 * @param x1 first point x location in pixels 2121 * @param y1 first point y location in pixels 2122 * @param x2 second point x location in pixels 2123 * @param y2 second point y location in pixels 2124 * 2125 * @return the distance 2126 */ 2127 protected static double CalcDistance2(long x1, 2128 long y1, 2129 long x2, 2130 long y2) { 2131 double dResult = 0; 2132 try { 2133 dResult = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); 2134 2135 //sanity check 2136 //return x or y distance if return value is 0 or infinity 2137 double xdist = Math.abs(x1 - x2); 2138 double ydist = Math.abs(y1 - y2); 2139 double max = xdist; 2140 if (ydist > xdist) { 2141 max = ydist; 2142 } 2143 if (dResult == 0 || Double.isInfinite(dResult)) { 2144 if (max > 0) { 2145 dResult = max; 2146 } 2147 } 2148 } catch (Exception exc) { 2149 ErrorLogger.LogException(_className, "CalcDistance2", 2150 new RendererException("Failed inside CalcDistance2", exc)); 2151 } 2152 return dResult; 2153 } 2154 /** 2155 * gets the middle line for Rev B air corridors AC, LLTR, MRR, UAV 2156 * Middle line is handled separately now because the line may have been segmented 2157 * @param pLinePoints 2158 * @return 2159 */ 2160 protected static POINT2[] GetSAAFRMiddleLine(POINT2[] pLinePoints) { 2161 POINT2[] pts = null; 2162 try { 2163 int j = 0, count = 0; 2164 for (j = 0; j < pLinePoints.length-1; j++) { 2165 if (pLinePoints[j].style > 0) { 2166 count++; 2167 } 2168 } 2169 pts = new POINT2[count*2]; 2170 count=0; 2171 double dMRR=0; 2172 POINT2 firstSegPt=null,lastSegPt=null,pt0=null,pt1=null; 2173 for (j = 0; j < pLinePoints.length; j++) { 2174 if(pLinePoints[j].style>=0 || j==pLinePoints.length-1) 2175 { 2176 if(lastSegPt != null) 2177 { 2178 firstSegPt=new POINT2(lastSegPt); 2179 lastSegPt=new POINT2(pLinePoints[j]); 2180 dMRR=firstSegPt.style; 2181 pt0 = ExtendLine2Double(lastSegPt, firstSegPt, -dMRR, 0); 2182 pt1 = ExtendLine2Double(firstSegPt, lastSegPt, -dMRR, 5); 2183 pts[count++]=pt0; 2184 pts[count++]=pt1; 2185 } 2186 else 2187 { 2188 lastSegPt=new POINT2(pLinePoints[j]); 2189 } 2190 } 2191 } 2192 } catch (Exception exc) { 2193 ErrorLogger.LogException(_className, "GetSAAFRMiddleLine", 2194 new RendererException("Failed inside GetSAAFRMiddleLine", exc)); 2195 } 2196 return pts; 2197 } 2198 /** 2199 * Computes the points for a SAAFR segment 2200 * 2201 * @param pLinePoints OUT - the client points also used for the returned 2202 * points 2203 * @param lineType the line type 2204 * @param dMRR the symbol width 2205 */ 2206 protected static void GetSAAFRSegment(POINT2[] pLinePoints, 2207 int lineType, 2208 double dMRR, 2209 int rev) { 2210 try { 2211 POINT2 pt0 = new POINT2(); 2212 POINT2 pt1 = new POINT2(); 2213 POINT2 pt2 = new POINT2(); 2214 POINT2 pt3 = new POINT2(); 2215 POINT2 pt4 = new POINT2(); 2216 POINT2 pt5 = new POINT2(); 2217 ref<double[]> m = new ref(); 2218 int bolVertical = CalcTrueSlopeDouble(pLinePoints[0], pLinePoints[1], m); 2219 //shortened line 2220 //pt1=ExtendLine2Double(pLinePoints[0],pLinePoints[1],-dMRR/2,5); 2221 //pt0=ExtendLine2Double(pLinePoints[1],pLinePoints[0],-dMRR/2,0); 2222 pt1 = ExtendLine2Double(pLinePoints[0], pLinePoints[1], -dMRR, 5); 2223 pt0 = ExtendLine2Double(pLinePoints[1], pLinePoints[0], -dMRR, 0); 2224 if (bolVertical != 0 && m.value[0] < 1) { 2225 //upper line 2226 pt2 = ExtendDirectedLine(pLinePoints[0], pLinePoints[1], pLinePoints[0], 2, dMRR); 2227 pt2.style = 0; 2228 pt3 = ExtendDirectedLine(pLinePoints[0], pLinePoints[1], pLinePoints[1], 2, dMRR); 2229 pt3.style = 5; 2230 //lower line 2231 pt4 = ExtendDirectedLine(pLinePoints[0], pLinePoints[1], pLinePoints[0], 3, dMRR); 2232 pt4.style = 0; 2233 pt5 = ExtendDirectedLine(pLinePoints[0], pLinePoints[1], pLinePoints[1], 3, dMRR); 2234 pt5.style = 5; 2235 } //if( (bolVertical!=0 && m>1) || bolVertical==0) 2236 else { 2237 //left line 2238 pt2 = ExtendDirectedLine(pLinePoints[0], pLinePoints[1], pLinePoints[0], 0, dMRR); 2239 pt2.style = 0; 2240 pt3 = ExtendDirectedLine(pLinePoints[0], pLinePoints[1], pLinePoints[1], 0, dMRR); 2241 pt3.style = 5; 2242 //right line 2243 pt4 = ExtendDirectedLine(pLinePoints[0], pLinePoints[1], pLinePoints[0], 1, dMRR); 2244 pt4.style = 0; 2245 pt5 = ExtendDirectedLine(pLinePoints[0], pLinePoints[1], pLinePoints[1], 1, dMRR); 2246 pt5.style = 5; 2247 } 2248 //load the line points 2249 pLinePoints[0] = new POINT2(pt0); 2250 pLinePoints[1] = new POINT2(pt1); 2251 pLinePoints[2] = new POINT2(pt2); 2252 pLinePoints[3] = new POINT2(pt3); 2253 pLinePoints[4] = new POINT2(pt4); 2254 pLinePoints[5] = new POINT2(pt5); 2255 pLinePoints[5].style = 5; 2256// if (lineType == TacticalLines.SAAFR) { 2257// pLinePoints[0].style = 5; 2258// } 2259// if (rev == RendererSettings.Symbology_2525C) { 2260// pLinePoints[0].style = 5; 2261// } 2262 pLinePoints[0].style = 5; 2263 } catch (Exception exc) { 2264 ErrorLogger.LogException(_className, "GetSAAFRSegment", 2265 new RendererException("Failed inside GetSAAFRSegment", exc)); 2266 } 2267 } 2268 /** 2269 * Called by arraysupport for SAAFR and AC fill shapes 2270 * @param pLinePoints 2271 * @param lineType 2272 * @param dMRR 2273 * @param rev 2274 */ 2275 protected static void GetSAAFRFillSegment(POINT2[] pLinePoints, 2276 double dMRR) { 2277 try { 2278 POINT2 pt2 = new POINT2(); 2279 POINT2 pt3 = new POINT2(); 2280 POINT2 pt4 = new POINT2(); 2281 POINT2 pt5 = new POINT2(); 2282 ref<double[]> m = new ref(); 2283 int bolVertical = CalcTrueSlopeDouble(pLinePoints[0], pLinePoints[1], m); 2284 if (bolVertical != 0 && m.value[0] < 1) { 2285 //upper line 2286 pt2 = ExtendDirectedLine(pLinePoints[0], pLinePoints[1], pLinePoints[0], 2, dMRR); 2287 pt3 = ExtendDirectedLine(pLinePoints[0], pLinePoints[1], pLinePoints[1], 2, dMRR); 2288 //lower line 2289 pt4 = ExtendDirectedLine(pLinePoints[0], pLinePoints[1], pLinePoints[0], 3, dMRR); 2290 pt5 = ExtendDirectedLine(pLinePoints[0], pLinePoints[1], pLinePoints[1], 3, dMRR); 2291 } //if( (bolVertical!=0 && m>1) || bolVertical==0) 2292 else { 2293 //left line 2294 pt2 = ExtendDirectedLine(pLinePoints[0], pLinePoints[1], pLinePoints[0], 0, dMRR); 2295 pt3 = ExtendDirectedLine(pLinePoints[0], pLinePoints[1], pLinePoints[1], 0, dMRR); 2296 //right line 2297 pt4 = ExtendDirectedLine(pLinePoints[0], pLinePoints[1], pLinePoints[0], 1, dMRR); 2298 pt5 = ExtendDirectedLine(pLinePoints[0], pLinePoints[1], pLinePoints[1], 1, dMRR); 2299 } 2300 //load the line points 2301 pLinePoints[0] = new POINT2(pt2); 2302 pLinePoints[1] = new POINT2(pt3); 2303 pLinePoints[2] = new POINT2(pt5); 2304 pLinePoints[3] = new POINT2(pt4); 2305 } catch (Exception exc) { 2306 ErrorLogger.LogException(_className, "GetSAAFRFillSegment", 2307 new RendererException("Failed inside GetSAAFRFillSegment", exc)); 2308 } 2309 //return; 2310 } 2311 /** 2312 * Computes an arc. 2313 * 2314 * @param pResultlinePoints OUT - contains center and start point and holds 2315 * the result arc points 2316 * @param vblCounter the number of client points 2317 * @param dRadius the arc radius in pixels 2318 * @param linetype the linetype determines start andgle and end angle for 2319 * the arc 2320 * 2321 */ 2322 protected static POINT2[] ArcArrayDouble(POINT2[] pResultLinePoints, 2323 int vblCounter, 2324 double dRadius, 2325 int linetype, 2326 IPointConversion converter) { 2327 try { 2328 //declarations 2329 double startangle = 0, //start of pArcLinePoints 2330 endangle = 0, //end of the pArcLinePoints 2331 increment = 0, 2332 //m = 0, 2333 length = 0, //length of a to e 2334 M = 0; 2335 2336 int j, numarcpts = 0, bolVertical = 0; 2337 ref<double[]> m = new ref(); 2338 //C is the center of the pArcLinePoints derived from a and e 2339 POINT2 C = new POINT2(pResultLinePoints[0]), 2340 a = new POINT2(pResultLinePoints[1]), 2341 e = new POINT2(pResultLinePoints[0]); 2342 2343 POINT2[] pArcLinePoints = null; 2344 //end declarations 2345 2346 bolVertical = CalcTrueSlopeDouble(a, e, m); 2347 if (bolVertical != 0) { 2348 M = Math.atan(m.value[0]); 2349 } else { 2350 if (a.y < e.y) { 2351 M = -Math.PI / 2; 2352 } else { 2353 M = Math.PI / 2; 2354 } 2355 } 2356 if(converter != null) 2357 { 2358 Point2D pt02d=new Point2D.Double(pResultLinePoints[0].x,pResultLinePoints[0].y); 2359 Point2D pt12d=new Point2D.Double(pResultLinePoints[1].x,pResultLinePoints[1].y); 2360 //boolean reverseM=false; 2361 pt02d=converter.PixelsToGeo(pt02d); 2362 pt12d=converter.PixelsToGeo(pt12d); 2363 //M=mdlGeodesic.GetAzimuth(pt02d,pt12d); 2364 M=mdlGeodesic.GetAzimuth(new POINT2(pt02d.getX(),pt02d.getY()),new POINT2(pt12d.getX(),pt12d.getY() ) ); 2365 M*=(Math.PI/180); 2366 if(M<0) 2367 M+=Math.PI; 2368 } 2369 length = CalcDistanceDouble(a, e); 2370 if(converter != null) 2371 { 2372 Point2D pt02d=new Point2D.Double(pResultLinePoints[0].x,pResultLinePoints[0].y); 2373 Point2D pt12d=new Point2D.Double(pResultLinePoints[1].x,pResultLinePoints[1].y); 2374 pt02d=converter.PixelsToGeo(pt02d); 2375 pt12d=converter.PixelsToGeo(pt12d); 2376 //length=mdlGeodesic.geodesic_distance(pt02d,pt12d,null,null); 2377 length=mdlGeodesic.geodesic_distance(new POINT2(pt02d.getX(),pt02d.getY()),new POINT2(pt12d.getX(),pt12d.getY()),null,null); 2378 } 2379 switch (linetype) { 2380 case TacticalLines.CLUSTER: 2381 startangle = M - 90 * Math.PI / 180.0; 2382 endangle = startangle + 2 * 90 * Math.PI / 180.0; 2383 break; 2384 case TacticalLines.TRIP: 2385 startangle = M - 45 * Math.PI / 180.0; 2386 endangle = startangle + 2 * 45 * Math.PI / 180.0; 2387 break; 2388 case TacticalLines.ISOLATE: 2389 case TacticalLines.CORDONKNOCK: 2390 case TacticalLines.CORDONSEARCH: 2391 startangle = M; 2392 endangle = startangle + 330 * Math.PI / 180; 2393 break; 2394 case TacticalLines.TURN: 2395 startangle = M; 2396 endangle = startangle + 90 * Math.PI / 180; 2397 break; 2398 case TacticalLines.OCCUPY: 2399 case TacticalLines.RETAIN: 2400 case TacticalLines.SECURE: 2401 startangle = M; 2402 //if(CELineArrayGlobals.Change1==false) 2403 endangle = startangle + 338 * Math.PI / 180; 2404 //else 2405 // endangle=startangle+330*pi/180; 2406 break; 2407 default: 2408 startangle = 0; 2409 endangle = 2 * Math.PI; 2410 break; 2411 } 2412 2413 if (a.x < e.x) { 2414 switch (linetype) { 2415 case TacticalLines.ISOLATE: 2416 case TacticalLines.CORDONKNOCK: 2417 case TacticalLines.CORDONSEARCH: 2418 startangle = M - Math.PI; 2419 endangle = startangle + 330 * Math.PI / 180; 2420 break; 2421 case TacticalLines.OCCUPY: 2422 case TacticalLines.RETAIN: 2423 case TacticalLines.SECURE: 2424 startangle = M - Math.PI; 2425 //if(CELineArrayGlobals.Change1==false) 2426 endangle = startangle + 338 * Math.PI / 180; 2427 //else 2428 // endangle=startangle+330*pi/180; 2429 break; 2430 case TacticalLines.TURN: 2431 startangle = M - Math.PI; 2432 endangle = startangle + 90 * Math.PI / 180; 2433 break; 2434 case TacticalLines.CLUSTER: 2435 startangle = M - Math.PI + 90 * Math.PI / 180.0; 2436 endangle = startangle - 2 * 90 * Math.PI / 180.0; 2437 break; 2438 case TacticalLines.TRIP: 2439 startangle = M - Math.PI + 45 * Math.PI / 180.0; 2440 endangle = startangle - 2 * 45 * Math.PI / 180.0; 2441 break; 2442 default: 2443 break; 2444 } 2445 } 2446 2447 numarcpts = 26; 2448 pArcLinePoints = new POINT2[numarcpts]; 2449 InitializePOINT2Array(pArcLinePoints); 2450 increment = (endangle - startangle) / (numarcpts - 1); 2451 if(dRadius != 0 && length != 0) 2452 { 2453 C.x = (int) ((double) e.x - (dRadius / length) 2454 * ((double) a.x - (double) e.x)); 2455 C.y = (int) ((double) e.y - (dRadius / length) 2456 * ((double) a.y - (double) e.y)); 2457 } 2458 else 2459 { 2460 C.x=e.x; 2461 C.y=e.y; 2462 } 2463 if (converter != null) 2464 { 2465 Point2D C2d=new Point2D.Double(pResultLinePoints[0].x,pResultLinePoints[0].y); 2466 C2d=converter.PixelsToGeo(C2d); 2467 double az=0; 2468 Point2D ptGeo2d=null; 2469 POINT2 ptGeo=null; 2470 POINT2 ptPixels=null; 2471 for (j = 0; j < numarcpts; j++) { 2472 az=startangle*180/Math.PI+j*increment*180/Math.PI; 2473 //ptGeo=mdlGeodesic.geodesic_coordinate(C2d,length,az); 2474 ptGeo=mdlGeodesic.geodesic_coordinate(new POINT2(C2d.getX(),C2d.getY()),length,az); 2475 ptGeo2d=new Point2D.Double(ptGeo.x,ptGeo.y); 2476 ptGeo2d=converter.GeoToPixels(ptGeo2d); 2477 ptPixels=new POINT2(ptGeo2d.getX(),ptGeo2d.getY()); 2478 pArcLinePoints[j].x = ptPixels.x; 2479 pArcLinePoints[j].y = ptPixels.y; 2480 } 2481 } 2482 else 2483 { 2484 for (j = 0; j < numarcpts; j++) { 2485 //pArcLinePoints[j]=pResultLinePoints[0]; //initialize 2486 pArcLinePoints[j].x = (int) (dRadius * Math.cos(startangle + j * increment)); 2487 pArcLinePoints[j].y = (int) (dRadius * Math.sin(startangle + j * increment)); 2488 } 2489 2490 for (j = 0; j < numarcpts; j++) { 2491 pArcLinePoints[j].x += C.x; 2492 pArcLinePoints[j].y += C.y; 2493 } 2494 } 2495 switch (linetype) { 2496 case TacticalLines.ISOLATE: 2497 case TacticalLines.CORDONKNOCK: 2498 case TacticalLines.CORDONSEARCH: 2499 case TacticalLines.OCCUPY: 2500 case TacticalLines.RETAIN: 2501 case TacticalLines.SECURE: 2502 case TacticalLines.CLUSTER: 2503 case TacticalLines.TURN: 2504 case TacticalLines.TRIP: 2505 for (j = 0; j < numarcpts; j++) { 2506 pResultLinePoints[j] = new POINT2(pArcLinePoints[j]); 2507 } 2508 break; 2509 default: 2510 for (j = 0; j < numarcpts; j++) { 2511 pResultLinePoints[j] = new POINT2(pArcLinePoints[j]); 2512 } 2513 break; 2514 } 2515 pArcLinePoints = null; 2516 } catch (Exception exc) { 2517 ErrorLogger.LogException(_className, "ArcArrayDouble", 2518 new RendererException("Failed inside ArcArrayDouble", exc)); 2519 } 2520 return pResultLinePoints; 2521 } 2522 /** 2523 * Gets geodesic circle using the converter 2524 * @param Center in pixels 2525 * @param pt1 a point on the radius in pixels 2526 * @param numpts number of points to return 2527 * @param CirclePoints the result points 2528 * @param converter 2529 */ 2530 protected static void CalcCircleDouble2(POINT2 Center, 2531 POINT2 pt1, 2532 int numpts, 2533 POINT2[] CirclePoints, 2534 IPointConversion converter) { 2535 try { 2536 int j = 0; 2537 double increment = (Math.PI * 2) / (numpts - 1); 2538 Point2D ptCenter2d=new Point2D.Double(Center.x,Center.y); 2539 ptCenter2d=converter.PixelsToGeo(ptCenter2d); 2540 Point2D pt12d=new Point2D.Double(pt1.x,pt1.y); 2541 pt12d=converter.PixelsToGeo(pt12d); 2542 Center=new POINT2(ptCenter2d.getX(),ptCenter2d.getY()); 2543 pt1=new POINT2(pt12d.getX(),pt12d.getY()); 2544 double dist=mdlGeodesic.geodesic_distance(Center, pt1, null, null); 2545 2546 //double dSegmentAngle = 2 * Math.PI / numpts; 2547 double az=0; 2548 double startangle=0,endAngle=Math.PI*2; 2549 POINT2 ptGeo=null,ptPixels=null; 2550 Point2D ptGeo2d=null; 2551 for (j = 0; j < numpts - 1; j++) { 2552 az=startangle*180/Math.PI+j*increment*180/Math.PI; 2553 //ptGeo=mdlGeodesic.geodesic_coordinate(C2d,length,az); 2554 ptGeo=mdlGeodesic.geodesic_coordinate(Center,dist,az); 2555 ptGeo2d=new Point2D.Double(ptGeo.x,ptGeo.y); 2556 ptGeo2d=converter.GeoToPixels(ptGeo2d); 2557 ptPixels=new POINT2(ptGeo2d.getX(),ptGeo2d.getY()); 2558 CirclePoints[j].x = ptPixels.x; 2559 CirclePoints[j].y = ptPixels.y; 2560 } 2561 CirclePoints[numpts - 1] = new POINT2(CirclePoints[0]); 2562 2563 } catch (Exception exc) { 2564 ErrorLogger.LogException(_className, "CalcCircleDouble2", 2565 new RendererException("Failed inside CalcCircleDouble2", exc)); 2566 } 2567 return; 2568 } 2569 /** 2570 * Computes the points for a circle. Assumes CirclePoints has been allocated 2571 * with size numpts. 2572 * 2573 * @param Center the cicle center 2574 * @param radius the circle radius in pixels 2575 * @param numpts the number of circle points 2576 * @param CirclePoints - OUT - array of circle points 2577 * @param styl the style to set the last circle point 2578 */ 2579 protected static void CalcCircleDouble(POINT2 Center, 2580 double radius, 2581 int numpts, 2582 POINT2[] CirclePoints, 2583 int styl) { 2584 try { 2585 int j = 0; 2586 double dSegmentAngle = 2 * Math.PI / numpts; 2587 double x = 0, y = 0; 2588 for (j = 0; j < numpts - 1; j++) { 2589 x = Center.x + (radius * Math.cos((double) j * dSegmentAngle)); 2590 y = Center.y + (radius * Math.sin((double) j * dSegmentAngle)); 2591 CirclePoints[j] = new POINT2(x, y); 2592 CirclePoints[j].style = styl; 2593 } 2594 CirclePoints[numpts - 1] = new POINT2(CirclePoints[0]); 2595 2596 switch (styl) { 2597 case 0: 2598 CirclePoints[numpts - 1].style = 0; 2599 break; 2600 case 9: 2601 CirclePoints[numpts - 1].style = 10; 2602 break; 2603 case 11: 2604 CirclePoints[numpts - 1].style = 12; 2605 break; 2606 default: 2607 CirclePoints[numpts - 1].style = 5; 2608 break; 2609 } 2610 } catch (Exception exc) { 2611 ErrorLogger.LogException(_className, "CalcCircleDouble", 2612 new RendererException("Failed inside CalcCircleDouble", exc)); 2613 } 2614 } 2615 2616 protected static Shape2 CalcCircleShape(POINT2 Center, 2617 double radius, 2618 int numpts, 2619 POINT2[] CirclePoints, 2620 int styl) { 2621 Shape2 shape; 2622 if (styl == 9) { 2623 shape = new Shape2(Shape2.SHAPE_TYPE_FILL); 2624 } else { 2625 shape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE); 2626 } 2627 2628 shape.set_Style(styl); 2629 try { 2630 int j = 0; 2631 CalcCircleDouble(Center, radius, numpts, CirclePoints, styl); 2632 shape.moveTo(CirclePoints[0]); 2633 for (j = 1; j < numpts; j++) { 2634 shape.lineTo(CirclePoints[j]); 2635 } 2636 } catch (Exception exc) { 2637 ErrorLogger.LogException(_className, "CalcCircleShape", 2638 new RendererException("Failed inside CalcCircleShape", exc)); 2639 } 2640 return shape; 2641 } 2642 2643 private static void GetSquallCurve(POINT2 StartPt, 2644 POINT2 EndPt, 2645 POINT2[] pSquallPts, 2646 int sign, 2647 int amplitude, 2648 int quantity) { 2649 try { 2650 double dist = CalcDistanceDouble(StartPt, EndPt); 2651 POINT2 ptTemp = new POINT2(); 2652 int j = 0; 2653 //end declarations 2654 2655 //get points along the horizontal segment between StartPt and EndPt2; 2656 for (j = 0; j < quantity; j++) { 2657 ptTemp = ExtendLineDouble(EndPt, StartPt, -dist * (double) j / (double) quantity); 2658 pSquallPts[j].x = ptTemp.x; 2659 //calculate the sin value along the x axis 2660 pSquallPts[j].y = ptTemp.y + amplitude * sign * Math.sin((double) j * 180 / (double) quantity * Math.PI / 180); 2661 } 2662 } catch (Exception exc) { 2663 ErrorLogger.LogException(_className, "GetSquallShape", 2664 new RendererException("Failed inside GeSquallShape", exc)); 2665 } 2666 } 2667 //caller needs to instantiate sign.value 2668 /** 2669 * Gets the squall curves for a line segment Assumes pSquallPts has been 2670 * allocated the proper number of points. 2671 * 2672 * @param StartPt segment start point 2673 * @param EndPt segment end point 2674 * @param pSquallPts OUT - the squall points 2675 * @param sign OUT - an object with a member to hold the starting curve sign 2676 * for the segment. 2677 * @param amplitude the sin curve amplitutde 2678 * @param quantity the number of points for each sin curve 2679 * @param length the desired length of the curve along the segment for each 2680 * sin curve 2681 * 2682 * @return segment squall points count 2683 */ 2684 protected static int GetSquallSegment(POINT2 StartPt, 2685 POINT2 EndPt, 2686 POINT2[] pSquallPts, 2687 ref<int[]> sign, 2688 int amplitude, 2689 int quantity, 2690 int length) { 2691 int counter = 0; 2692 try { 2693 POINT2 StartCurvePt, EndCurvePt; //use these for the curve points 2694 POINT2[] pSquallPts2 = new POINT2[quantity]; 2695 double dist = CalcDistanceDouble(StartPt, EndPt); 2696 int numCurves = (int) (dist / (double) length); 2697 int j = 0, k = 0; 2698 POINT2 EndPt2 = new POINT2(); 2699 double angle = Math.atan((StartPt.y - EndPt.y) / (StartPt.x - EndPt.x)); 2700 int lAngle = (int) ((180 / Math.PI) * angle); 2701 InitializePOINT2Array(pSquallPts2); 2702 //define EndPt2 to be the point dist from StartPt along the x axis 2703 if (StartPt.x < EndPt.x) { 2704 EndPt2.x = StartPt.x + dist; 2705 } else { 2706 EndPt2.x = StartPt.x - dist; 2707 } 2708 2709 EndPt2.y = StartPt.y; 2710 2711 EndCurvePt = StartPt; 2712 for (j = 0; j < numCurves; j++) { 2713 StartCurvePt = ExtendLineDouble(EndPt2, StartPt, -(double) (j * length)); 2714 EndCurvePt = ExtendLineDouble(EndPt2, StartPt, -(double) ((j + 1) * length)); 2715 2716 //get the curve points 2717 GetSquallCurve(StartCurvePt, EndCurvePt, pSquallPts2, sign.value[0], amplitude, quantity); 2718 2719 //fill the segment points with the curve points 2720 for (k = 0; k < quantity; k++) { 2721 //pSquallPts[counter].x=pSquallPts2[k].x; 2722 //pSquallPts[counter].y=pSquallPts2[k].y; 2723 pSquallPts[counter] = new POINT2(pSquallPts2[k]); 2724 counter++; 2725 } 2726 //reverse the sign 2727 2728 sign.value[0] = -sign.value[0]; 2729 } 2730 if (numCurves == 0) { 2731 pSquallPts[counter] = new POINT2(StartPt); 2732 counter++; 2733 pSquallPts[counter] = new POINT2(EndPt); 2734 counter++; 2735 } 2736 //the points are along the x axis. Rotate them about the first point as the origin 2737 RotateGeometryDoubleOrigin(pSquallPts, counter, lAngle); 2738 pSquallPts2 = null; 2739 } catch (Exception exc) { 2740 ErrorLogger.LogException(_className, "GetSquallSegment", 2741 new RendererException("Failed inside GetSquallSegment", exc)); 2742 } 2743 return counter; 2744 } 2745 2746 //temporarily using 2000 pixels 2747 private static int PointInBounds(POINT2 pt) { 2748 try { 2749 //double maxPixels=CELineArrayGlobals.MaxPixels2; 2750 double maxPixels = 100000;//was 2000 2751 if (Math.abs(pt.x) <= maxPixels && Math.abs(pt.y) <= maxPixels) { 2752 return 1; 2753 } else { 2754 return 0; 2755 } 2756 } catch (Exception exc) { 2757 ErrorLogger.LogException(_className, "PointInBounds", 2758 new RendererException("Failed inside PointInBounds", exc)); 2759 } 2760 return 1; 2761 } 2762 2763 /** 2764 * @param pt 2765 * @param ul 2766 * @param lr 2767 * @return 2768 */ 2769 private static int PointInBounds2(POINT2 pt, POINT2 ul, POINT2 lr) { 2770 try { 2771 double maxX = lr.x, minX = ul.x, maxY = lr.y, minY = ul.y; 2772 if (pt.x <= maxX && pt.x >= minX && pt.y <= maxY && pt.y >= minY) { 2773 return 1; 2774 } else { 2775 return 0; 2776 } 2777 } catch (Exception exc) { 2778 ErrorLogger.LogException(_className, "PointInBounds2", 2779 new RendererException("Failed inside PointInBounds2", exc)); 2780 } 2781 return 1; 2782 } 2783 2784 /** 2785 * Analyzes if line from pt0 to pt 1 intersects a side and returns the 2786 * intersection or null assumes pt0 to pt1 is not vertical. the caller will 2787 * replace pt0 with the intersection point if it is not null 2788 * 2789 * @param pt0 2790 * @param pt1 2791 * @param sidePt0 vertical or horizontal side first point 2792 * @param sidePt1 2793 * @return null if it does not intersect the side 2794 */ 2795 private static POINT2 intersectSegment(POINT2 pt0, POINT2 pt1, POINT2 sidePt0, POINT2 sidePt1) { 2796 POINT2 pt = null; 2797 try { 2798 if (pt0.x == pt1.x) { 2799 return null; 2800 } 2801 double m = (pt1.y - pt0.y) / (pt1.x - pt0.x); 2802 double dx = 0, dy = 0, x = 0, y = 0; 2803 POINT2 upper = null, lower = null, left = null, right = null; 2804 Boolean bolVertical = false; 2805 //the side is either vertical or horizontal 2806 if (sidePt0.x == sidePt1.x) //vertical side 2807 { 2808 bolVertical = true; 2809 if (sidePt0.y < sidePt1.y) { 2810 upper = sidePt0; 2811 lower = sidePt1; 2812 } else { 2813 upper = sidePt1; 2814 lower = sidePt0; 2815 } 2816 } else //horizontal side 2817 { 2818 if (sidePt0.x < sidePt1.x) { 2819 left = sidePt0; 2820 right = sidePt1; 2821 } else { 2822 left = sidePt1; 2823 right = sidePt0; 2824 } 2825 } 2826 //travel in the direction from pt0 to pt1 to find the pt0 intersect 2827 if (bolVertical) { //the side to intersect is vertical 2828 dx = upper.x - pt0.x; 2829 dy = m * dx; 2830 x = upper.x; 2831 y = pt0.y + dy; 2832 //the potential intersection point 2833 pt = new POINT2(x, y); 2834 2835 if (pt0.x <= pt.x && pt.x <= pt1.x) //left to right 2836 { 2837 if (upper.y <= pt.y && pt.y <= lower.y) { 2838 return pt; 2839 } 2840 } else if (pt0.x >= pt.x && pt.x >= pt1.x) //right to left 2841 { 2842 if (upper.y <= pt.y && pt.y <= lower.y) { 2843 return pt; 2844 } 2845 } 2846 } else //horizontal side 2847 { 2848 dy = left.y - pt0.y; 2849 dx = dy / m; 2850 x = pt0.x + dx; 2851 y = left.y; 2852 //the potential intersection point 2853 pt = new POINT2(x, y); 2854 2855 if (pt0.y <= pt.y && pt.y <= pt1.y) { 2856 if (left.x <= pt.x && pt.x <= right.x) { 2857 return pt; 2858 } 2859 } else if (pt0.y >= pt.y && pt.y >= pt1.y) { 2860 if (left.x <= pt.x && pt.x <= right.x) { 2861 return pt; 2862 } 2863 } 2864 } 2865 } catch (Exception exc) { 2866 ErrorLogger.LogException(_className, "intersectSegment", 2867 new RendererException("Failed inside intersectSegment", exc)); 2868 } 2869 return null; 2870 } 2871 2872 /** 2873 * side 1 ----- | | side 0 | | side 2 | | ------ side 3 bounds one segment 2874 * for autoshapes that need it: bydif, fordif, fix, mnfldfix if null is 2875 * returned the client should conect the original line points (i.e. no 2876 * jaggies) 2877 * 2878 * @param pt0 2879 * @param pt1 2880 * @param ul 2881 * @param lr 2882 * @return bounded segment or null 2883 */ 2884 public static POINT2[] BoundOneSegment(POINT2 pt0, POINT2 pt1, POINT2 ul, POINT2 lr) { 2885 POINT2[] line = new POINT2[2]; 2886 try { 2887 if (pt0.y < ul.y && pt1.y < ul.y) { 2888 return null; 2889 } 2890 if (pt0.y > lr.y && pt1.y > lr.y) { 2891 return null; 2892 } 2893 if (pt0.x < ul.x && pt1.x < ul.x) { 2894 return null; 2895 } 2896 if (pt0.x > lr.x && pt1.x > lr.x) { 2897 return null; 2898 } 2899 2900 Boolean bolVertical = false; 2901 InitializePOINT2Array(line); 2902 if (pt0.x == pt1.x) { 2903 bolVertical = true; 2904 } 2905 2906 if (bolVertical) { 2907 line[0] = new POINT2(pt0); 2908 if (line[0].y < ul.y) { 2909 line[0].y = ul.y; 2910 } 2911 if (line[0].y > lr.y) { 2912 line[0].y = lr.y; 2913 } 2914 2915 line[1] = new POINT2(pt1); 2916 if (line[1].y < ul.y) { 2917 line[1].y = ul.y; 2918 } 2919 if (line[1].y > lr.y) { 2920 line[1].y = lr.y; 2921 } 2922 2923 return line; 2924 } 2925 2926 double dx = 0, dy = 0, x = 0, y = 0; 2927 double m = (pt1.y - pt0.y) / (pt1.x - pt0.x); 2928 Boolean side0Intersect = false, 2929 side1Intersect = false, 2930 side2Intersect = false, 2931 side3Intersect = false; 2932 //travel in the direction from pt0 to pt1 to find pt0 intersect 2933 POINT2 ur = new POINT2(lr.x, ul.y); 2934 POINT2 ll = new POINT2(ul.x, lr.y); 2935 2936 POINT2 pt0Intersect = null; 2937 if (PointInBounds2(pt0, ul, lr) == 1) { 2938 pt0Intersect = pt0; 2939 } 2940 if (pt0Intersect == null) { 2941 pt0Intersect = intersectSegment(pt0, pt1, ll, ul); //interesect side 0 2942 side0Intersect = true; 2943 } 2944 if (pt0Intersect == null) { 2945 pt0Intersect = intersectSegment(pt0, pt1, ul, ur); //interesect side 1 2946 side1Intersect = true; 2947 } 2948 if (pt0Intersect == null) { 2949 pt0Intersect = intersectSegment(pt0, pt1, ur, lr); //interesect side 2 2950 side2Intersect = true; 2951 } 2952 if (pt0Intersect == null) { 2953 pt0Intersect = intersectSegment(pt0, pt1, ll, lr); //interesect side 3 2954 side3Intersect = true; 2955 } 2956 2957 //travel in the direction from pt1 to pt0 to find pt1 intersect 2958 POINT2 pt1Intersect = null; 2959 if (PointInBounds2(pt1, ul, lr) == 1) { 2960 pt1Intersect = pt1; 2961 } 2962 if (pt1Intersect == null && side0Intersect == false) { 2963 pt1Intersect = intersectSegment(pt1, pt0, ll, ul); //interesect side 0 2964 } 2965 if (pt1Intersect == null && side1Intersect == false) { 2966 pt1Intersect = intersectSegment(pt1, pt0, ul, ur); //interesect side 1 2967 } 2968 if (pt1Intersect == null && side2Intersect == false) { 2969 pt1Intersect = intersectSegment(pt1, pt0, ur, lr); //interesect side 2 2970 } 2971 if (pt1Intersect == null && side3Intersect == false) { 2972 pt1Intersect = intersectSegment(pt1, pt0, ll, lr); //interesect side 3 2973 } 2974 2975 if (pt0Intersect != null && pt1Intersect != null) { 2976 line[0] = pt0Intersect; 2977 line[1] = pt1Intersect; 2978 //return line; 2979 } else { 2980 line = null; 2981 } 2982 } catch (Exception exc) { 2983 ErrorLogger.LogException(_className, "BoundOneSegment", 2984 new RendererException("Failed inside BoundOneSegment", exc)); 2985 } 2986 return line; 2987 } 2988 2989 private static int DisplayIntersectPixels(POINT2 pt0, 2990 POINT2 pt1, 2991 ref<double[]> pt2x, 2992 ref<double[]> pt2y, 2993 ref<double[]> pt3x, 2994 ref<double[]> pt3y) //POINT2 ul, 2995 //POINT2 lr) 2996 { 2997 int nResult = -1; 2998 try { 2999 //declarations 3000 double X = 0, Y = 0; 3001 ref<double[]> m = new ref(); 3002 //double maxPixels=CELineArrayGlobals.MaxPixels2; 3003 double maxPixels = 2000; 3004 //double maxX=lr.x,minX=ul.x,maxY=lr.y,minY=ul.y; 3005 3006 int bol0Inside = 0, bol1Inside = 0; 3007 int bolVertical = CalcTrueSlopeDouble(pt0, pt1, m); 3008 double b = pt0.y - m.value[0] * pt0.x; //the y intercept for the segment line 3009 POINT2 pt2, pt3; 3010 //end declarations 3011 3012 pt2x.value = new double[1]; 3013 pt2y.value = new double[1]; 3014 pt3x.value = new double[1]; 3015 pt3y.value = new double[1]; 3016 pt2 = new POINT2(pt0); 3017 pt3 = new POINT2(pt1); 3018 3019 //diagnostic 3020 if (pt0.x <= maxPixels && pt0.x >= -maxPixels 3021 && pt0.y <= maxPixels && pt0.y >= -maxPixels) { 3022 bol0Inside = 1; 3023 } 3024 if (pt1.x <= maxPixels && pt1.x >= -maxPixels 3025 && pt1.y <= maxPixels && pt1.y >= -maxPixels) { 3026 bol1Inside = 1; 3027 } 3028 //if both points are inside the area then use the whole segment 3029 if (bol0Inside == 1 && bol1Inside == 1) { 3030 return 0; 3031 } 3032 //if at leat one of the points is inside the area then use some of the segment 3033 if (bol0Inside == 1 || bol1Inside == 1) { 3034 nResult = 1; 3035 } 3036 3037 //segment is not vertical 3038 if (bolVertical != 0) { 3039 //analysis for side 0, get the intersection for either point if it exists 3040 //diagnostic 3041 X = -maxPixels; 3042 //X=minX; 3043 3044 Y = m.value[0] * X + b; 3045 if (pt0.x < -maxPixels && -maxPixels < pt1.x) //pt0 is outside the area 3046 { 3047 if (-maxPixels <= Y && Y <= maxPixels) //intersection is on side 0 3048 //if(minY<=Y && Y<=maxY) //intersection is on side 0 3049 { 3050 pt2.x = X; 3051 pt2.y = Y; 3052 nResult = 1; //use at least some of the pixels 3053 } 3054 } 3055 if (pt1.x < -maxPixels && -maxPixels < pt0.x) //pt1 is outside the area 3056 //if(pt1.x<minX && minX<pt0.x) //pt1 is outside the area 3057 { 3058 if (-maxPixels <= Y && Y <= maxPixels) //intersection is on side 0 3059 { 3060 pt3.x = X; 3061 pt3.y = Y; 3062 nResult = 1; //use at least some of the pixels 3063 } 3064 } 3065 3066 //analysis for side 1, get the intersection for either point if it exists 3067 Y = -maxPixels; 3068 if (m.value[0] != 0) { 3069 X = (Y - b) / m.value[0]; 3070 if (pt0.y < -maxPixels && -maxPixels < pt1.y) //pt0 is outside the area 3071 { 3072 if (-maxPixels <= X && X <= maxPixels) //intersection is on side 1 3073 { 3074 pt2.x = X; 3075 pt2.y = Y; 3076 nResult = 1; //use at least some of the pixels 3077 } 3078 } 3079 if (pt1.y <= -maxPixels && -maxPixels <= pt0.y) //pt1 is outside the area 3080 { 3081 if (-maxPixels < X && X < maxPixels) //intersection is on the boundary 3082 { 3083 pt3.x = X; 3084 pt3.y = Y; 3085 nResult = 1; //use at least some of the pixels 3086 } 3087 } 3088 } 3089 //analysis for side 2, get the intersection for either point if it exists 3090 X = maxPixels; 3091 Y = m.value[0] * X + b; 3092 if (pt0.x < maxPixels && maxPixels < pt1.x) //pt1 is outside the area 3093 { 3094 if (-maxPixels <= Y && Y <= maxPixels) //intersection is on the boundary 3095 { 3096 pt3.x = X; 3097 pt3.y = Y; 3098 nResult = 1; //use at least some of the pixels 3099 } 3100 } 3101 if (pt1.x < maxPixels && maxPixels < pt0.x) //pt0 is outside the area 3102 { 3103 if (-maxPixels <= Y && Y <= maxPixels) //intersection is on the boundary 3104 { 3105 pt2.x = X; 3106 pt2.y = Y; 3107 nResult = 1; //use at least some of the pixels 3108 } 3109 } 3110 3111 //analysis for side 3, get the intersection for either point if it exists 3112 Y = maxPixels; 3113 if (m.value[0] != 0) { 3114 X = (Y - b) / m.value[0]; 3115 if (pt0.y < maxPixels && maxPixels < pt1.y) //pt1 is outside the area 3116 { 3117 if (-maxPixels <= X && X <= maxPixels) //intersection is on the boundary 3118 { 3119 pt3.x = X; 3120 pt3.y = Y; 3121 nResult = 1; //use at least some of the pixels 3122 } 3123 } 3124 if (pt1.y < maxPixels && maxPixels < pt0.y) //pt0 is outside the area 3125 { 3126 if (-maxPixels <= X && X <= maxPixels) //intersection is on the boundary 3127 { 3128 pt2.x = X; 3129 pt2.y = Y; 3130 nResult = 1; //use at least some of the pixels 3131 } 3132 } 3133 } 3134 } 3135 3136 //segment is vertical 3137 if (bolVertical == 0) { 3138 //analysis for side 1 3139 X = pt0.x; 3140 Y = -maxPixels; 3141 if (-maxPixels < pt0.x && pt0.x < maxPixels) { 3142 if (pt0.y <= -maxPixels && -maxPixels <= pt1.y) //pt0 outside the area 3143 { 3144 pt2.x = X; 3145 pt2.y = Y; 3146 nResult = 1; //use at least some of the pixels 3147 } 3148 if (pt1.y <= -maxPixels && -maxPixels <= pt0.y) //pt1 outside the area 3149 { 3150 pt3.x = X; 3151 pt3.y = Y; 3152 nResult = 1; //use at least some of the pixels 3153 } 3154 } 3155 3156 //analysis for side 3 3157 X = pt0.x; 3158 Y = maxPixels; 3159 if (-maxPixels < pt0.x && pt0.x < maxPixels) { 3160 if (pt0.y <= maxPixels && maxPixels <= pt1.y) //pt1 outside the area 3161 { 3162 pt3.x = X; 3163 pt3.y = Y; 3164 nResult = 1; //use at least some of the pixels 3165 } 3166 if (pt1.y <= maxPixels && maxPixels <= pt0.y) //pt0 outside the area 3167 { 3168 pt2.x = X; 3169 pt2.y = Y; 3170 nResult = 1; //use at least some of the pixels 3171 } 3172 } 3173 } 3174 3175 pt2x.value[0] = pt2.x; 3176 pt2y.value[0] = pt2.y; 3177 pt3x.value[0] = pt3.x; 3178 pt3y.value[0] = pt3.y; 3179 } catch (Exception exc) { 3180 ErrorLogger.LogException(_className, "DisplayIntersectPixels", 3181 new RendererException("Failed inside DisplayIntersectPixels", exc)); 3182 } 3183 return nResult; 3184 } 3185 /** 3186 * Computes Ditch spikes for the ATDITCH line types. This function uses 3187 * linestyles provided by the caller to skip segments. 3188 * 3189 * @param pLinePoints OUT - the client points also used for the return 3190 * points 3191 * @param nOldCounter the number of client points 3192 * @param bWayIs the parallel line to use (0) for inner or outer spikes 3193 * @param linetype the line type 3194 * 3195 * @return the symbol point count 3196 */ 3197 protected static int GetDitchSpikeDouble(POINT2[] pLinePoints, 3198 int nOldCounter, 3199 int bWayIs, 3200 int linetype) { 3201 int nSpikeCounter = 0; 3202 try { 3203 //declarations 3204 int nNumberOfSegments = 0, 3205 lCircleCounter = 0, 3206 bolVertical = 0, 3207 nTemp = 0, 3208 i, 3209 j; 3210 double dPrinter = 1.0; 3211 double dIntLocation1x = 0, 3212 dIntLocation2x = 0, 3213 dIntLocation1y = 0, 3214 dIntLocation2y = 0, 3215 r = 0, 3216 s = 0, 3217 use = 0, 3218 length = 0, 3219 k = 0, 3220 bint = 0; 3221 ref<double[]> pdAnswer = new ref();//new double[6]; 3222 ref<double[]> m = new ref(); 3223 3224 POINT2 UpperLinePoint = new POINT2(pLinePoints[0]), 3225 Lower1LinePoint = new POINT2(pLinePoints[0]), 3226 Lower2LinePoint = new POINT2(pLinePoints[0]), 3227 a = new POINT2(pLinePoints[0]), 3228 b = new POINT2(pLinePoints[0]); 3229 POINT2[] pCirclePoints = new POINT2[pLinePoints.length]; 3230 POINT2 averagePoint = new POINT2(); 3231 POINT2 lastAveragePoint = new POINT2(); 3232 POINT2[] pTempLinePoints = null; 3233 double minLength = 24; 3234 //end declarations 3235 3236 pTempLinePoints = new POINT2[nOldCounter]; 3237 for (j = 0; j < nOldCounter; j++) { 3238 pTempLinePoints[j] = new POINT2(pLinePoints[j]); 3239 } 3240 3241 ArrayList<POINT2> basePoints = new ArrayList(); 3242 3243 InitializePOINT2Array(pCirclePoints); 3244 nSpikeCounter = nOldCounter; 3245 for (i = 0; i < nOldCounter - 1; i++) { 3246 if (linetype == TacticalLines.ATDITCHM && i == 0) { 3247 minLength = 38; 3248 } 3249 3250 nTemp = CalcTrueLinesDouble(15 * (int) dPrinter, pLinePoints[i], pLinePoints[i + 1], pdAnswer); 3251 r = pdAnswer.value[3]; 3252 s = pdAnswer.value[5]; 3253 length = CalcDistanceDouble(pLinePoints[i], pLinePoints[i + 1]); 3254 bolVertical = CalcTrueSlopeDouble(pLinePoints[i], pLinePoints[i + 1], m); 3255 nNumberOfSegments = (int) ((length - 1) / (12 * dPrinter)); 3256 3257 if (length > minLength * dPrinter) { //minLength was 24 3258 if (bWayIs != 0) { 3259 if (pLinePoints[i].x <= pLinePoints[i + 1].x) { 3260 use = r; 3261 } 3262 if (pLinePoints[i].x >= pLinePoints[i + 1].x) { 3263 use = s; 3264 } 3265 } //end if 3266 else { 3267 if (pLinePoints[i].x <= pLinePoints[i + 1].x) { 3268 use = s; 3269 } 3270 if (pLinePoints[i].x >= pLinePoints[i + 1].x) { 3271 use = r; 3272 } 3273 } //end else 3274 3275 for (j = 1; j <= nNumberOfSegments; j++) { 3276 k = (double) j; 3277 a = new POINT2(pLinePoints[i]); 3278 b = new POINT2(pLinePoints[i + 1]); 3279 3280 if (j > 1) { 3281 dIntLocation1x = dIntLocation2x; 3282 } else { 3283 dIntLocation1x 3284 = (double) pLinePoints[i].x + ((k * 12.0 - 12) * dPrinter / length) 3285 * (double) (pLinePoints[i + 1].x - pLinePoints[i].x); 3286 } 3287 3288 if (j > 1) //added M. Deutch 2-23-99 3289 { 3290 dIntLocation1y = dIntLocation2y; 3291 } else { 3292 dIntLocation1y 3293 = (double) pLinePoints[i].y + ((k * 12.0 - 6.0) * dPrinter / length) 3294 * (double) (pLinePoints[i + 1].y - pLinePoints[i].y); 3295 } 3296 3297 dIntLocation2x = (double) pLinePoints[i].x 3298 + ((k * 12.0 + 6.0) * dPrinter / length) 3299 * (double) (pLinePoints[i + 1].x 3300 - pLinePoints[i].x); 3301 3302 dIntLocation2y = (double) pLinePoints[i].y 3303 + ((k * 12.0 + 6.0) * dPrinter / length) 3304 * (double) (pLinePoints[i + 1].y 3305 - pLinePoints[i].y); 3306 3307 if (m.value[0] != 0 && bolVertical != 0) { 3308 bint = (dIntLocation1y + dIntLocation2y) / 2.0 3309 + (1 / m.value[0]) * (dIntLocation1x + dIntLocation2x) / 2.0; 3310 //independent of direction 3311 UpperLinePoint = CalcTrueIntersectDouble2(m.value[0], use, -1 / m.value[0], bint, 1, 1, pLinePoints[0].x, pLinePoints[0].y); 3312 } 3313 3314 if (bolVertical == 0) //vertical segment 3315 { 3316 if (dIntLocation1y < dIntLocation2y) { 3317 UpperLinePoint.y = (int) dIntLocation1y + (int) (length / nNumberOfSegments / 2); 3318 } else { 3319 UpperLinePoint.y = (int) dIntLocation1y - (int) (length / nNumberOfSegments / 2); 3320 } 3321 if (pLinePoints[i].y < pLinePoints[i + 1].y) { 3322 UpperLinePoint.x = (int) dIntLocation1x + (int) (length / nNumberOfSegments); 3323 } else { 3324 UpperLinePoint.x = (int) dIntLocation1x - (int) (length / nNumberOfSegments); 3325 } 3326 } 3327 if (m.value[0] == 0 && bolVertical != 0) { 3328 if (dIntLocation1x < dIntLocation2x) { 3329 UpperLinePoint.x = (int) dIntLocation1x + (int) (length / nNumberOfSegments / 2); 3330 } else { 3331 UpperLinePoint.x = (int) dIntLocation1x - (int) (length / nNumberOfSegments / 2); 3332 } 3333 if (pLinePoints[i + 1].x < pLinePoints[i].x) { 3334 UpperLinePoint.y = (int) dIntLocation1y + (int) (length / nNumberOfSegments); 3335 } else { 3336 UpperLinePoint.y = (int) dIntLocation1y - (int) (length / nNumberOfSegments); 3337 } 3338 } 3339 //end section 3340 3341 Lower1LinePoint.x = dIntLocation1x; 3342 Lower1LinePoint.y = dIntLocation1y; 3343 Lower2LinePoint.x = dIntLocation2x; 3344 Lower2LinePoint.y = dIntLocation2y; 3345 3346 pLinePoints[nSpikeCounter] = new POINT2(Lower1LinePoint); 3347 if (linetype == TacticalLines.ATDITCHC || linetype == TacticalLines.ATDITCHM) { 3348 pLinePoints[nSpikeCounter].style = 9; 3349 } 3350 if (j % 2 == 1 && linetype == TacticalLines.ATDITCHM)//diagnostic 1-8-13 3351 { 3352 pLinePoints[nSpikeCounter].style = 5; 3353 } 3354 3355 nSpikeCounter++; 3356 3357 pLinePoints[nSpikeCounter] = new POINT2(UpperLinePoint); 3358 if (linetype == (long) TacticalLines.ATDITCHC || linetype == (long) TacticalLines.ATDITCHM) { 3359 pLinePoints[nSpikeCounter].style = 9; 3360 } 3361 if (j % 2 == 1 && linetype == TacticalLines.ATDITCHM)//diagnostic 1-8-13 3362 { 3363 pLinePoints[nSpikeCounter].style = 5; 3364 } 3365 3366 nSpikeCounter++; 3367 3368 pLinePoints[nSpikeCounter] = new POINT2(Lower2LinePoint); 3369 if (linetype == (long) TacticalLines.ATDITCHC || linetype == (long) TacticalLines.ATDITCHM) { 3370 pLinePoints[nSpikeCounter].style = 10; 3371 } 3372 if (j % 2 == 1 && linetype == TacticalLines.ATDITCHM)//diagnostic 1-8-13 3373 { 3374 pLinePoints[nSpikeCounter].style = 5; 3375 } 3376 3377 nSpikeCounter++; 3378 3379 if (linetype == TacticalLines.ATDITCHM) { 3380 if (j % 2 == 0) { 3381 averagePoint = lineutility.MidPointDouble(Lower1LinePoint, Lower2LinePoint, 0); 3382 averagePoint = lineutility.MidPointDouble(averagePoint, UpperLinePoint, 0); 3383 } else if (j == 1) { 3384 averagePoint = lineutility.ExtendLineDouble(Lower2LinePoint, Lower1LinePoint, 5); 3385 averagePoint = lineutility.MidPointDouble(averagePoint, UpperLinePoint, 0); 3386 } 3387 } 3388 //end section 3389 if (j > 1 && j < nNumberOfSegments) { 3390 basePoints.add(new POINT2(Lower1LinePoint)); 3391 //if(j==nNumberOfSegments-1) 3392 // basePoints.get(basePoints.size()-1).style=5; 3393 } else if (j == 1) { 3394 basePoints.add(new POINT2(pLinePoints[i])); 3395 } else if (j == nNumberOfSegments) { 3396 basePoints.add(new POINT2(pLinePoints[i + 1])); 3397 basePoints.get(basePoints.size() - 1).style = 5; 3398 } 3399 if (linetype == TacticalLines.ATDITCHM && j > 1) { 3400 if (j % 2 == 0) { 3401 pCirclePoints[lCircleCounter] = lineutility.MidPointDouble(averagePoint, lastAveragePoint, 20); 3402 lCircleCounter++; 3403 } 3404 //end section 3405 } 3406 if (j < nNumberOfSegments && linetype == TacticalLines.ATDITCHM) { 3407 if (j == 1 || j % 2 == 0) { 3408 //LastUpperLinePoint = new POINT2(UpperLinePoint); 3409 lastAveragePoint = new POINT2(averagePoint); 3410 } 3411 //end section 3412 } 3413 }//end for j<numberOfsegments 3414 } //end if length big enough 3415 else { 3416 //diagnostic 3417 pLinePoints[nSpikeCounter].x = pLinePoints[i].x; 3418 pLinePoints[nSpikeCounter].y = pLinePoints[i].y; 3419 pLinePoints[nSpikeCounter].style = 0; 3420 nSpikeCounter++; 3421 pLinePoints[nSpikeCounter].x = pLinePoints[i + 1].x; 3422 pLinePoints[nSpikeCounter].y = pLinePoints[i + 1].y; 3423 pLinePoints[nSpikeCounter].style = 5; 3424 nSpikeCounter++; 3425 } 3426 } 3427 3428 for (j = 0; j < nOldCounter; j++) //reverse the first nOldCounter points for 3429 { 3430 pLinePoints[j] = new POINT2(pTempLinePoints[nOldCounter - j - 1]); //purpose of drawing 3431 pLinePoints[j].style = 5; 3432 } 3433 3434 if (pLinePoints[nSpikeCounter - 1].style == 0) { 3435 pLinePoints[nSpikeCounter - 1].style = 5; 3436 } 3437 int t=basePoints.size(); 3438 //for (j = nSpikeCounter; j < nSpikeCounter + basePoints.size(); j++) 3439 for (j = nSpikeCounter; j < nSpikeCounter + t; j++) 3440 { 3441 pLinePoints[j] = new POINT2(basePoints.get(j - nSpikeCounter)); 3442 //if(linetype == TacticalLines.ATDITCHM && pLinePoints[j].style != 5) 3443 if (pLinePoints[j].style != 5) { 3444 pLinePoints[j].style = 0; 3445 } 3446 } 3447 nSpikeCounter += basePoints.size(); 3448 3449 if (linetype == (int) TacticalLines.ATDITCHM) { 3450 pLinePoints[nSpikeCounter - 1].style = 5;//was 10 3451 for (j = nSpikeCounter; j < nSpikeCounter + lCircleCounter; j++) { 3452 pLinePoints[j] = new POINT2(pCirclePoints[j - nSpikeCounter]); 3453 pLinePoints[j].style = 20; 3454 } 3455 nSpikeCounter += lCircleCounter; 3456 } 3457 3458 } catch (Exception exc) { 3459 ErrorLogger.LogException(_className, "GetDitchSpikeDouble", 3460 new RendererException("Failed inside GetDitchSpikeDouble", exc)); 3461 } 3462 return nSpikeCounter; 3463 } 3464 3465 /** 3466 * Moves pixels if points are identical, used for the channel types 3467 * 3468 * @param pLinePoints OUT - client points also for returned points 3469 */ 3470 protected static void MoveChannelPixels(POINT2[] pLinePoints) { 3471 try { 3472 if (pLinePoints == null || pLinePoints.length <= 0) { 3473 return; 3474 } 3475 3476 double[] pixels = new double[pLinePoints.length * 2]; 3477 boolean bolNoRepeats; 3478 int j, k = 0; 3479 double x1; 3480 double y1; 3481 double x2; 3482 double y2; 3483 int count = pLinePoints.length; 3484 //stuff pixels 3485 for (j = 0; j < count; j++) { 3486 pixels[k++] = pLinePoints[j].x; 3487 pixels[k++] = pLinePoints[j].y; 3488 } 3489 3490 bolNoRepeats = false; 3491 do { 3492 bolNoRepeats = true; 3493 for (j = 0; j < count - 1; j++) { 3494 x1 = pixels[2 * j]; 3495 y1 = pixels[2 * j + 1]; 3496 x2 = pixels[2 * j + 2]; 3497 y2 = pixels[2 * j + 3]; 3498 if (x1 == x2 && y1 == y2) //it's the same point 3499 { 3500 bolNoRepeats = false; 3501 pixels[2 * j + 2] = (long) x2 + 1; //move the point 3502 break; 3503 } 3504 } 3505 } while (bolNoRepeats == false); 3506 //stuff pLinePoints 3507 k = 0; 3508 for (j = 0; j < count; j++) { 3509 pLinePoints[j].x = pixels[k++]; 3510 pLinePoints[j].y = pixels[k++]; 3511 } 3512 } catch (Exception exc) { 3513 ErrorLogger.LogException(_className, "MoveChannelPixels", 3514 new RendererException("Failed inside MoveChannelPixels", exc)); 3515 } 3516 } 3517 3518 /** 3519 * Single Concertina cannot have horizontal first segment 3520 * 3521 * @param linetype 3522 * @param pLinePoints 3523 */ 3524 protected static void moveSingleCPixels(int linetype, POINT2[] pLinePoints) { 3525 try { 3526 switch (linetype) { 3527 case TacticalLines.SINGLEC: 3528 break; 3529 default: 3530 return; 3531 } 3532 if (pLinePoints.length > 1) { 3533 if (pLinePoints[1].y == pLinePoints[0].y) { 3534 pLinePoints[1].y++; 3535 } 3536 } 3537 } catch (Exception exc) { 3538 ErrorLogger.LogException(_className, "MoveSingleCPixels", 3539 new RendererException("Failed inside MoveSingleCPixels", exc)); 3540 } 3541 } 3542 3543 /** 3544 * Rotates an the first vblCounter points in the array about its first point 3545 * 3546 * @param pLinePoints OUT - the points to rotate 3547 * @param vblCounter the number of points to rotate 3548 * @param lAngle the angle in degrees to rotate 3549 * 3550 * @return pLinePoints 3551 */ 3552 protected static void RotateGeometryDouble(POINT2[] pLinePoints, 3553 int vblCounter, 3554 double lAngle) { 3555 try { 3556 int j = 0; 3557 double dRotate = 0, 3558 dTheta = 0, 3559 dGamma = 0, 3560 x = 0, 3561 y = 0; 3562 3563 if (lAngle != 0) //if the angle is 0 no rotation occurs 3564 { 3565 POINT2 pdCenter; 3566 dRotate = lAngle * Math.PI / 180d; 3567 pdCenter = CalcCenterPointDouble(pLinePoints, vblCounter); 3568 3569 for (j = 0; j < vblCounter; j++) { 3570 //added if/else to get rid of divide by zero error 5/12/04 M. Deutch 3571 if (pLinePoints[j].x == pdCenter.x) { 3572 if ((pLinePoints[j].y > pdCenter.y)) { 3573 dGamma = Math.PI + Math.PI / 2; 3574 } else { 3575 dGamma = Math.PI / 2; 3576 } 3577 } else { 3578 dGamma = Math.PI + Math.atan((pLinePoints[j].y - pdCenter.y) 3579 / (pLinePoints[j].x - pdCenter.x)); 3580 } 3581 3582 if ((double) pLinePoints[j].x >= pdCenter.x) { 3583 dGamma = dGamma + Math.PI; 3584 } 3585 3586 dTheta = dRotate + dGamma; 3587 y = CalcDistanceDouble(pLinePoints[j], pdCenter) * Math.sin(dTheta); 3588 x = CalcDistanceDouble(pLinePoints[j], pdCenter) * Math.cos(dTheta); 3589 pLinePoints[j].y = pdCenter.y + y; 3590 pLinePoints[j].x = pdCenter.x + x; 3591 } //end for 3592 3593 return; 3594 } //end if 3595 } catch (Exception exc) { 3596 ErrorLogger.LogException(_className, "RotateGeometryDouble", 3597 new RendererException("Failed inside RotateGeometryDouble", exc)); 3598 } 3599 } // end 3600 3601 /** 3602 * Returns the point perpendicular to the line (pt0 to pt1) at the midpoint 3603 * the same distance from (and on the same side of) the the line as 3604 * ptRelative. 3605 * 3606 * @param pt0 the first point 3607 * @param pt1 the second point 3608 * @param ptRelative the point to use for computing the return point 3609 * 3610 * @return the point perpendicular to the line at the midpoint 3611 */ 3612 protected static POINT2 PointRelativeToLine(POINT2 pt0, 3613 POINT2 pt1, 3614 POINT2 ptRelative) { 3615 POINT2 ptResult = new POINT2(pt0); 3616 try { 3617 int bolVertical = 0; 3618 ref<double[]> m = new ref(); 3619 POINT2 midPt = MidPointDouble(pt0, pt1, 0); 3620 double b1 = 0, b2 = 0; 3621 //end declarations 3622 3623 bolVertical = CalcTrueSlopeDouble(pt0, pt1, m); 3624 if (bolVertical == 0) //line is vertical 3625 { 3626 ptResult.x = ptRelative.x; 3627 ptResult.y = midPt.y; 3628 } 3629 if (bolVertical != 0 && m.value[0] == 0) { 3630 ptResult.x = midPt.x; 3631 ptResult.y = ptRelative.y; 3632 } 3633 if (bolVertical != 0 && m.value[0] != 0) { 3634 b1 = midPt.y + (1 / m.value[0]) * midPt.x; //the line perp to midPt 3635 b2 = ptRelative.y - m.value[0] * ptRelative.x; //the line ptRelative with the slope of pt1-pt2 3636 ptResult = CalcTrueIntersectDouble2(-1 / m.value[0], b1, m.value[0], b2, 1, 1, 0, 0); 3637 } 3638 } catch (Exception exc) { 3639 ErrorLogger.LogException(_className, "PointRelativeToLine", 3640 new RendererException("Failed inside PointRelativeToLine", exc)); 3641 } 3642 return ptResult; 3643 } 3644 3645 /** 3646 * shift the control point to match the shift that occurs in 3647 * Channels.GetAXADDouble for CATKBYFIRE. This is because the rotary feature 3648 * arrow tip must align with the anchor point 3649 * 3650 * @param linetype 3651 * @param pLinePoints the anchor points including the control point 3652 * @param minDist the minimum required distance from the front of the rotary 3653 * arrow 3654 */ 3655 public static void adjustCATKBYFIREControlPoint(int linetype, 3656 ArrayList<POINT2> pLinePoints, 3657 double dist) { 3658 try { 3659 if (linetype != TacticalLines.CATKBYFIRE) { 3660 return; 3661 } 3662 3663 double dist2 = lineutility.CalcDistanceDouble(pLinePoints.get(0), pLinePoints.get(1)); 3664 if (dist2 <= dist) { 3665 return; 3666 } 3667 3668 POINT2 pt = null; 3669 int count = pLinePoints.size(); 3670 POINT2 pt0 = new POINT2(pLinePoints.get(0)); 3671 POINT2 pt1 = new POINT2(pLinePoints.get(1)); 3672 POINT2 controlPt = new POINT2(pLinePoints.get(count - 1)); 3673 POINT2 pt4 = PointRelativeToLine(pt0, pt1, pt1, controlPt); 3674 pt = lineutility.ExtendLineDouble(pt4, controlPt, dist); 3675 pLinePoints.set(count - 1, pt); 3676 } catch (Exception exc) { 3677 ErrorLogger.LogException(_className, "adjustCATKBYFIREControlPoint", 3678 new RendererException("Failed inside adjustCATKBYFIREControlPoint", exc)); 3679 } 3680 } 3681 3682 /** 3683 * Returns the point perpendicular to the line (pt0 to pt1) at atPoint the 3684 * same distance from (and on the same side of) the the line as ptRelative. 3685 * 3686 * @param pt0 the first point 3687 * @param pt1 the second point 3688 * @param atPoint the point on the line at which to compute the extended 3689 * point 3690 * @param ptRelative the point to use for computing the return point 3691 * 3692 * @return the point perpendicular to the line at ptRelative 3693 */ 3694 public static POINT2 PointRelativeToLine(POINT2 pt0, 3695 POINT2 pt1, 3696 POINT2 atPoint, 3697 POINT2 ptRelative) { 3698 POINT2 ptResult = new POINT2(pt0); 3699 try { 3700 int bolVertical = 0; 3701 ref<double[]> m = new ref(); 3702 double b1 = 0, b2 = 0; 3703 3704 bolVertical = CalcTrueSlopeDouble(pt0, pt1, m); 3705 if (bolVertical == 0) //line is vertical 3706 { 3707 ptResult.x = ptRelative.x; 3708 ptResult.y = atPoint.y; 3709 } 3710 if (bolVertical != 0 && m.value[0] == 0) { 3711 ptResult.x = atPoint.x; 3712 ptResult.y = ptRelative.y; 3713 } 3714 if (bolVertical != 0 && m.value[0] != 0) { 3715 b1 = atPoint.y + (1 / m.value[0]) * atPoint.x; //the line perp to midPt 3716 b2 = ptRelative.y - m.value[0] * ptRelative.x; //the line ptRelative with the slope of pt1-pt2 3717 ptResult = CalcTrueIntersectDouble2(-1 / m.value[0], b1, m.value[0], b2, 1, 1, 0, 0); 3718 } 3719 } catch (Exception exc) { 3720 ErrorLogger.LogException(_className, "PointRelativeToLine", 3721 new RendererException("Failed inside PointRelativeToLine", exc)); 3722 } 3723 return ptResult; 3724 } 3725 3726 /** 3727 * Returns in pt2 and pt3 the line segment parallel to segment pt0-pt1 which 3728 * would contain ptRelative. pt2 corresponds to pt0 and pt3 corresponds to 3729 * pt1. 3730 * 3731 * @param pt0 first line point 3732 * @param pt1 second line point 3733 * @param ptRelative relative line point 3734 * @param pt2 OUT - first computed relative line point 3735 * @param pt3 OUT - second computed relative line point 3736 */ 3737 public static void LineRelativeToLine(POINT2 pt0, 3738 POINT2 pt1, 3739 POINT2 ptRelative, 3740 POINT2 pt2, 3741 POINT2 pt3) { 3742 try { 3743 int bolVertical = 0; 3744 ref<double[]> m = new ref(); 3745 double b1 = 0, b2 = 0; 3746 POINT2 pt2Temp = null; 3747 POINT2 pt3Temp = null; 3748 3749 bolVertical = CalcTrueSlopeDouble(pt0, pt1, m); 3750 if (bolVertical == 0) //line is vertical 3751 { 3752 pt2.x = ptRelative.x; 3753 pt2.y = pt0.y; 3754 pt3.x = ptRelative.x; 3755 pt3.y = pt1.y; 3756 } 3757 if (bolVertical != 0 && m.value[0] == 0) //line is horizontal 3758 { 3759 pt2.x = pt0.x; 3760 pt2.y = ptRelative.y; 3761 pt3.x = pt1.x; 3762 pt3.y = ptRelative.y; 3763 } 3764 if (bolVertical != 0 && m.value[0] != 0) { 3765 b1 = pt0.y + (1 / m.value[0]) * pt0.x; //the line perp to pt0 3766 b2 = ptRelative.y - m.value[0] * ptRelative.x; //the line the ptRelative with the slope of pt0-pt1 3767 pt2Temp = CalcTrueIntersectDouble2(-1 / m.value[0], b1, m.value[0], b2, 1, 1, 0, 0); 3768 3769 b1 = pt1.y + (1 / m.value[0]) * pt1.x; //the line perp to pt1 3770 //b2=ptRelative.y-m*ptRelative.x; //the line the ptRelative with the slope of pt0-pt1 3771 pt3Temp = CalcTrueIntersectDouble2(-1 / m.value[0], b1, m.value[0], b2, 1, 1, 0, 0); 3772 3773 pt2.x = pt2Temp.x; 3774 pt2.y = pt2Temp.y; 3775 pt3.x = pt3Temp.x; 3776 pt3.y = pt3Temp.y; 3777 } 3778 } catch (Exception exc) { 3779 ErrorLogger.LogException(_className, "LineRelativeToLine", 3780 new RendererException("Failed inside LineRelativeToLine", exc)); 3781 } 3782 } 3783 3784 private static void CalcMBR(POINT2[] pLinePoints, 3785 int numpts, 3786 ref<double[]> ulx, 3787 ref<double[]> uly, 3788 ref<double[]> lrx, 3789 ref<double[]> lry) { 3790 try { 3791 int j = 0; 3792 //initialize the MBR 3793 ulx.value = new double[1]; 3794 uly.value = new double[1]; 3795 lrx.value = new double[1]; 3796 lry.value = new double[1]; 3797 ulx.value[0] = Double.MAX_VALUE;//was 99999 3798 uly.value[0] = Double.MAX_VALUE;//was 99999 3799 lrx.value[0] = -Double.MAX_VALUE;//was -99999 3800 lry.value[0] = -Double.MAX_VALUE;//was -99999 3801 for (j = 0; j < numpts; j++) { 3802 if (pLinePoints[j].x > lrx.value[0]) { 3803 lrx.value[0] = pLinePoints[j].x; 3804 } 3805 if (pLinePoints[j].y > lry.value[0]) { 3806 lry.value[0] = pLinePoints[j].y; 3807 } 3808 if (pLinePoints[j].x < ulx.value[0]) { 3809 ulx.value[0] = pLinePoints[j].x; 3810 } 3811 if (pLinePoints[j].y < uly.value[0]) { 3812 uly.value[0] = pLinePoints[j].y; 3813 } 3814 } 3815 } catch (Exception exc) { 3816 ErrorLogger.LogException(_className, "CalcMBR", 3817 new RendererException("Failed inside CalcMBR", exc)); 3818 } 3819 return; 3820 } 3821 3822 public static void CalcMBRPoints(POINT2[] pLinePoints, 3823 int numpts, 3824 POINT2 ul, 3825 POINT2 lr) { 3826 try { 3827 int j = 0; 3828 ul.x = Double.MAX_VALUE; 3829 ul.y = Double.MAX_VALUE; 3830 lr.x = -Double.MAX_VALUE; 3831 lr.y = -Double.MAX_VALUE; 3832 for (j = 0; j < numpts; j++) { 3833 if (pLinePoints[j].x > lr.x) { 3834 lr.x = pLinePoints[j].x; 3835 } 3836 if (pLinePoints[j].y > lr.y) { 3837 lr.y = pLinePoints[j].y; 3838 } 3839 if (pLinePoints[j].x < ul.x) { 3840 ul.x = pLinePoints[j].x; 3841 } 3842 if (pLinePoints[j].y < ul.y) { 3843 ul.y = pLinePoints[j].y; 3844 } 3845 } 3846 } catch (Exception exc) { 3847 ErrorLogger.LogException(_className, "CalcMBRPoints", 3848 new RendererException("Failed inside CalcMBRPoints", exc)); 3849 } 3850 } 3851 3852 /** 3853 * Computes the distance in pixels from upper left to lower right of the 3854 * minimum bounding rectangle for the first numpts of pLinePoints 3855 * 3856 * @param pLinePoints the inpupt point array 3857 * @param numpts the number of points to use 3858 * 3859 * @return the distance in pixels 3860 */ 3861 protected static double MBRDistance(POINT2[] pLinePoints, 3862 int numpts) { 3863 double result = 0; 3864 try { 3865 ref<double[]> ulx = new ref(), uly = new ref(), lrx = new ref(), lry = new ref(); 3866 CalcMBR(pLinePoints, numpts, ulx, uly, lrx, lry); 3867 result = Math.sqrt((lrx.value[0] - ulx.value[0]) * (lrx.value[0] - ulx.value[0]) + (lry.value[0] - uly.value[0]) * (lry.value[0] - uly.value[0])); 3868 //sanity check 3869 3870 //return x or y distance if returnValue is 0 or infinity 3871 double xdist = Math.abs(lrx.value[0] - ulx.value[0]); 3872 double ydist = Math.abs(lry.value[0] - uly.value[0]); 3873 double max = xdist; 3874 if (ydist > xdist) { 3875 max = ydist; 3876 } 3877 3878 if (result == 0 || Double.isInfinite(result)) { 3879 if (max > 0) { 3880 result = max; 3881 } 3882 } 3883 3884 } catch (Exception exc) { 3885 ErrorLogger.LogException(_className, "MBRDistance", 3886 new RendererException("Failed inside MBRDistance", exc)); 3887 } 3888 return result; 3889 } 3890 3891 /** 3892 * Swaps two points. 3893 * 3894 * @param pt1 OUT - first point 3895 * @param pt2 OUT - second point 3896 * 3897 */ 3898 protected static void Reverse2Points(POINT2 pt1, POINT2 pt2) { 3899 try { 3900 POINT2 tempPt = new POINT2(); 3901 //store pt1 3902 tempPt.x = pt1.x; 3903 tempPt.y = pt1.y; 3904 pt1.x = pt2.x; 3905 pt1.y = pt2.y; 3906 pt2.x = tempPt.x; 3907 pt2.y = tempPt.y; 3908 } catch (Exception exc) { 3909 ErrorLogger.LogException(_className, "Reverse2Points", 3910 new RendererException("Failed inside Reverse2Points", exc)); 3911 } 3912 } 3913 /** 3914 * Creates a GeneralPath from a Path2D 3915 * 3916 * @param shape 3917 * @return 3918 */ 3919 public static Shape createStrokedShape(Shape shape) { 3920 GeneralPath newshape = new GeneralPath(); // Start with an empty shape 3921 try { 3922 // Iterate through the specified shape, perturb its coordinates, and 3923 // use them to build up the new shape. 3924 float[] coords = new float[6]; 3925 for (PathIterator i = shape.getPathIterator(null); !i.isDone(); i.next()) { 3926 int type = i.currentSegment(coords); 3927 switch (type) { 3928 case PathIterator.SEG_MOVETO: 3929 //perturb(coords, 2); 3930 newshape.moveTo(coords[0], coords[1]); 3931 break; 3932 case PathIterator.SEG_LINETO: 3933 //perturb(coords, 2); 3934 newshape.lineTo(coords[0], coords[1]); 3935 break; 3936 case PathIterator.SEG_QUADTO: 3937 //perturb(coords, 4); 3938 newshape.quadTo(coords[0], coords[1], coords[2], coords[3]); 3939 break; 3940 case PathIterator.SEG_CUBICTO: 3941 //perturb(coords, 6); 3942 newshape.curveTo(coords[0], coords[1], coords[2], coords[3], 3943 coords[4], coords[5]); 3944 break; 3945 case PathIterator.SEG_CLOSE: 3946 newshape.closePath(); 3947 break; 3948 } 3949 3950 } 3951 } catch (Exception exc) { 3952 ErrorLogger.LogException(_className, "createStrokedShape", 3953 new RendererException("Failed inside createStrokedShape", exc)); 3954 } 3955 return newshape; 3956 } 3957 //These functions were added to create a minimum bounding polygon 3958 /** 3959 * @deprecated Returns the determinant of the point matrix This determinant 3960 * tells how far p3 is from vector p1p2 and on which side it is 3961 * @param p1 3962 * @param p2 3963 * @param p3 3964 * @return 3965 */ 3966 static private int distance(Point p1, Point p2, Point p3) { 3967 try { 3968 int x1 = p1.x; 3969 int x2 = p2.x; 3970 int x3 = p3.x; 3971 int y1 = p1.y; 3972 int y2 = p2.y; 3973 int y3 = p3.y; 3974 return x1 * y2 + x3 * y1 + x2 * y3 - x3 * y2 - x2 * y1 - x1 * y3; 3975 } catch (Exception exc) { 3976 ErrorLogger.LogException(_className, "distance", 3977 new RendererException("Failed inside distance", exc)); 3978 } 3979 return 0; 3980 } 3981 3982 /** 3983 * @deprecated Returns the determinant of the point matrix This determinant 3984 * tells how far p3 is from vector p1p2 and on which side it is 3985 * @param p1 3986 * @param p2 3987 * @param p3 3988 * @return 3989 */ 3990 static private double distance2(POINT2 p1, POINT2 p2, POINT2 p3) { 3991 try { 3992 double x1 = p1.x; 3993 double x2 = p2.x; 3994 double x3 = p3.x; 3995 double y1 = p1.y; 3996 double y2 = p2.y; 3997 double y3 = p3.y; 3998 return x1 * y2 + x3 * y1 + x2 * y3 - x3 * y2 - x2 * y1 - x1 * y3; 3999 } catch (Exception exc) { 4000 ErrorLogger.LogException(_className, "distance2", 4001 new RendererException("Failed inside distance2", exc)); 4002 } 4003 return 0; 4004 } 4005 4006 /** 4007 * @deprecated @param points 4008 * @param l 4009 * @param r 4010 * @param path 4011 */ 4012 static private void cHull(ArrayList<Point> points, Point l, Point r, ArrayList<Point> path) { 4013 4014 if (points.size() < 3) { 4015 return; 4016 } 4017 4018 int maxDist = 0; 4019 int tmp; 4020 Point p = null; 4021 4022 for (Point pt : points) { 4023 if (pt != l && pt != r) { 4024 tmp = distance(l, r, pt); 4025 4026 if (tmp > maxDist) { 4027 maxDist = tmp; 4028 p = pt; 4029 } 4030 } 4031 } 4032 4033 ArrayList<Point> left = new ArrayList<Point>(); 4034 ArrayList<Point> right = new ArrayList<Point>(); 4035 left.add(l); 4036 right.add(p); 4037 4038 for (Point pt : points) { 4039 if (distance(l, p, pt) > 0) { 4040 left.add(pt); 4041 } else if (distance(p, r, pt) > 0) { 4042 right.add(pt); 4043 } 4044 } 4045 4046 left.add(p); 4047 right.add(r); 4048 cHull(left, l, p, path); 4049 path.add(p); 4050 cHull(right, p, r, path); 4051 } 4052 4053 /** 4054 * @deprecated @param points 4055 * @param l 4056 * @param r 4057 * @param path 4058 */ 4059 static private void cHull2(ArrayList<POINT2> points, POINT2 l, POINT2 r, ArrayList<POINT2> path) { 4060 4061 if (points.size() < 3) { 4062 return; 4063 } 4064 4065 double maxDist = 0; 4066 double tmp; 4067 POINT2 p = null; 4068 4069 for (POINT2 pt : points) { 4070 if (pt != l && pt != r) { 4071 tmp = distance2(l, r, pt); 4072 4073 if (tmp > maxDist) { 4074 maxDist = tmp; 4075 p = pt; 4076 } 4077 } 4078 } 4079 4080 ArrayList<POINT2> left = new ArrayList<POINT2>(); 4081 ArrayList<POINT2> right = new ArrayList<POINT2>(); 4082 left.add(l); 4083 right.add(p); 4084 4085 for (POINT2 pt : points) { 4086 if (distance2(l, p, pt) > 0) { 4087 left.add(pt); 4088 } else if (distance2(p, r, pt) > 0) { 4089 right.add(pt); 4090 } 4091 } 4092 4093 left.add(p); 4094 right.add(r); 4095 cHull2(left, l, p, path); 4096 path.add(p); 4097 cHull2(right, p, r, path); 4098 } 4099 //Returns the points of convex hull in the correct order 4100 /** 4101 * @deprecated @param array 4102 * @return 4103 */ 4104 static public ArrayList<Point> cHull(ArrayList<Point> array) { 4105 int size = array.size(); 4106 if (size < 2) { 4107 return null; 4108 } 4109 4110 Point l = array.get(0); 4111 Point r = array.get(size - 1); 4112 ArrayList<Point> path = new ArrayList<Point>(); 4113 path.add(l); 4114 cHull(array, l, r, path); 4115 path.add(r); 4116 cHull(array, r, l, path); 4117 return path; 4118 } 4119 4120 /** 4121 * @deprecated @param array 4122 * @return 4123 */ 4124 static public ArrayList<POINT2> cHull2(ArrayList<POINT2> array) { 4125 try { 4126 int size = array.size(); 4127 if (size < 2) { 4128 return null; 4129 } 4130 4131 POINT2 l = array.get(0); 4132 POINT2 r = array.get(size - 1); 4133 ArrayList<POINT2> path = new ArrayList<POINT2>(); 4134 path.add(l); 4135 cHull2(array, l, r, path); 4136 path.add(r); 4137 cHull2(array, r, l, path); 4138 return path; 4139 } catch (Exception exc) { 4140 ErrorLogger.LogException(_className, "cHull2", 4141 new RendererException("Failed inside cHull2", exc)); 4142 } 4143 return null; 4144 } 4145 4146 public static void getExteriorPoints(POINT2[] pLinePoints, 4147 int vblCounter, 4148 int lineType, 4149 boolean interior 4150 ) { 4151 int j; 4152 int index; 4153 POINT2 pt0, pt1, pt2; 4154 ref<double[]> m01 = new ref(), m12 = new ref(); 4155 int direction; 4156 POINT2 intersectPt; 4157 //ref<double[]> m1 = new ref(), m2 = new ref(); 4158 ArrayList<POINT2> intersectPoints = new ArrayList(); 4159 double b01, b12; //the y intercepts for the lines corresponding to m1,m2 4160 double dist = pLinePoints[0].style; 4161 for (j = 0; j < vblCounter; j++) { 4162 if (j == 0 || j == vblCounter - 1) { 4163 pt0 = new POINT2(pLinePoints[vblCounter - 2]); 4164 pt1 = new POINT2(pLinePoints[0]); 4165 pt2 = new POINT2(pLinePoints[1]); 4166 } else { 4167 pt0 = new POINT2(pLinePoints[j - 1]); 4168 pt1 = new POINT2(pLinePoints[j]); 4169 pt2 = new POINT2(pLinePoints[j + 1]); 4170 } 4171 if (pt1.style > 0) { 4172 dist = pt1.style; 4173 } 4174 //the exterior/interior points 4175 POINT2 pt00, pt01, pt10, pt11; 4176 4177 index = j - 1; 4178 if (index < 0) { 4179 index = vblCounter - 1; 4180 } 4181 POINT2[] pts = new POINT2[pLinePoints.length]; 4182 int n=pLinePoints.length; 4183 //for (int k = 0; k < pLinePoints.length; k++) 4184 for (int k = 0; k < n; k++) 4185 { 4186 pts[k] = pLinePoints[k]; 4187 } 4188 4189 direction = arraysupport.GetInsideOutsideDouble2(pt0, pt1, pts, vblCounter, index, lineType); 4190 //reverse the direction if these are interior points 4191 if (interior == true) { 4192 switch (direction) { 4193 case 0: 4194 direction = 1; 4195 break; 4196 case 1: 4197 direction = 0; 4198 break; 4199 case 2: 4200 direction = 3; 4201 break; 4202 case 3: 4203 direction = 2; 4204 break; 4205 default: 4206 break; 4207 } 4208 } 4209 //pt00-pt01 will be the interior line inside line pt0-pt1 4210 //pt00 is inside pt0, pt01 is inside pt1 4211 pt00 = lineutility.ExtendDirectedLine(pt0, pt1, pt0, direction, dist); 4212 pt01 = lineutility.ExtendDirectedLine(pt0, pt1, pt1, direction, dist); 4213 4214 //pt10-pt11 will be the interior line inside line pt1-pt2 4215 //pt10 is inside pt1, pt11 is inside pt2 4216 index = j; 4217 if (j == vblCounter - 1) { 4218 index = 0; 4219 } 4220 direction = arraysupport.GetInsideOutsideDouble2(pt1, pt2, (POINT2[]) pts, vblCounter, index, lineType); 4221 //reverse the direction if these are interior points 4222 if (interior == true) { 4223 switch (direction) { 4224 case 0: 4225 direction = 1; 4226 break; 4227 case 1: 4228 direction = 0; 4229 break; 4230 case 2: 4231 direction = 3; 4232 break; 4233 case 3: 4234 direction = 2; 4235 break; 4236 default: 4237 break; 4238 } 4239 } 4240 pt10 = lineutility.ExtendDirectedLine(pt1, pt2, pt1, direction, dist); 4241 pt11 = lineutility.ExtendDirectedLine(pt1, pt2, pt2, direction, dist); 4242 //intersectPt=new POINT2(null); 4243 //get the intersection of pt01-p00 and pt10-pt11 4244 //so it it is the interior intersection of pt0-pt1 and pt1-pt2 4245 4246 //first handle the case of vertical lines. 4247 if (pt0.x == pt1.x && pt1.x == pt2.x) { 4248 intersectPt = new POINT2(pt01); 4249 intersectPoints.add(intersectPt); 4250 continue; 4251 } 4252 //it's the same situation if the slopes are identical, 4253 //simply use pt01 or pt10 since they already uniquely define the intesection 4254 lineutility.CalcTrueSlopeDouble2(pt00, pt01, m01); 4255 lineutility.CalcTrueSlopeDouble2(pt10, pt11, m12); 4256 //if(m01.dbl==m12.dbl) 4257 if (m01.value[0] == m12.value[0]) { 4258 intersectPt = new POINT2(pt01); 4259 intersectPoints.add(intersectPt); 4260 continue; 4261 } 4262 //now we are assuming a non-trivial intersection 4263 //calculate the y-intercepts using y=mx+b (use b=y-mx) 4264 b01 = pt01.y - m01.value[0] * pt01.x; 4265 b12 = pt11.y - m12.value[0] * pt11.x; 4266 intersectPt = lineutility.CalcTrueIntersectDouble2(m01.value[0], b01, m12.value[0], b12, 1, 1, 0, 0); 4267 intersectPoints.add(intersectPt); 4268 }//end for 4269 int n=intersectPoints.size(); 4270 //for (j = 0; j < intersectPoints.size(); j++) 4271 for (j = 0; j < n; j++) 4272 { 4273 pLinePoints[j] = intersectPoints.get(j); 4274 } 4275 } 4276 public static ArrayList<POINT2> getDeepCopy(ArrayList<POINT2>pts) 4277 { 4278 ArrayList<POINT2>deepCopy=null; 4279 try 4280 { 4281 if(pts == null || pts.isEmpty()) 4282 return pts; 4283 deepCopy=new ArrayList(); 4284 int j=0; 4285 POINT2 pt=null; 4286 for(j=0;j<pts.size();j++) 4287 { 4288 pt=new POINT2(pts.get(j).x,pts.get(j).y,pts.get(j).style); 4289 deepCopy.add(pt); 4290 } 4291 } 4292 catch (Exception exc) { 4293 ErrorLogger.LogException(_className, "getDeepCopy", 4294 new RendererException("Failed inside getDeepCopy", exc)); 4295 } 4296 return deepCopy; 4297 } 4298 4299}//end lineutility