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