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()); 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.TRIP: 2355 startangle = M - 45 * Math.PI / 180.0; 2356 endangle = startangle + 2 * 45 * Math.PI / 180.0; 2357 break; 2358 case TacticalLines.ISOLATE: 2359 case TacticalLines.CORDONKNOCK: 2360 case TacticalLines.CORDONSEARCH: 2361 startangle = M; 2362 endangle = startangle + 330 * Math.PI / 180; 2363 break; 2364 case TacticalLines.TURN: 2365 startangle = M; 2366 endangle = startangle + 90 * Math.PI / 180; 2367 break; 2368 case TacticalLines.OCCUPY: 2369 case TacticalLines.RETAIN: 2370 case TacticalLines.SECURE: 2371 startangle = M; 2372 //if(CELineArrayGlobals.Change1==false) 2373 endangle = startangle + 338 * Math.PI / 180; 2374 //else 2375 // endangle=startangle+330*pi/180; 2376 break; 2377 default: 2378 startangle = 0; 2379 endangle = 2 * Math.PI; 2380 break; 2381 } 2382 2383 if (a.x < e.x) { 2384 switch (linetype) { 2385 case TacticalLines.ISOLATE: 2386 case TacticalLines.CORDONKNOCK: 2387 case TacticalLines.CORDONSEARCH: 2388 startangle = M - Math.PI; 2389 endangle = startangle + 330 * Math.PI / 180; 2390 break; 2391 case TacticalLines.OCCUPY: 2392 case TacticalLines.RETAIN: 2393 case TacticalLines.SECURE: 2394 startangle = M - Math.PI; 2395 //if(CELineArrayGlobals.Change1==false) 2396 endangle = startangle + 338 * Math.PI / 180; 2397 //else 2398 // endangle=startangle+330*pi/180; 2399 break; 2400 case TacticalLines.TURN: 2401 startangle = M - Math.PI; 2402 endangle = startangle + 90 * Math.PI / 180; 2403 break; 2404 case TacticalLines.CLUSTER: 2405 startangle = M - Math.PI + 90 * Math.PI / 180.0; 2406 endangle = startangle - 2 * 90 * Math.PI / 180.0; 2407 break; 2408 case TacticalLines.TRIP: 2409 startangle = M - Math.PI + 45 * Math.PI / 180.0; 2410 endangle = startangle - 2 * 45 * Math.PI / 180.0; 2411 break; 2412 default: 2413 break; 2414 } 2415 } 2416 2417 numarcpts = 26; 2418 pArcLinePoints = new POINT2[numarcpts]; 2419 InitializePOINT2Array(pArcLinePoints); 2420 increment = (endangle - startangle) / (numarcpts - 1); 2421 if(dRadius != 0 && length != 0) 2422 { 2423 C.x = (int) ((double) e.x - (dRadius / length) 2424 * ((double) a.x - (double) e.x)); 2425 C.y = (int) ((double) e.y - (dRadius / length) 2426 * ((double) a.y - (double) e.y)); 2427 } 2428 else 2429 { 2430 C.x=e.x; 2431 C.y=e.y; 2432 } 2433 if (converter != null) 2434 { 2435 Point2D C2d=new Point2D.Double(pResultLinePoints[0].x,pResultLinePoints[0].y); 2436 C2d=converter.PixelsToGeo(C2d); 2437 double az=0; 2438 Point2D ptGeo2d=null; 2439 POINT2 ptGeo=null; 2440 POINT2 ptPixels=null; 2441 for (j = 0; j < numarcpts; j++) { 2442 az=startangle*180/Math.PI+j*increment*180/Math.PI; 2443 //ptGeo=mdlGeodesic.geodesic_coordinate(C2d,length,az); 2444 ptGeo=mdlGeodesic.geodesic_coordinate(new POINT2(C2d.getX(),C2d.getY()),length,az); 2445 ptGeo2d=new Point2D.Double(ptGeo.x,ptGeo.y); 2446 ptGeo2d=converter.GeoToPixels(ptGeo2d); 2447 ptPixels=new POINT2(ptGeo2d.getX(),ptGeo2d.getY()); 2448 pArcLinePoints[j].x = ptPixels.x; 2449 pArcLinePoints[j].y = ptPixels.y; 2450 } 2451 } 2452 else 2453 { 2454 for (j = 0; j < numarcpts; j++) { 2455 //pArcLinePoints[j]=pResultLinePoints[0]; //initialize 2456 pArcLinePoints[j].x = (int) (dRadius * Math.cos(startangle + j * increment)); 2457 pArcLinePoints[j].y = (int) (dRadius * Math.sin(startangle + j * increment)); 2458 } 2459 2460 for (j = 0; j < numarcpts; j++) { 2461 pArcLinePoints[j].x += C.x; 2462 pArcLinePoints[j].y += C.y; 2463 } 2464 } 2465 for (j = 0; j < numarcpts; j++) { 2466 pResultLinePoints[j] = new POINT2(pArcLinePoints[j]); 2467 } 2468 pArcLinePoints = null; 2469 } catch (Exception exc) { 2470 ErrorLogger.LogException(_className, "ArcArrayDouble", 2471 new RendererException("Failed inside ArcArrayDouble", exc)); 2472 } 2473 return pResultLinePoints; 2474 } 2475 /** 2476 * Gets geodesic circle using the converter 2477 * @param Center in pixels 2478 * @param pt1 a point on the radius in pixels 2479 * @param numpts number of points to return 2480 * @param CirclePoints the result points 2481 * @param converter 2482 */ 2483 protected static void CalcCircleDouble2(POINT2 Center, 2484 POINT2 pt1, 2485 int numpts, 2486 POINT2[] CirclePoints, 2487 IPointConversion converter) { 2488 try { 2489 int j = 0; 2490 double increment = (Math.PI * 2) / (numpts - 1); 2491 Point2D ptCenter2d=new Point2D.Double(Center.x,Center.y); 2492 ptCenter2d=converter.PixelsToGeo(ptCenter2d); 2493 Point2D pt12d=new Point2D.Double(pt1.x,pt1.y); 2494 pt12d=converter.PixelsToGeo(pt12d); 2495 Center=new POINT2(ptCenter2d.getX(),ptCenter2d.getY()); 2496 pt1=new POINT2(pt12d.getX(),pt12d.getY()); 2497 double dist=mdlGeodesic.geodesic_distance(Center, pt1, null, null); 2498 2499 //double dSegmentAngle = 2 * Math.PI / numpts; 2500 double az=0; 2501 double startangle=0,endAngle=Math.PI*2; 2502 POINT2 ptGeo=null,ptPixels=null; 2503 Point2D ptGeo2d=null; 2504 for (j = 0; j < numpts - 1; j++) { 2505 az=startangle*180/Math.PI+j*increment*180/Math.PI; 2506 //ptGeo=mdlGeodesic.geodesic_coordinate(C2d,length,az); 2507 ptGeo=mdlGeodesic.geodesic_coordinate(Center,dist,az); 2508 ptGeo2d=new Point2D.Double(ptGeo.x,ptGeo.y); 2509 ptGeo2d=converter.GeoToPixels(ptGeo2d); 2510 ptPixels=new POINT2(ptGeo2d.getX(),ptGeo2d.getY()); 2511 CirclePoints[j].x = ptPixels.x; 2512 CirclePoints[j].y = ptPixels.y; 2513 } 2514 CirclePoints[numpts - 1] = new POINT2(CirclePoints[0]); 2515 2516 } catch (Exception exc) { 2517 ErrorLogger.LogException(_className, "CalcCircleDouble2", 2518 new RendererException("Failed inside CalcCircleDouble2", exc)); 2519 } 2520 return; 2521 } 2522 /** 2523 * Computes the points for a circle. Assumes CirclePoints has been allocated 2524 * with size numpts. 2525 * 2526 * @param Center the cicle center 2527 * @param radius the circle radius in pixels 2528 * @param numpts the number of circle points 2529 * @param CirclePoints - OUT - array of circle points 2530 * @param styl the style to set the last circle point 2531 */ 2532 protected static void CalcCircleDouble(POINT2 Center, 2533 double radius, 2534 int numpts, 2535 POINT2[] CirclePoints, 2536 int styl) { 2537 try { 2538 int j = 0; 2539 double dSegmentAngle = 2 * Math.PI / (numpts - 1); 2540 double x = 0, y = 0; 2541 for (j = 0; j < numpts - 1; j++) { 2542 x = Center.x + (radius * Math.cos((double) j * dSegmentAngle)); 2543 y = Center.y + (radius * Math.sin((double) j * dSegmentAngle)); 2544 CirclePoints[j] = new POINT2(x, y); 2545 CirclePoints[j].style = styl; 2546 } 2547 CirclePoints[numpts - 1] = new POINT2(CirclePoints[0]); 2548 2549 switch (styl) { 2550 case 0: 2551 CirclePoints[numpts - 1].style = 0; 2552 break; 2553 case 9: 2554 CirclePoints[numpts - 1].style = 10; 2555 break; 2556 case 11: 2557 CirclePoints[numpts - 1].style = 12; 2558 break; 2559 default: 2560 CirclePoints[numpts - 1].style = 5; 2561 break; 2562 } 2563 } catch (Exception exc) { 2564 ErrorLogger.LogException(_className, "CalcCircleDouble", 2565 new RendererException("Failed inside CalcCircleDouble", exc)); 2566 } 2567 } 2568 2569 protected static Shape2 CalcCircleShape(POINT2 Center, 2570 double radius, 2571 int numpts, 2572 POINT2[] CirclePoints, 2573 int styl) { 2574 Shape2 shape; 2575 if (styl == 9) { 2576 shape = new Shape2(Shape2.SHAPE_TYPE_FILL); 2577 } else { 2578 shape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE); 2579 } 2580 2581 shape.set_Style(styl); 2582 try { 2583 int j = 0; 2584 CalcCircleDouble(Center, radius, numpts, CirclePoints, styl); 2585 shape.moveTo(CirclePoints[0]); 2586 for (j = 1; j < numpts; j++) { 2587 shape.lineTo(CirclePoints[j]); 2588 } 2589 } catch (Exception exc) { 2590 ErrorLogger.LogException(_className, "CalcCircleShape", 2591 new RendererException("Failed inside CalcCircleShape", exc)); 2592 } 2593 return shape; 2594 } 2595 2596 private static void GetSquallCurve(POINT2 StartPt, 2597 POINT2 EndPt, 2598 POINT2[] pSquallPts, 2599 int sign, 2600 double amplitude, 2601 int quantity) { 2602 try { 2603 double dist = CalcDistanceDouble(StartPt, EndPt); 2604 POINT2 ptTemp = new POINT2(); 2605 int j = 0; 2606 //end declarations 2607 2608 //get points along the horizontal segment between StartPt and EndPt2; 2609 for (j = 0; j < quantity; j++) { 2610 ptTemp = ExtendLineDouble(EndPt, StartPt, -dist * (double) j / (double) quantity); 2611 pSquallPts[j].x = ptTemp.x; 2612 //calculate the sin value along the x axis 2613 pSquallPts[j].y = ptTemp.y + amplitude * sign * Math.sin((double) j * 180 / (double) quantity * Math.PI / 180); 2614 } 2615 } catch (Exception exc) { 2616 ErrorLogger.LogException(_className, "GetSquallShape", 2617 new RendererException("Failed inside GeSquallShape", exc)); 2618 } 2619 } 2620 //caller needs to instantiate sign.value 2621 /** 2622 * Gets the squall curves for a line segment Assumes pSquallPts has been 2623 * allocated the proper number of points. 2624 * 2625 * @param StartPt segment start point 2626 * @param EndPt segment end point 2627 * @param pSquallPts OUT - the squall points 2628 * @param sign OUT - an object with a member to hold the starting curve sign 2629 * for the segment. 2630 * @param amplitude the sin curve amplitutde 2631 * @param quantity the number of points for each sin curve 2632 * @param length the desired length of the curve along the segment for each 2633 * sin curve 2634 * 2635 * @return segment squall points count 2636 */ 2637 protected static int GetSquallSegment(POINT2 StartPt, 2638 POINT2 EndPt, 2639 POINT2[] pSquallPts, 2640 ref<int[]> sign, 2641 double amplitude, 2642 int quantity, 2643 double length) { 2644 int counter = 0; 2645 try { 2646 POINT2 StartCurvePt, EndCurvePt; //use these for the curve points 2647 POINT2[] pSquallPts2 = new POINT2[quantity]; 2648 double dist = CalcDistanceDouble(StartPt, EndPt); 2649 int numCurves = (int) (dist / (double) length); 2650 int j = 0, k = 0; 2651 POINT2 EndPt2 = new POINT2(); 2652 double angle = Math.atan((StartPt.y - EndPt.y) / (StartPt.x - EndPt.x)); 2653 int lAngle = (int) ((180 / Math.PI) * angle); 2654 InitializePOINT2Array(pSquallPts2); 2655 //define EndPt2 to be the point dist from StartPt along the x axis 2656 if (StartPt.x < EndPt.x) { 2657 EndPt2.x = StartPt.x + dist; 2658 } else { 2659 EndPt2.x = StartPt.x - dist; 2660 } 2661 2662 EndPt2.y = StartPt.y; 2663 2664 EndCurvePt = StartPt; 2665 for (j = 0; j < numCurves; j++) { 2666 StartCurvePt = ExtendLineDouble(EndPt2, StartPt, -(double) (j * length)); 2667 EndCurvePt = ExtendLineDouble(EndPt2, StartPt, -(double) ((j + 1) * length)); 2668 2669 //get the curve points 2670 GetSquallCurve(StartCurvePt, EndCurvePt, pSquallPts2, sign.value[0], amplitude, quantity); 2671 2672 //fill the segment points with the curve points 2673 for (k = 0; k < quantity; k++) { 2674 //pSquallPts[counter].x=pSquallPts2[k].x; 2675 //pSquallPts[counter].y=pSquallPts2[k].y; 2676 pSquallPts[counter] = new POINT2(pSquallPts2[k]); 2677 counter++; 2678 } 2679 //reverse the sign 2680 2681 sign.value[0] = -sign.value[0]; 2682 } 2683 if (numCurves == 0) { 2684 pSquallPts[counter] = new POINT2(StartPt); 2685 counter++; 2686 pSquallPts[counter] = new POINT2(EndPt); 2687 counter++; 2688 } 2689 //the points are along the x axis. Rotate them about the first point as the origin 2690 RotateGeometryDoubleOrigin(pSquallPts, counter, lAngle); 2691 pSquallPts2 = null; 2692 } catch (Exception exc) { 2693 ErrorLogger.LogException(_className, "GetSquallSegment", 2694 new RendererException("Failed inside GetSquallSegment", exc)); 2695 } 2696 return counter; 2697 } 2698 2699 //temporarily using 2000 pixels 2700 private static int PointInBounds(POINT2 pt) { 2701 try { 2702 //double maxPixels=CELineArrayGlobals.MaxPixels2; 2703 double maxPixels = 100000;//was 2000 2704 if (Math.abs(pt.x) <= maxPixels && Math.abs(pt.y) <= maxPixels) { 2705 return 1; 2706 } else { 2707 return 0; 2708 } 2709 } catch (Exception exc) { 2710 ErrorLogger.LogException(_className, "PointInBounds", 2711 new RendererException("Failed inside PointInBounds", exc)); 2712 } 2713 return 1; 2714 } 2715 2716 /** 2717 * @param pt 2718 * @param ul 2719 * @param lr 2720 * @return 2721 */ 2722 private static int PointInBounds2(POINT2 pt, POINT2 ul, POINT2 lr) { 2723 try { 2724 double maxX = lr.x, minX = ul.x, maxY = lr.y, minY = ul.y; 2725 if (pt.x <= maxX && pt.x >= minX && pt.y <= maxY && pt.y >= minY) { 2726 return 1; 2727 } else { 2728 return 0; 2729 } 2730 } catch (Exception exc) { 2731 ErrorLogger.LogException(_className, "PointInBounds2", 2732 new RendererException("Failed inside PointInBounds2", exc)); 2733 } 2734 return 1; 2735 } 2736 2737 /** 2738 * Analyzes if line from pt0 to pt 1 intersects a side and returns the 2739 * intersection or null assumes pt0 to pt1 is not vertical. the caller will 2740 * replace pt0 with the intersection point if it is not null 2741 * 2742 * @param pt0 2743 * @param pt1 2744 * @param sidePt0 vertical or horizontal side first point 2745 * @param sidePt1 2746 * @return null if it does not intersect the side 2747 */ 2748 private static POINT2 intersectSegment(POINT2 pt0, POINT2 pt1, POINT2 sidePt0, POINT2 sidePt1) { 2749 POINT2 pt = null; 2750 try { 2751 if (pt0.x == pt1.x) { 2752 return null; 2753 } 2754 double m = (pt1.y - pt0.y) / (pt1.x - pt0.x); 2755 double dx = 0, dy = 0, x = 0, y = 0; 2756 POINT2 upper = null, lower = null, left = null, right = null; 2757 Boolean bolVertical = false; 2758 //the side is either vertical or horizontal 2759 if (sidePt0.x == sidePt1.x) //vertical side 2760 { 2761 bolVertical = true; 2762 if (sidePt0.y < sidePt1.y) { 2763 upper = sidePt0; 2764 lower = sidePt1; 2765 } else { 2766 upper = sidePt1; 2767 lower = sidePt0; 2768 } 2769 } else //horizontal side 2770 { 2771 if (sidePt0.x < sidePt1.x) { 2772 left = sidePt0; 2773 right = sidePt1; 2774 } else { 2775 left = sidePt1; 2776 right = sidePt0; 2777 } 2778 } 2779 //travel in the direction from pt0 to pt1 to find the pt0 intersect 2780 if (bolVertical) { //the side to intersect is vertical 2781 dx = upper.x - pt0.x; 2782 dy = m * dx; 2783 x = upper.x; 2784 y = pt0.y + dy; 2785 //the potential intersection point 2786 pt = new POINT2(x, y); 2787 2788 if (pt0.x <= pt.x && pt.x <= pt1.x) //left to right 2789 { 2790 if (upper.y <= pt.y && pt.y <= lower.y) { 2791 return pt; 2792 } 2793 } else if (pt0.x >= pt.x && pt.x >= pt1.x) //right to left 2794 { 2795 if (upper.y <= pt.y && pt.y <= lower.y) { 2796 return pt; 2797 } 2798 } 2799 } else //horizontal side 2800 { 2801 dy = left.y - pt0.y; 2802 dx = dy / m; 2803 x = pt0.x + dx; 2804 y = left.y; 2805 //the potential intersection point 2806 pt = new POINT2(x, y); 2807 2808 if (pt0.y <= pt.y && pt.y <= pt1.y) { 2809 if (left.x <= pt.x && pt.x <= right.x) { 2810 return pt; 2811 } 2812 } else if (pt0.y >= pt.y && pt.y >= pt1.y) { 2813 if (left.x <= pt.x && pt.x <= right.x) { 2814 return pt; 2815 } 2816 } 2817 } 2818 } catch (Exception exc) { 2819 ErrorLogger.LogException(_className, "intersectSegment", 2820 new RendererException("Failed inside intersectSegment", exc)); 2821 } 2822 return null; 2823 } 2824 2825 /** 2826 * side 1 ----- | | side 0 | | side 2 | | ------ side 3 bounds one segment 2827 * for autoshapes that need it: bydif, fordif, fix, mnfldfix if null is 2828 * returned the client should conect the original line points (i.e. no 2829 * jaggies) 2830 * 2831 * @param pt0 2832 * @param pt1 2833 * @param ul 2834 * @param lr 2835 * @return bounded segment or null 2836 */ 2837 public static POINT2[] BoundOneSegment(POINT2 pt0, POINT2 pt1, POINT2 ul, POINT2 lr) { 2838 POINT2[] line = new POINT2[2]; 2839 try { 2840 if (pt0.y < ul.y && pt1.y < ul.y) { 2841 return null; 2842 } 2843 if (pt0.y > lr.y && pt1.y > lr.y) { 2844 return null; 2845 } 2846 if (pt0.x < ul.x && pt1.x < ul.x) { 2847 return null; 2848 } 2849 if (pt0.x > lr.x && pt1.x > lr.x) { 2850 return null; 2851 } 2852 2853 Boolean bolVertical = false; 2854 InitializePOINT2Array(line); 2855 if (pt0.x == pt1.x) { 2856 bolVertical = true; 2857 } 2858 2859 if (bolVertical) { 2860 line[0] = new POINT2(pt0); 2861 if (line[0].y < ul.y) { 2862 line[0].y = ul.y; 2863 } 2864 if (line[0].y > lr.y) { 2865 line[0].y = lr.y; 2866 } 2867 2868 line[1] = new POINT2(pt1); 2869 if (line[1].y < ul.y) { 2870 line[1].y = ul.y; 2871 } 2872 if (line[1].y > lr.y) { 2873 line[1].y = lr.y; 2874 } 2875 2876 return line; 2877 } 2878 2879 double dx = 0, dy = 0, x = 0, y = 0; 2880 double m = (pt1.y - pt0.y) / (pt1.x - pt0.x); 2881 Boolean side0Intersect = false, 2882 side1Intersect = false, 2883 side2Intersect = false, 2884 side3Intersect = false; 2885 //travel in the direction from pt0 to pt1 to find pt0 intersect 2886 POINT2 ur = new POINT2(lr.x, ul.y); 2887 POINT2 ll = new POINT2(ul.x, lr.y); 2888 2889 POINT2 pt0Intersect = null; 2890 if (PointInBounds2(pt0, ul, lr) == 1) { 2891 pt0Intersect = pt0; 2892 } 2893 if (pt0Intersect == null) { 2894 pt0Intersect = intersectSegment(pt0, pt1, ll, ul); //interesect side 0 2895 side0Intersect = true; 2896 } 2897 if (pt0Intersect == null) { 2898 pt0Intersect = intersectSegment(pt0, pt1, ul, ur); //interesect side 1 2899 side1Intersect = true; 2900 } 2901 if (pt0Intersect == null) { 2902 pt0Intersect = intersectSegment(pt0, pt1, ur, lr); //interesect side 2 2903 side2Intersect = true; 2904 } 2905 if (pt0Intersect == null) { 2906 pt0Intersect = intersectSegment(pt0, pt1, ll, lr); //interesect side 3 2907 side3Intersect = true; 2908 } 2909 2910 //travel in the direction from pt1 to pt0 to find pt1 intersect 2911 POINT2 pt1Intersect = null; 2912 if (PointInBounds2(pt1, ul, lr) == 1) { 2913 pt1Intersect = pt1; 2914 } 2915 if (pt1Intersect == null && side0Intersect == false) { 2916 pt1Intersect = intersectSegment(pt1, pt0, ll, ul); //interesect side 0 2917 } 2918 if (pt1Intersect == null && side1Intersect == false) { 2919 pt1Intersect = intersectSegment(pt1, pt0, ul, ur); //interesect side 1 2920 } 2921 if (pt1Intersect == null && side2Intersect == false) { 2922 pt1Intersect = intersectSegment(pt1, pt0, ur, lr); //interesect side 2 2923 } 2924 if (pt1Intersect == null && side3Intersect == false) { 2925 pt1Intersect = intersectSegment(pt1, pt0, ll, lr); //interesect side 3 2926 } 2927 2928 if (pt0Intersect != null && pt1Intersect != null) { 2929 line[0] = pt0Intersect; 2930 line[1] = pt1Intersect; 2931 //return line; 2932 } else { 2933 line = null; 2934 } 2935 } catch (Exception exc) { 2936 ErrorLogger.LogException(_className, "BoundOneSegment", 2937 new RendererException("Failed inside BoundOneSegment", exc)); 2938 } 2939 return line; 2940 } 2941 2942 private static int DisplayIntersectPixels(POINT2 pt0, 2943 POINT2 pt1, 2944 ref<double[]> pt2x, 2945 ref<double[]> pt2y, 2946 ref<double[]> pt3x, 2947 ref<double[]> pt3y) //POINT2 ul, 2948 //POINT2 lr) 2949 { 2950 int nResult = -1; 2951 try { 2952 //declarations 2953 double X = 0, Y = 0; 2954 ref<double[]> m = new ref(); 2955 //double maxPixels=CELineArrayGlobals.MaxPixels2; 2956 double maxPixels = 2000; 2957 //double maxX=lr.x,minX=ul.x,maxY=lr.y,minY=ul.y; 2958 2959 int bol0Inside = 0, bol1Inside = 0; 2960 int bolVertical = CalcTrueSlopeDouble(pt0, pt1, m); 2961 double b = pt0.y - m.value[0] * pt0.x; //the y intercept for the segment line 2962 POINT2 pt2, pt3; 2963 //end declarations 2964 2965 pt2x.value = new double[1]; 2966 pt2y.value = new double[1]; 2967 pt3x.value = new double[1]; 2968 pt3y.value = new double[1]; 2969 pt2 = new POINT2(pt0); 2970 pt3 = new POINT2(pt1); 2971 2972 //diagnostic 2973 if (pt0.x <= maxPixels && pt0.x >= -maxPixels 2974 && pt0.y <= maxPixels && pt0.y >= -maxPixels) { 2975 bol0Inside = 1; 2976 } 2977 if (pt1.x <= maxPixels && pt1.x >= -maxPixels 2978 && pt1.y <= maxPixels && pt1.y >= -maxPixels) { 2979 bol1Inside = 1; 2980 } 2981 //if both points are inside the area then use the whole segment 2982 if (bol0Inside == 1 && bol1Inside == 1) { 2983 return 0; 2984 } 2985 //if at leat one of the points is inside the area then use some of the segment 2986 if (bol0Inside == 1 || bol1Inside == 1) { 2987 nResult = 1; 2988 } 2989 2990 //segment is not vertical 2991 if (bolVertical != 0) { 2992 //analysis for side 0, get the intersection for either point if it exists 2993 //diagnostic 2994 X = -maxPixels; 2995 //X=minX; 2996 2997 Y = m.value[0] * X + b; 2998 if (pt0.x < -maxPixels && -maxPixels < pt1.x) //pt0 is outside the area 2999 { 3000 if (-maxPixels <= Y && Y <= maxPixels) //intersection is on side 0 3001 //if(minY<=Y && Y<=maxY) //intersection is on side 0 3002 { 3003 pt2.x = X; 3004 pt2.y = Y; 3005 nResult = 1; //use at least some of the pixels 3006 } 3007 } 3008 if (pt1.x < -maxPixels && -maxPixels < pt0.x) //pt1 is outside the area 3009 //if(pt1.x<minX && minX<pt0.x) //pt1 is outside the area 3010 { 3011 if (-maxPixels <= Y && Y <= maxPixels) //intersection is on side 0 3012 { 3013 pt3.x = X; 3014 pt3.y = Y; 3015 nResult = 1; //use at least some of the pixels 3016 } 3017 } 3018 3019 //analysis for side 1, get the intersection for either point if it exists 3020 Y = -maxPixels; 3021 if (m.value[0] != 0) { 3022 X = (Y - b) / m.value[0]; 3023 if (pt0.y < -maxPixels && -maxPixels < pt1.y) //pt0 is outside the area 3024 { 3025 if (-maxPixels <= X && X <= maxPixels) //intersection is on side 1 3026 { 3027 pt2.x = X; 3028 pt2.y = Y; 3029 nResult = 1; //use at least some of the pixels 3030 } 3031 } 3032 if (pt1.y <= -maxPixels && -maxPixels <= pt0.y) //pt1 is outside the area 3033 { 3034 if (-maxPixels < X && X < maxPixels) //intersection is on the boundary 3035 { 3036 pt3.x = X; 3037 pt3.y = Y; 3038 nResult = 1; //use at least some of the pixels 3039 } 3040 } 3041 } 3042 //analysis for side 2, get the intersection for either point if it exists 3043 X = maxPixels; 3044 Y = m.value[0] * X + b; 3045 if (pt0.x < maxPixels && maxPixels < pt1.x) //pt1 is outside the area 3046 { 3047 if (-maxPixels <= Y && Y <= maxPixels) //intersection is on the boundary 3048 { 3049 pt3.x = X; 3050 pt3.y = Y; 3051 nResult = 1; //use at least some of the pixels 3052 } 3053 } 3054 if (pt1.x < maxPixels && maxPixels < pt0.x) //pt0 is outside the area 3055 { 3056 if (-maxPixels <= Y && Y <= maxPixels) //intersection is on the boundary 3057 { 3058 pt2.x = X; 3059 pt2.y = Y; 3060 nResult = 1; //use at least some of the pixels 3061 } 3062 } 3063 3064 //analysis for side 3, get the intersection for either point if it exists 3065 Y = maxPixels; 3066 if (m.value[0] != 0) { 3067 X = (Y - b) / m.value[0]; 3068 if (pt0.y < maxPixels && maxPixels < pt1.y) //pt1 is outside the area 3069 { 3070 if (-maxPixels <= X && X <= maxPixels) //intersection is on the boundary 3071 { 3072 pt3.x = X; 3073 pt3.y = Y; 3074 nResult = 1; //use at least some of the pixels 3075 } 3076 } 3077 if (pt1.y < maxPixels && maxPixels < pt0.y) //pt0 is outside the area 3078 { 3079 if (-maxPixels <= X && X <= maxPixels) //intersection is on the boundary 3080 { 3081 pt2.x = X; 3082 pt2.y = Y; 3083 nResult = 1; //use at least some of the pixels 3084 } 3085 } 3086 } 3087 } 3088 3089 //segment is vertical 3090 if (bolVertical == 0) { 3091 //analysis for side 1 3092 X = pt0.x; 3093 Y = -maxPixels; 3094 if (-maxPixels < pt0.x && pt0.x < maxPixels) { 3095 if (pt0.y <= -maxPixels && -maxPixels <= pt1.y) //pt0 outside the area 3096 { 3097 pt2.x = X; 3098 pt2.y = Y; 3099 nResult = 1; //use at least some of the pixels 3100 } 3101 if (pt1.y <= -maxPixels && -maxPixels <= pt0.y) //pt1 outside the area 3102 { 3103 pt3.x = X; 3104 pt3.y = Y; 3105 nResult = 1; //use at least some of the pixels 3106 } 3107 } 3108 3109 //analysis for side 3 3110 X = pt0.x; 3111 Y = maxPixels; 3112 if (-maxPixels < pt0.x && pt0.x < maxPixels) { 3113 if (pt0.y <= maxPixels && maxPixels <= pt1.y) //pt1 outside the area 3114 { 3115 pt3.x = X; 3116 pt3.y = Y; 3117 nResult = 1; //use at least some of the pixels 3118 } 3119 if (pt1.y <= maxPixels && maxPixels <= pt0.y) //pt0 outside the area 3120 { 3121 pt2.x = X; 3122 pt2.y = Y; 3123 nResult = 1; //use at least some of the pixels 3124 } 3125 } 3126 } 3127 3128 pt2x.value[0] = pt2.x; 3129 pt2y.value[0] = pt2.y; 3130 pt3x.value[0] = pt3.x; 3131 pt3y.value[0] = pt3.y; 3132 } catch (Exception exc) { 3133 ErrorLogger.LogException(_className, "DisplayIntersectPixels", 3134 new RendererException("Failed inside DisplayIntersectPixels", exc)); 3135 } 3136 return nResult; 3137 } 3138 /** 3139 * Computes Ditch spikes for the ATDITCH line types. This function uses 3140 * linestyles provided by the caller to skip segments. 3141 * 3142 * @param pLinePoints OUT - the client points also used for the return 3143 * points 3144 * @param nOldCounter the number of client points 3145 * @param bWayIs the parallel line to use (0) for inner or outer spikes 3146 * @param linetype the line type 3147 * 3148 * @return the symbol point count 3149 */ 3150 protected static int GetDitchSpikeDouble(TGLight tg, POINT2[] pLinePoints, 3151 int nOldCounter, 3152 int bWayIs) { 3153 int nSpikeCounter = 0; 3154 try { 3155 //declarations 3156 int linetype = tg.get_LineType(); 3157 int nNumberOfSegments = 0, 3158 lCircleCounter = 0, 3159 bolVertical = 0, 3160 nTemp = 0, 3161 i, 3162 j; 3163 double dPrinter = 1.0; 3164 double dIntLocation1x = 0, 3165 dIntLocation2x = 0, 3166 dIntLocation1y = 0, 3167 dIntLocation2y = 0, 3168 r = 0, 3169 s = 0, 3170 use = 0, 3171 length = 0, 3172 k = 0, 3173 bint = 0; 3174 ref<double[]> pdAnswer = new ref();//new double[6]; 3175 ref<double[]> m = new ref(); 3176 3177 POINT2 UpperLinePoint = new POINT2(pLinePoints[0]), 3178 Lower1LinePoint = new POINT2(pLinePoints[0]), 3179 Lower2LinePoint = new POINT2(pLinePoints[0]), 3180 a = new POINT2(pLinePoints[0]), 3181 b = new POINT2(pLinePoints[0]); 3182 POINT2[] pCirclePoints = new POINT2[pLinePoints.length]; 3183 POINT2 averagePoint = new POINT2(); 3184 POINT2 lastAveragePoint = new POINT2(); 3185 POINT2[] pTempLinePoints = null; 3186 //end declarations 3187 3188 pTempLinePoints = new POINT2[nOldCounter]; 3189 for (j = 0; j < nOldCounter; j++) { 3190 pTempLinePoints[j] = new POINT2(pLinePoints[j]); 3191 } 3192 3193 ArrayList<POINT2> basePoints = new ArrayList(); 3194 3195 InitializePOINT2Array(pCirclePoints); 3196 nSpikeCounter = nOldCounter; 3197 double spikeLength = arraysupport.getScaledSize(12, tg.get_LineThickness()); 3198 double spikeHeight = spikeLength * 1.25; 3199 double minLength = 2 * spikeLength; 3200 for (i = 0; i < nOldCounter - 1; i++) { 3201 if (linetype == TacticalLines.ATDITCHM && i == 0) { 3202 double radius = arraysupport.getScaledSize(4, tg.get_LineThickness()); 3203 minLength = spikeLength * 2.5 + radius * 2; 3204 } 3205 3206 nTemp = CalcTrueLinesDouble((long) (spikeHeight * dPrinter), pLinePoints[i], pLinePoints[i + 1], pdAnswer); 3207 r = pdAnswer.value[3]; 3208 s = pdAnswer.value[5]; 3209 length = CalcDistanceDouble(pLinePoints[i], pLinePoints[i + 1]); 3210 bolVertical = CalcTrueSlopeDouble(pLinePoints[i], pLinePoints[i + 1], m); 3211 nNumberOfSegments = (int) ((length - 1) / (spikeLength * dPrinter)); 3212 3213 if (length > minLength * dPrinter) { //minLength was 24 3214 if (bWayIs != 0) { 3215 if (pLinePoints[i].x <= pLinePoints[i + 1].x) { 3216 use = r; 3217 } 3218 if (pLinePoints[i].x >= pLinePoints[i + 1].x) { 3219 use = s; 3220 } 3221 } //end if 3222 else { 3223 if (pLinePoints[i].x <= pLinePoints[i + 1].x) { 3224 use = s; 3225 } 3226 if (pLinePoints[i].x >= pLinePoints[i + 1].x) { 3227 use = r; 3228 } 3229 } //end else 3230 3231 for (j = 1; j <= nNumberOfSegments; j++) { 3232 k = (double) j; 3233 a = new POINT2(pLinePoints[i]); 3234 b = new POINT2(pLinePoints[i + 1]); 3235 3236 if (j > 1) { 3237 dIntLocation1x = dIntLocation2x; 3238 } else { 3239 dIntLocation1x 3240 = (double) pLinePoints[i].x + ((k * spikeLength - spikeLength) * dPrinter / length) 3241 * (double) (pLinePoints[i + 1].x - pLinePoints[i].x); 3242 } 3243 3244 if (j > 1) //added M. Deutch 2-23-99 3245 { 3246 dIntLocation1y = dIntLocation2y; 3247 } else { 3248 dIntLocation1y 3249 = (double) pLinePoints[i].y + ((k * spikeLength - spikeLength / 2) * dPrinter / length) 3250 * (double) (pLinePoints[i + 1].y - pLinePoints[i].y); 3251 } 3252 3253 dIntLocation2x = (double) pLinePoints[i].x 3254 + ((k * spikeLength + spikeLength / 2) * dPrinter / length) 3255 * (double) (pLinePoints[i + 1].x 3256 - pLinePoints[i].x); 3257 3258 dIntLocation2y = (double) pLinePoints[i].y 3259 + ((k * spikeLength + spikeLength / 2) * dPrinter / length) 3260 * (double) (pLinePoints[i + 1].y 3261 - pLinePoints[i].y); 3262 3263 if (m.value[0] != 0 && bolVertical != 0) { 3264 bint = (dIntLocation1y + dIntLocation2y) / 2.0 3265 + (1 / m.value[0]) * (dIntLocation1x + dIntLocation2x) / 2.0; 3266 //independent of direction 3267 UpperLinePoint = CalcTrueIntersectDouble2(m.value[0], use, -1 / m.value[0], bint, 1, 1, pLinePoints[0].x, pLinePoints[0].y); 3268 } 3269 3270 if (bolVertical == 0) //vertical segment 3271 { 3272 if (dIntLocation1y < dIntLocation2y) { 3273 UpperLinePoint.y = (int) dIntLocation1y + (int) (length / nNumberOfSegments / 2); 3274 } else { 3275 UpperLinePoint.y = (int) dIntLocation1y - (int) (length / nNumberOfSegments / 2); 3276 } 3277 if (pLinePoints[i].y < pLinePoints[i + 1].y) { 3278 UpperLinePoint.x = (int) dIntLocation1x + (int) (length / nNumberOfSegments); 3279 } else { 3280 UpperLinePoint.x = (int) dIntLocation1x - (int) (length / nNumberOfSegments); 3281 } 3282 } 3283 if (m.value[0] == 0 && bolVertical != 0) { 3284 if (dIntLocation1x < dIntLocation2x) { 3285 UpperLinePoint.x = (int) dIntLocation1x + (int) (length / nNumberOfSegments / 2); 3286 } else { 3287 UpperLinePoint.x = (int) dIntLocation1x - (int) (length / nNumberOfSegments / 2); 3288 } 3289 if (pLinePoints[i + 1].x < pLinePoints[i].x) { 3290 UpperLinePoint.y = (int) dIntLocation1y + (int) (length / nNumberOfSegments); 3291 } else { 3292 UpperLinePoint.y = (int) dIntLocation1y - (int) (length / nNumberOfSegments); 3293 } 3294 } 3295 //end section 3296 3297 Lower1LinePoint.x = dIntLocation1x; 3298 Lower1LinePoint.y = dIntLocation1y; 3299 Lower2LinePoint.x = dIntLocation2x; 3300 Lower2LinePoint.y = dIntLocation2y; 3301 3302 pLinePoints[nSpikeCounter] = new POINT2(Lower1LinePoint); 3303 if (linetype == TacticalLines.ATDITCHC || linetype == TacticalLines.ATDITCHM) { 3304 pLinePoints[nSpikeCounter].style = 9; 3305 } 3306 if (j % 2 == 1 && linetype == TacticalLines.ATDITCHM)//diagnostic 1-8-13 3307 { 3308 pLinePoints[nSpikeCounter].style = 5; 3309 } 3310 3311 nSpikeCounter++; 3312 3313 pLinePoints[nSpikeCounter] = new POINT2(UpperLinePoint); 3314 if (linetype == (long) TacticalLines.ATDITCHC || linetype == (long) TacticalLines.ATDITCHM) { 3315 pLinePoints[nSpikeCounter].style = 9; 3316 } 3317 if (j % 2 == 1 && linetype == TacticalLines.ATDITCHM)//diagnostic 1-8-13 3318 { 3319 pLinePoints[nSpikeCounter].style = 5; 3320 } 3321 3322 nSpikeCounter++; 3323 3324 pLinePoints[nSpikeCounter] = new POINT2(Lower2LinePoint); 3325 if (linetype == (long) TacticalLines.ATDITCHC || linetype == (long) TacticalLines.ATDITCHM) { 3326 pLinePoints[nSpikeCounter].style = 10; 3327 } 3328 if (j % 2 == 1 && linetype == TacticalLines.ATDITCHM)//diagnostic 1-8-13 3329 { 3330 pLinePoints[nSpikeCounter].style = 5; 3331 } 3332 3333 nSpikeCounter++; 3334 3335 if (linetype == TacticalLines.ATDITCHM) { 3336 if (j % 2 == 0) { 3337 averagePoint = lineutility.MidPointDouble(Lower1LinePoint, Lower2LinePoint, 0); 3338 averagePoint = lineutility.MidPointDouble(averagePoint, UpperLinePoint, 0); 3339 } else if (j == 1) { 3340 averagePoint = lineutility.ExtendLineDouble(Lower2LinePoint, Lower1LinePoint, 5); 3341 averagePoint = lineutility.MidPointDouble(averagePoint, UpperLinePoint, 0); 3342 } 3343 } 3344 //end section 3345 if (j > 1 && j < nNumberOfSegments) { 3346 basePoints.add(new POINT2(Lower1LinePoint)); 3347 //if(j==nNumberOfSegments-1) 3348 // basePoints.get(basePoints.size()-1).style=5; 3349 } else if (j == 1) { 3350 basePoints.add(new POINT2(pLinePoints[i])); 3351 } else if (j == nNumberOfSegments) { 3352 basePoints.add(new POINT2(pLinePoints[i + 1])); 3353 basePoints.get(basePoints.size() - 1).style = 5; 3354 } 3355 if (linetype == TacticalLines.ATDITCHM && j > 1) { 3356 if (j % 2 == 0) { 3357 pCirclePoints[lCircleCounter] = lineutility.MidPointDouble(averagePoint, lastAveragePoint, 20); 3358 lCircleCounter++; 3359 } 3360 //end section 3361 } 3362 if (j < nNumberOfSegments && linetype == TacticalLines.ATDITCHM) { 3363 if (j == 1 || j % 2 == 0) { 3364 //LastUpperLinePoint = new POINT2(UpperLinePoint); 3365 lastAveragePoint = new POINT2(averagePoint); 3366 } 3367 //end section 3368 } 3369 }//end for j<numberOfsegments 3370 } //end if length big enough 3371 else { 3372 //diagnostic 3373 pLinePoints[nSpikeCounter].x = pLinePoints[i].x; 3374 pLinePoints[nSpikeCounter].y = pLinePoints[i].y; 3375 pLinePoints[nSpikeCounter].style = 0; 3376 nSpikeCounter++; 3377 pLinePoints[nSpikeCounter].x = pLinePoints[i + 1].x; 3378 pLinePoints[nSpikeCounter].y = pLinePoints[i + 1].y; 3379 pLinePoints[nSpikeCounter].style = 5; 3380 nSpikeCounter++; 3381 } 3382 } 3383 3384 for (j = 0; j < nOldCounter; j++) //reverse the first nOldCounter points for 3385 { 3386 pLinePoints[j] = new POINT2(pTempLinePoints[nOldCounter - j - 1]); //purpose of drawing 3387 pLinePoints[j].style = 5; 3388 } 3389 3390 if (pLinePoints[nSpikeCounter - 1].style == 0) { 3391 pLinePoints[nSpikeCounter - 1].style = 5; 3392 } 3393 int t=basePoints.size(); 3394 //for (j = nSpikeCounter; j < nSpikeCounter + basePoints.size(); j++) 3395 for (j = nSpikeCounter; j < nSpikeCounter + t; j++) 3396 { 3397 pLinePoints[j] = new POINT2(basePoints.get(j - nSpikeCounter)); 3398 //if(linetype == TacticalLines.ATDITCHM && pLinePoints[j].style != 5) 3399 if (pLinePoints[j].style != 5) { 3400 pLinePoints[j].style = 0; 3401 } 3402 } 3403 nSpikeCounter += basePoints.size(); 3404 3405 if (linetype == (int) TacticalLines.ATDITCHM) { 3406 pLinePoints[nSpikeCounter - 1].style = 5;//was 10 3407 for (j = nSpikeCounter; j < nSpikeCounter + lCircleCounter; j++) { 3408 pLinePoints[j] = new POINT2(pCirclePoints[j - nSpikeCounter]); 3409 pLinePoints[j].style = 20; 3410 } 3411 nSpikeCounter += lCircleCounter; 3412 } 3413 3414 } catch (Exception exc) { 3415 ErrorLogger.LogException(_className, "GetDitchSpikeDouble", 3416 new RendererException("Failed inside GetDitchSpikeDouble", exc)); 3417 } 3418 return nSpikeCounter; 3419 } 3420 3421 /** 3422 * Moves pixels if points are identical, used for the channel types 3423 * 3424 * @param pLinePoints OUT - client points also for returned points 3425 */ 3426 protected static void MoveChannelPixels(POINT2[] pLinePoints) { 3427 try { 3428 if (pLinePoints == null || pLinePoints.length <= 0) { 3429 return; 3430 } 3431 3432 double[] pixels = new double[pLinePoints.length * 2]; 3433 boolean bolNoRepeats; 3434 int j, k = 0; 3435 double x1; 3436 double y1; 3437 double x2; 3438 double y2; 3439 int count = pLinePoints.length; 3440 //stuff pixels 3441 for (j = 0; j < count; j++) { 3442 pixels[k++] = pLinePoints[j].x; 3443 pixels[k++] = pLinePoints[j].y; 3444 } 3445 3446 bolNoRepeats = false; 3447 do { 3448 bolNoRepeats = true; 3449 for (j = 0; j < count - 1; j++) { 3450 x1 = pixels[2 * j]; 3451 y1 = pixels[2 * j + 1]; 3452 x2 = pixels[2 * j + 2]; 3453 y2 = pixels[2 * j + 3]; 3454 if (x1 == x2 && y1 == y2) //it's the same point 3455 { 3456 bolNoRepeats = false; 3457 pixels[2 * j + 2] = (long) x2 + 1; //move the point 3458 break; 3459 } 3460 } 3461 } while (bolNoRepeats == false); 3462 //stuff pLinePoints 3463 k = 0; 3464 for (j = 0; j < count; j++) { 3465 pLinePoints[j].x = pixels[k++]; 3466 pLinePoints[j].y = pixels[k++]; 3467 } 3468 } catch (Exception exc) { 3469 ErrorLogger.LogException(_className, "MoveChannelPixels", 3470 new RendererException("Failed inside MoveChannelPixels", exc)); 3471 } 3472 } 3473 3474 /** 3475 * Single Concertina cannot have horizontal first segment 3476 * 3477 * @param linetype 3478 * @param pLinePoints 3479 */ 3480 protected static void moveSingleCPixels(int linetype, POINT2[] pLinePoints) { 3481 try { 3482 switch (linetype) { 3483 case TacticalLines.SINGLEC: 3484 break; 3485 default: 3486 return; 3487 } 3488 if (pLinePoints.length > 1) { 3489 if (pLinePoints[1].y == pLinePoints[0].y) { 3490 pLinePoints[1].y++; 3491 } 3492 } 3493 } catch (Exception exc) { 3494 ErrorLogger.LogException(_className, "MoveSingleCPixels", 3495 new RendererException("Failed inside MoveSingleCPixels", exc)); 3496 } 3497 } 3498 3499 /** 3500 * Rotates an the first vblCounter points in the array about its first point 3501 * 3502 * @param pLinePoints OUT - the points to rotate 3503 * @param vblCounter the number of points to rotate 3504 * @param lAngle the angle in degrees to rotate 3505 */ 3506 protected static void RotateGeometryDouble(POINT2[] pLinePoints, 3507 int vblCounter, 3508 double lAngle) { 3509 try { 3510 int j = 0; 3511 double dRotate = 0, 3512 dTheta = 0, 3513 dGamma = 0, 3514 x = 0, 3515 y = 0; 3516 3517 if (lAngle != 0) //if the angle is 0 no rotation occurs 3518 { 3519 POINT2 pdCenter; 3520 dRotate = lAngle * Math.PI / 180d; 3521 pdCenter = CalcCenterPointDouble(pLinePoints, vblCounter); 3522 3523 for (j = 0; j < vblCounter; j++) { 3524 //added if/else to get rid of divide by zero error 5/12/04 M. Deutch 3525 if (pLinePoints[j].x == pdCenter.x) { 3526 if ((pLinePoints[j].y > pdCenter.y)) { 3527 dGamma = Math.PI + Math.PI / 2; 3528 } else { 3529 dGamma = Math.PI / 2; 3530 } 3531 } else { 3532 dGamma = Math.PI + Math.atan((pLinePoints[j].y - pdCenter.y) 3533 / (pLinePoints[j].x - pdCenter.x)); 3534 } 3535 3536 if ((double) pLinePoints[j].x >= pdCenter.x) { 3537 dGamma = dGamma + Math.PI; 3538 } 3539 3540 dTheta = dRotate + dGamma; 3541 y = CalcDistanceDouble(pLinePoints[j], pdCenter) * Math.sin(dTheta); 3542 x = CalcDistanceDouble(pLinePoints[j], pdCenter) * Math.cos(dTheta); 3543 pLinePoints[j].y = pdCenter.y + y; 3544 pLinePoints[j].x = pdCenter.x + x; 3545 } //end for 3546 3547 return; 3548 } //end if 3549 } catch (Exception exc) { 3550 ErrorLogger.LogException(_className, "RotateGeometryDouble", 3551 new RendererException("Failed inside RotateGeometryDouble", exc)); 3552 } 3553 } // end 3554 3555 /** 3556 * Returns the point perpendicular to the line (pt0 to pt1) at the midpoint 3557 * the same distance from (and on the same side of) the the line as 3558 * ptRelative. 3559 * 3560 * @param pt0 the first point 3561 * @param pt1 the second point 3562 * @param ptRelative the point to use for computing the return point 3563 * 3564 * @return the point perpendicular to the line at the midpoint 3565 */ 3566 protected static POINT2 PointRelativeToLine(POINT2 pt0, 3567 POINT2 pt1, 3568 POINT2 ptRelative) { 3569 POINT2 ptResult = new POINT2(pt0); 3570 try { 3571 int bolVertical = 0; 3572 ref<double[]> m = new ref(); 3573 POINT2 midPt = MidPointDouble(pt0, pt1, 0); 3574 double b1 = 0, b2 = 0; 3575 //end declarations 3576 3577 bolVertical = CalcTrueSlopeDouble(pt0, pt1, m); 3578 if (bolVertical == 0) //line is vertical 3579 { 3580 ptResult.x = ptRelative.x; 3581 ptResult.y = midPt.y; 3582 } 3583 if (bolVertical != 0 && m.value[0] == 0) { 3584 ptResult.x = midPt.x; 3585 ptResult.y = ptRelative.y; 3586 } 3587 if (bolVertical != 0 && m.value[0] != 0) { 3588 b1 = midPt.y + (1 / m.value[0]) * midPt.x; //the line perp to midPt 3589 b2 = ptRelative.y - m.value[0] * ptRelative.x; //the line ptRelative with the slope of pt1-pt2 3590 ptResult = CalcTrueIntersectDouble2(-1 / m.value[0], b1, m.value[0], b2, 1, 1, 0, 0); 3591 } 3592 } catch (Exception exc) { 3593 ErrorLogger.LogException(_className, "PointRelativeToLine", 3594 new RendererException("Failed inside PointRelativeToLine", exc)); 3595 } 3596 return ptResult; 3597 } 3598 3599 /** 3600 * shift the control point to match the shift that occurs in 3601 * Channels.GetAXADDouble for CATKBYFIRE. This is because the rotary feature 3602 * arrow tip must align with the anchor point 3603 * 3604 * @param linetype 3605 * @param pLinePoints the anchor points including the control point 3606 * @param dist the minimum required distance from the front of the rotary 3607 * arrow 3608 */ 3609 public static void adjustCATKBYFIREControlPoint(int linetype, 3610 ArrayList<POINT2> pLinePoints, 3611 double dist) { 3612 try { 3613 if (linetype != TacticalLines.CATKBYFIRE) { 3614 return; 3615 } 3616 3617 double dist2 = lineutility.CalcDistanceDouble(pLinePoints.get(0), pLinePoints.get(1)); 3618 if (dist2 <= dist) { 3619 return; 3620 } 3621 3622 POINT2 pt = null; 3623 int count = pLinePoints.size(); 3624 POINT2 pt0 = new POINT2(pLinePoints.get(0)); 3625 POINT2 pt1 = new POINT2(pLinePoints.get(1)); 3626 POINT2 controlPt = new POINT2(pLinePoints.get(count - 1)); 3627 POINT2 pt4 = PointRelativeToLine(pt0, pt1, pt1, controlPt); 3628 pt = lineutility.ExtendLineDouble(pt4, controlPt, dist); 3629 pLinePoints.set(count - 1, pt); 3630 } catch (Exception exc) { 3631 ErrorLogger.LogException(_className, "adjustCATKBYFIREControlPoint", 3632 new RendererException("Failed inside adjustCATKBYFIREControlPoint", exc)); 3633 } 3634 } 3635 3636 /** 3637 * Returns the point perpendicular to the line (pt0 to pt1) at atPoint the 3638 * same distance from (and on the same side of) the the line as ptRelative. 3639 * 3640 * @param pt0 the first point 3641 * @param pt1 the second point 3642 * @param atPoint the point on the line at which to compute the extended 3643 * point 3644 * @param ptRelative the point to use for computing the return point 3645 * 3646 * @return the point perpendicular to the line at ptRelative 3647 */ 3648 public static POINT2 PointRelativeToLine(POINT2 pt0, 3649 POINT2 pt1, 3650 POINT2 atPoint, 3651 POINT2 ptRelative) { 3652 POINT2 ptResult = new POINT2(pt0); 3653 try { 3654 int bolVertical = 0; 3655 ref<double[]> m = new ref(); 3656 double b1 = 0, b2 = 0; 3657 3658 bolVertical = CalcTrueSlopeDouble(pt0, pt1, m); 3659 if (bolVertical == 0) //line is vertical 3660 { 3661 ptResult.x = ptRelative.x; 3662 ptResult.y = atPoint.y; 3663 } 3664 if (bolVertical != 0 && m.value[0] == 0) { 3665 ptResult.x = atPoint.x; 3666 ptResult.y = ptRelative.y; 3667 } 3668 if (bolVertical != 0 && m.value[0] != 0) { 3669 b1 = atPoint.y + (1 / m.value[0]) * atPoint.x; //the line perp to midPt 3670 b2 = ptRelative.y - m.value[0] * ptRelative.x; //the line ptRelative with the slope of pt1-pt2 3671 ptResult = CalcTrueIntersectDouble2(-1 / m.value[0], b1, m.value[0], b2, 1, 1, 0, 0); 3672 } 3673 } catch (Exception exc) { 3674 ErrorLogger.LogException(_className, "PointRelativeToLine", 3675 new RendererException("Failed inside PointRelativeToLine", exc)); 3676 } 3677 return ptResult; 3678 } 3679 3680 /** 3681 * Returns in pt2 and pt3 the line segment parallel to segment pt0-pt1 which 3682 * would contain ptRelative. pt2 corresponds to pt0 and pt3 corresponds to 3683 * pt1. 3684 * 3685 * @param pt0 first line point 3686 * @param pt1 second line point 3687 * @param ptRelative relative line point 3688 * @param pt2 OUT - first computed relative line point 3689 * @param pt3 OUT - second computed relative line point 3690 */ 3691 public static void LineRelativeToLine(POINT2 pt0, 3692 POINT2 pt1, 3693 POINT2 ptRelative, 3694 POINT2 pt2, 3695 POINT2 pt3) { 3696 try { 3697 int bolVertical = 0; 3698 ref<double[]> m = new ref(); 3699 double b1 = 0, b2 = 0; 3700 POINT2 pt2Temp = null; 3701 POINT2 pt3Temp = null; 3702 3703 bolVertical = CalcTrueSlopeDouble(pt0, pt1, m); 3704 if (bolVertical == 0) //line is vertical 3705 { 3706 pt2.x = ptRelative.x; 3707 pt2.y = pt0.y; 3708 pt3.x = ptRelative.x; 3709 pt3.y = pt1.y; 3710 } 3711 if (bolVertical != 0 && m.value[0] == 0) //line is horizontal 3712 { 3713 pt2.x = pt0.x; 3714 pt2.y = ptRelative.y; 3715 pt3.x = pt1.x; 3716 pt3.y = ptRelative.y; 3717 } 3718 if (bolVertical != 0 && m.value[0] != 0) { 3719 b1 = pt0.y + (1 / m.value[0]) * pt0.x; //the line perp to pt0 3720 b2 = ptRelative.y - m.value[0] * ptRelative.x; //the line the ptRelative with the slope of pt0-pt1 3721 pt2Temp = CalcTrueIntersectDouble2(-1 / m.value[0], b1, m.value[0], b2, 1, 1, 0, 0); 3722 3723 b1 = pt1.y + (1 / m.value[0]) * pt1.x; //the line perp to pt1 3724 //b2=ptRelative.y-m*ptRelative.x; //the line the ptRelative with the slope of pt0-pt1 3725 pt3Temp = CalcTrueIntersectDouble2(-1 / m.value[0], b1, m.value[0], b2, 1, 1, 0, 0); 3726 3727 pt2.x = pt2Temp.x; 3728 pt2.y = pt2Temp.y; 3729 pt3.x = pt3Temp.x; 3730 pt3.y = pt3Temp.y; 3731 } 3732 } catch (Exception exc) { 3733 ErrorLogger.LogException(_className, "LineRelativeToLine", 3734 new RendererException("Failed inside LineRelativeToLine", exc)); 3735 } 3736 } 3737 3738 private static void CalcMBR(POINT2[] pLinePoints, 3739 int numpts, 3740 ref<double[]> ulx, 3741 ref<double[]> uly, 3742 ref<double[]> lrx, 3743 ref<double[]> lry) { 3744 try { 3745 int j = 0; 3746 //initialize the MBR 3747 ulx.value = new double[1]; 3748 uly.value = new double[1]; 3749 lrx.value = new double[1]; 3750 lry.value = new double[1]; 3751 ulx.value[0] = Double.MAX_VALUE;//was 99999 3752 uly.value[0] = Double.MAX_VALUE;//was 99999 3753 lrx.value[0] = -Double.MAX_VALUE;//was -99999 3754 lry.value[0] = -Double.MAX_VALUE;//was -99999 3755 for (j = 0; j < numpts; j++) { 3756 if (pLinePoints[j].x > lrx.value[0]) { 3757 lrx.value[0] = pLinePoints[j].x; 3758 } 3759 if (pLinePoints[j].y > lry.value[0]) { 3760 lry.value[0] = pLinePoints[j].y; 3761 } 3762 if (pLinePoints[j].x < ulx.value[0]) { 3763 ulx.value[0] = pLinePoints[j].x; 3764 } 3765 if (pLinePoints[j].y < uly.value[0]) { 3766 uly.value[0] = pLinePoints[j].y; 3767 } 3768 } 3769 } catch (Exception exc) { 3770 ErrorLogger.LogException(_className, "CalcMBR", 3771 new RendererException("Failed inside CalcMBR", exc)); 3772 } 3773 return; 3774 } 3775 3776 public static void CalcMBRPoints(POINT2[] pLinePoints, 3777 int numpts, 3778 POINT2 ul, 3779 POINT2 lr) { 3780 try { 3781 int j = 0; 3782 ul.x = Double.MAX_VALUE; 3783 ul.y = Double.MAX_VALUE; 3784 lr.x = -Double.MAX_VALUE; 3785 lr.y = -Double.MAX_VALUE; 3786 for (j = 0; j < numpts; j++) { 3787 if (pLinePoints[j].x > lr.x) { 3788 lr.x = pLinePoints[j].x; 3789 } 3790 if (pLinePoints[j].y > lr.y) { 3791 lr.y = pLinePoints[j].y; 3792 } 3793 if (pLinePoints[j].x < ul.x) { 3794 ul.x = pLinePoints[j].x; 3795 } 3796 if (pLinePoints[j].y < ul.y) { 3797 ul.y = pLinePoints[j].y; 3798 } 3799 } 3800 } catch (Exception exc) { 3801 ErrorLogger.LogException(_className, "CalcMBRPoints", 3802 new RendererException("Failed inside CalcMBRPoints", exc)); 3803 } 3804 } 3805 3806 /** 3807 * Computes the distance in pixels from upper left to lower right of the 3808 * minimum bounding rectangle for the first numpts of pLinePoints 3809 * 3810 * @param pLinePoints the inpupt point array 3811 * @param numpts the number of points to use 3812 * 3813 * @return the distance in pixels 3814 */ 3815 protected static double MBRDistance(POINT2[] pLinePoints, 3816 int numpts) { 3817 double result = 0; 3818 try { 3819 ref<double[]> ulx = new ref(), uly = new ref(), lrx = new ref(), lry = new ref(); 3820 CalcMBR(pLinePoints, numpts, ulx, uly, lrx, lry); 3821 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])); 3822 //sanity check 3823 3824 //return x or y distance if returnValue is 0 or infinity 3825 double xdist = Math.abs(lrx.value[0] - ulx.value[0]); 3826 double ydist = Math.abs(lry.value[0] - uly.value[0]); 3827 double max = xdist; 3828 if (ydist > xdist) { 3829 max = ydist; 3830 } 3831 3832 if (result == 0 || Double.isInfinite(result)) { 3833 if (max > 0) { 3834 result = max; 3835 } 3836 } 3837 3838 } catch (Exception exc) { 3839 ErrorLogger.LogException(_className, "MBRDistance", 3840 new RendererException("Failed inside MBRDistance", exc)); 3841 } 3842 return result; 3843 } 3844 3845 /** 3846 * Swaps two points. 3847 * 3848 * @param pt1 OUT - first point 3849 * @param pt2 OUT - second point 3850 * 3851 */ 3852 protected static void Reverse2Points(POINT2 pt1, POINT2 pt2) { 3853 try { 3854 POINT2 tempPt = new POINT2(); 3855 //store pt1 3856 tempPt.x = pt1.x; 3857 tempPt.y = pt1.y; 3858 pt1.x = pt2.x; 3859 pt1.y = pt2.y; 3860 pt2.x = tempPt.x; 3861 pt2.y = tempPt.y; 3862 } catch (Exception exc) { 3863 ErrorLogger.LogException(_className, "Reverse2Points", 3864 new RendererException("Failed inside Reverse2Points", exc)); 3865 } 3866 } 3867 /** 3868 * Creates a GeneralPath from a Path2D 3869 * 3870 * @param shape 3871 * @return 3872 */ 3873 public static Shape createStrokedShape(Shape shape) { 3874 GeneralPath newshape = new GeneralPath(); // Start with an empty shape 3875 try { 3876 // Iterate through the specified shape, perturb its coordinates, and 3877 // use them to build up the new shape. 3878 double[] coords = new double[6]; 3879 for (PathIterator i = shape.getPathIterator(null); !i.isDone(); i.next()) { 3880 int type = i.currentSegment(coords); 3881 switch (type) { 3882 case PathIterator.SEG_MOVETO: 3883 //perturb(coords, 2); 3884 newshape.moveTo(coords[0], coords[1]); 3885 break; 3886 case PathIterator.SEG_LINETO: 3887 //perturb(coords, 2); 3888 newshape.lineTo(coords[0], coords[1]); 3889 break; 3890 case PathIterator.SEG_QUADTO: 3891 //perturb(coords, 4); 3892 newshape.quadTo(coords[0], coords[1], coords[2], coords[3]); 3893 break; 3894 case PathIterator.SEG_CUBICTO: 3895 //perturb(coords, 6); 3896 newshape.curveTo(coords[0], coords[1], coords[2], coords[3], 3897 coords[4], coords[5]); 3898 break; 3899 case PathIterator.SEG_CLOSE: 3900 newshape.closePath(); 3901 break; 3902 } 3903 3904 } 3905 } catch (Exception exc) { 3906 ErrorLogger.LogException(_className, "createStrokedShape", 3907 new RendererException("Failed inside createStrokedShape", exc)); 3908 } 3909 return newshape; 3910 } 3911 //These functions were added to create a minimum bounding polygon 3912 /** 3913 * @deprecated Returns the determinant of the point matrix This determinant 3914 * tells how far p3 is from vector p1p2 and on which side it is 3915 * @param p1 3916 * @param p2 3917 * @param p3 3918 * @return 3919 */ 3920 static private int distance(Point p1, Point p2, Point p3) { 3921 try { 3922 int x1 = p1.x; 3923 int x2 = p2.x; 3924 int x3 = p3.x; 3925 int y1 = p1.y; 3926 int y2 = p2.y; 3927 int y3 = p3.y; 3928 return x1 * y2 + x3 * y1 + x2 * y3 - x3 * y2 - x2 * y1 - x1 * y3; 3929 } catch (Exception exc) { 3930 ErrorLogger.LogException(_className, "distance", 3931 new RendererException("Failed inside distance", exc)); 3932 } 3933 return 0; 3934 } 3935 3936 /** 3937 * @deprecated Returns the determinant of the point matrix This determinant 3938 * tells how far p3 is from vector p1p2 and on which side it is 3939 * @param p1 3940 * @param p2 3941 * @param p3 3942 * @return 3943 */ 3944 static private double distance2(POINT2 p1, POINT2 p2, POINT2 p3) { 3945 try { 3946 double x1 = p1.x; 3947 double x2 = p2.x; 3948 double x3 = p3.x; 3949 double y1 = p1.y; 3950 double y2 = p2.y; 3951 double y3 = p3.y; 3952 return x1 * y2 + x3 * y1 + x2 * y3 - x3 * y2 - x2 * y1 - x1 * y3; 3953 } catch (Exception exc) { 3954 ErrorLogger.LogException(_className, "distance2", 3955 new RendererException("Failed inside distance2", exc)); 3956 } 3957 return 0; 3958 } 3959 3960 /** 3961 * @deprecated @param points 3962 * @param l 3963 * @param r 3964 * @param path 3965 */ 3966 static private void cHull(ArrayList<Point> points, Point l, Point r, ArrayList<Point> path) { 3967 3968 if (points.size() < 3) { 3969 return; 3970 } 3971 3972 int maxDist = 0; 3973 int tmp; 3974 Point p = null; 3975 3976 for (Point pt : points) { 3977 if (pt != l && pt != r) { 3978 tmp = distance(l, r, pt); 3979 3980 if (tmp > maxDist) { 3981 maxDist = tmp; 3982 p = pt; 3983 } 3984 } 3985 } 3986 3987 ArrayList<Point> left = new ArrayList<Point>(); 3988 ArrayList<Point> right = new ArrayList<Point>(); 3989 left.add(l); 3990 right.add(p); 3991 3992 for (Point pt : points) { 3993 if (distance(l, p, pt) > 0) { 3994 left.add(pt); 3995 } else if (distance(p, r, pt) > 0) { 3996 right.add(pt); 3997 } 3998 } 3999 4000 left.add(p); 4001 right.add(r); 4002 cHull(left, l, p, path); 4003 path.add(p); 4004 cHull(right, p, r, path); 4005 } 4006 4007 /** 4008 * @deprecated @param points 4009 * @param l 4010 * @param r 4011 * @param path 4012 */ 4013 static private void cHull2(ArrayList<POINT2> points, POINT2 l, POINT2 r, ArrayList<POINT2> path) { 4014 4015 if (points.size() < 3) { 4016 return; 4017 } 4018 4019 double maxDist = 0; 4020 double tmp; 4021 POINT2 p = null; 4022 4023 for (POINT2 pt : points) { 4024 if (pt != l && pt != r) { 4025 tmp = distance2(l, r, pt); 4026 4027 if (tmp > maxDist) { 4028 maxDist = tmp; 4029 p = pt; 4030 } 4031 } 4032 } 4033 4034 ArrayList<POINT2> left = new ArrayList<POINT2>(); 4035 ArrayList<POINT2> right = new ArrayList<POINT2>(); 4036 left.add(l); 4037 right.add(p); 4038 4039 for (POINT2 pt : points) { 4040 if (distance2(l, p, pt) > 0) { 4041 left.add(pt); 4042 } else if (distance2(p, r, pt) > 0) { 4043 right.add(pt); 4044 } 4045 } 4046 4047 left.add(p); 4048 right.add(r); 4049 cHull2(left, l, p, path); 4050 path.add(p); 4051 cHull2(right, p, r, path); 4052 } 4053 //Returns the points of convex hull in the correct order 4054 /** 4055 * @deprecated @param array 4056 * @return 4057 */ 4058 static public ArrayList<Point> cHull(ArrayList<Point> array) { 4059 int size = array.size(); 4060 if (size < 2) { 4061 return null; 4062 } 4063 4064 Point l = array.get(0); 4065 Point r = array.get(size - 1); 4066 ArrayList<Point> path = new ArrayList<Point>(); 4067 path.add(l); 4068 cHull(array, l, r, path); 4069 path.add(r); 4070 cHull(array, r, l, path); 4071 return path; 4072 } 4073 4074 /** 4075 * @deprecated @param array 4076 * @return 4077 */ 4078 static public ArrayList<POINT2> cHull2(ArrayList<POINT2> array) { 4079 try { 4080 int size = array.size(); 4081 if (size < 2) { 4082 return null; 4083 } 4084 4085 POINT2 l = array.get(0); 4086 POINT2 r = array.get(size - 1); 4087 ArrayList<POINT2> path = new ArrayList<POINT2>(); 4088 path.add(l); 4089 cHull2(array, l, r, path); 4090 path.add(r); 4091 cHull2(array, r, l, path); 4092 return path; 4093 } catch (Exception exc) { 4094 ErrorLogger.LogException(_className, "cHull2", 4095 new RendererException("Failed inside cHull2", exc)); 4096 } 4097 return null; 4098 } 4099 4100 public static void getExteriorPoints(POINT2[] pLinePoints, 4101 int vblCounter, 4102 int lineType, 4103 boolean interior 4104 ) { 4105 int j; 4106 int index; 4107 POINT2 pt0, pt1, pt2; 4108 ref<double[]> m01 = new ref(), m12 = new ref(); 4109 int direction; 4110 POINT2 intersectPt; 4111 //ref<double[]> m1 = new ref(), m2 = new ref(); 4112 ArrayList<POINT2> intersectPoints = new ArrayList(); 4113 double b01, b12; //the y intercepts for the lines corresponding to m1,m2 4114 double dist = pLinePoints[0].style; 4115 for (j = 0; j < vblCounter; j++) { 4116 if (j == 0 || j == vblCounter - 1) { 4117 pt0 = new POINT2(pLinePoints[vblCounter - 2]); 4118 pt1 = new POINT2(pLinePoints[0]); 4119 pt2 = new POINT2(pLinePoints[1]); 4120 } else { 4121 pt0 = new POINT2(pLinePoints[j - 1]); 4122 pt1 = new POINT2(pLinePoints[j]); 4123 pt2 = new POINT2(pLinePoints[j + 1]); 4124 } 4125 if (pt1.style > 0) { 4126 dist = pt1.style; 4127 } 4128 //the exterior/interior points 4129 POINT2 pt00, pt01, pt10, pt11; 4130 4131 index = j - 1; 4132 if (index < 0) { 4133 index = vblCounter - 1; 4134 } 4135 POINT2[] pts = new POINT2[pLinePoints.length]; 4136 int n=pLinePoints.length; 4137 //for (int k = 0; k < pLinePoints.length; k++) 4138 for (int k = 0; k < n; k++) 4139 { 4140 pts[k] = pLinePoints[k]; 4141 } 4142 4143 direction = arraysupport.GetInsideOutsideDouble2(pt0, pt1, pts, vblCounter, index, lineType); 4144 //reverse the direction if these are interior points 4145 if (interior == true) { 4146 switch (direction) { 4147 case 0: 4148 direction = 1; 4149 break; 4150 case 1: 4151 direction = 0; 4152 break; 4153 case 2: 4154 direction = 3; 4155 break; 4156 case 3: 4157 direction = 2; 4158 break; 4159 default: 4160 break; 4161 } 4162 } 4163 //pt00-pt01 will be the interior line inside line pt0-pt1 4164 //pt00 is inside pt0, pt01 is inside pt1 4165 pt00 = lineutility.ExtendDirectedLine(pt0, pt1, pt0, direction, dist); 4166 pt01 = lineutility.ExtendDirectedLine(pt0, pt1, pt1, direction, dist); 4167 4168 //pt10-pt11 will be the interior line inside line pt1-pt2 4169 //pt10 is inside pt1, pt11 is inside pt2 4170 index = j; 4171 if (j == vblCounter - 1) { 4172 index = 0; 4173 } 4174 direction = arraysupport.GetInsideOutsideDouble2(pt1, pt2, (POINT2[]) pts, vblCounter, index, lineType); 4175 //reverse the direction if these are interior points 4176 if (interior == true) { 4177 switch (direction) { 4178 case 0: 4179 direction = 1; 4180 break; 4181 case 1: 4182 direction = 0; 4183 break; 4184 case 2: 4185 direction = 3; 4186 break; 4187 case 3: 4188 direction = 2; 4189 break; 4190 default: 4191 break; 4192 } 4193 } 4194 pt10 = lineutility.ExtendDirectedLine(pt1, pt2, pt1, direction, dist); 4195 pt11 = lineutility.ExtendDirectedLine(pt1, pt2, pt2, direction, dist); 4196 //intersectPt=new POINT2(null); 4197 //get the intersection of pt01-p00 and pt10-pt11 4198 //so it it is the interior intersection of pt0-pt1 and pt1-pt2 4199 4200 //first handle the case of vertical lines. 4201 if (pt0.x == pt1.x && pt1.x == pt2.x) { 4202 intersectPt = new POINT2(pt01); 4203 intersectPoints.add(intersectPt); 4204 continue; 4205 } 4206 //it's the same situation if the slopes are identical, 4207 //simply use pt01 or pt10 since they already uniquely define the intesection 4208 lineutility.CalcTrueSlopeDouble2(pt00, pt01, m01); 4209 lineutility.CalcTrueSlopeDouble2(pt10, pt11, m12); 4210 //if(m01.dbl==m12.dbl) 4211 if (m01.value[0] == m12.value[0]) { 4212 intersectPt = new POINT2(pt01); 4213 intersectPoints.add(intersectPt); 4214 continue; 4215 } 4216 //now we are assuming a non-trivial intersection 4217 //calculate the y-intercepts using y=mx+b (use b=y-mx) 4218 b01 = pt01.y - m01.value[0] * pt01.x; 4219 b12 = pt11.y - m12.value[0] * pt11.x; 4220 intersectPt = lineutility.CalcTrueIntersectDouble2(m01.value[0], b01, m12.value[0], b12, 1, 1, 0, 0); 4221 intersectPoints.add(intersectPt); 4222 }//end for 4223 int n=intersectPoints.size(); 4224 //for (j = 0; j < intersectPoints.size(); j++) 4225 for (j = 0; j < n; j++) 4226 { 4227 pLinePoints[j] = intersectPoints.get(j); 4228 } 4229 } 4230 public static ArrayList<POINT2> getDeepCopy(ArrayList<POINT2>pts) 4231 { 4232 ArrayList<POINT2>deepCopy=null; 4233 try 4234 { 4235 if(pts == null || pts.isEmpty()) 4236 return pts; 4237 deepCopy=new ArrayList(); 4238 int j=0; 4239 POINT2 pt=null; 4240 for(j=0;j<pts.size();j++) 4241 { 4242 pt=new POINT2(pts.get(j).x,pts.get(j).y,pts.get(j).style); 4243 deepCopy.add(pt); 4244 } 4245 } 4246 catch (Exception exc) { 4247 ErrorLogger.LogException(_className, "getDeepCopy", 4248 new RendererException("Failed inside getDeepCopy", exc)); 4249 } 4250 return deepCopy; 4251 } 4252 4253}//end lineutility