001/* 002 * To change this template, choose Tools | Templates 003 * and open the template in the editor. 004 */ 005package armyc2.c5isr.RenderMultipoints; 006 007import armyc2.c5isr.JavaTacticalRenderer.clsUtility; 008import armyc2.c5isr.JavaTacticalRenderer.TGLight; 009import java.util.ArrayList; 010import armyc2.c5isr.renderer.utilities.ErrorLogger; 011import armyc2.c5isr.renderer.utilities.RendererException; 012import armyc2.c5isr.JavaLineArray.POINT2; 013import armyc2.c5isr.JavaLineArray.TacticalLines; 014import armyc2.c5isr.JavaLineArray.Shape2; 015import java.util.HashMap; 016import java.util.Map; 017import armyc2.c5isr.graphics2d.*; 018import armyc2.c5isr.graphics2d.Line2D; 019import armyc2.c5isr.graphics2d.Point2D; 020import armyc2.c5isr.graphics2d.Rectangle2D; 021 022/** 023 * A class to clip tactical lines and areas 024* 025 */ 026public final class clsClipPolygon2 { 027 028 private static final String _className = "clsClipPolygon2"; 029 /** 030 * Calculate the point the line intersects an edge of the clipbounds 031 * @param pt0 start point of the line 032 * @param pt1 end point of the line 033 * @param currentEdge 034 * @return 035 */ 036 private static Point2D intersectPoint(Point2D pt0, 037 Point2D pt1, 038 Line2D currentEdge) { 039 Point2D ptIntersect = null; 040 try { 041 Point2D edgePt1 = currentEdge.getP1(); 042 Point2D edgePt2 = currentEdge.getP2(); 043 double edge_x = 0, edge_y = 0, m = 0; 044 double deltaX = 0, deltaY = 0; 045 //vertical edge 046 if (Math.abs(edgePt1.getX() - edgePt2.getX()) < Math.abs(edgePt1.getY() - edgePt2.getY())) 047 { 048 ptIntersect=new Point2D.Double(); 049 edge_x = edgePt1.getX(); 050 //if (pt1.getX() == pt0.getX()) 051 if (Math.abs(pt1.getX() - pt0.getX())<1) 052 pt1.setLocation(pt1.getX()+1, pt1.getY()); 053 054 m = (pt1.getY() - pt0.getY()) / (pt1.getX() - pt0.getX()); 055 deltaX = edge_x - pt0.getX(); 056 ptIntersect.setLocation(edge_x, pt0.getY() + m * deltaX); 057 } 058 //horizontal edge 059 else 060 { 061 ptIntersect=new Point2D.Double(); 062 edge_y = edgePt1.getY(); 063 //if (pt1.getX() == pt0.getX()) 064 if (Math.abs(pt1.getX() - pt0.getX())<1) 065 pt1.setLocation(pt1.getX()+1, pt1.getY()); 066 067 m = (pt1.getY() - pt0.getY()) / (pt1.getX() - pt0.getX()); 068 deltaY = edge_y - pt0.getY(); 069 ptIntersect.setLocation(pt0.getX() + deltaY / m, edge_y); 070 } 071 } catch (Exception exc) { 072 ErrorLogger.LogException(_className, "intersectPoint", 073 new RendererException("Failed inside intersectPoint", exc)); 074 } 075 return ptIntersect; 076 } 077 /** 078 * clip the top 079 * on the line is considered inside 080 * @param pts 081 * @param clipBounds 082 * @return 083 */ 084 private static ArrayList<Point2D> clipTop(TGLight tg,ArrayList<Point2D> pts, 085 Rectangle2D clipBounds) { 086 ArrayList<Point2D> ptsResult = new ArrayList(); 087 try { 088 double ulx = 0, uly = 0, lrx = 0;// lry = 0; 089 ulx = clipBounds.getMinX(); 090 uly = clipBounds.getMinY(); 091 Point2D ul = new Point2D.Double(ulx, uly); 092 Point2D ur = new Point2D.Double(lrx, uly); 093 094 int j = 0; 095 Point2D current = null, previous = null; 096 Point2D intersectPt = null; 097 Line2D edge; 098 int n=pts.size(); 099 //for (j = 0; j < pts.size(); j++) 100 for (j = 0; j < n; j++) 101 { 102 current = pts.get(j); 103 if (j == 0) 104 { 105 previous = pts.get(pts.size() - 1); 106 } 107 else 108 { 109 previous = pts.get(j - 1); 110 } 111 112 //both inside 113 if (previous.getY() >= ul.getY() && current.getY() >= ul.getY()) { 114 ptsResult.add(current); 115 } 116 //previous inside, current outside 117 if (previous.getY() >= ul.getY() && current.getY() < ul.getY()) { 118 edge = new Line2D.Double(ul, ur); 119 intersectPt = intersectPoint(previous, current, edge); 120 if (intersectPt != null) { 121 ptsResult.add(intersectPt); 122 } 123 tg.set_WasClipped(true); 124 } 125 //both outside 126 if (previous.getY() < ul.getY() && current.getY() < ul.getY()) { 127 continue; 128 } 129 130 //previous outside current inside 131 if (previous.getY() < ul.getY() && current.getY() >= ul.getY()) { 132 edge = new Line2D.Double(ul, ur); 133 intersectPt = intersectPoint(previous, current, edge); 134 if (intersectPt != null) { 135 ptsResult.add(intersectPt); 136 } 137 ptsResult.add(current); 138 tg.set_WasClipped(true); 139 } 140 } 141 } catch (Exception exc) { 142 ErrorLogger.LogException(_className, "clipTop", 143 new RendererException("Failed inside clipTop", exc)); 144 } 145 return ptsResult; 146 } 147 /** 148 * on the boundary is considered inside 149 * clip the bottom 150 * @param pts 151 * @param clipBounds 152 * @return 153 */ 154 private static ArrayList<Point2D> clipBottom(TGLight tg, ArrayList<Point2D> pts, 155 Rectangle2D clipBounds) { 156 ArrayList<Point2D> ptsResult = new ArrayList(); 157 try { 158 double ulx = 0, uly = 0, lrx = 0, lry = 0; 159 ulx = clipBounds.getMinX(); 160 lrx = clipBounds.getMaxX(); 161 lry = clipBounds.getMaxY(); 162 Point2D ll = new Point2D.Double(ulx, lry); 163 Point2D lr = new Point2D.Double(lrx, lry); 164 165 int j = 0; 166 Point2D current = null, previous = null; 167 Point2D intersectPt = null; 168 Line2D edge; 169 int n=pts.size(); 170 //for (j = 0; j < pts.size(); j++) 171 for (j = 0; j < n; j++) 172 { 173 current = pts.get(j); 174 if (j == 0) 175 { 176 previous = pts.get(pts.size() - 1); 177 } 178 else 179 { 180 previous = pts.get(j - 1); 181 } 182 183 //both inside 184 if (previous.getY() <= lr.getY() && current.getY() <= lr.getY()) 185 { 186 ptsResult.add(current); 187 } 188 //previous inside, current outside 189 if (previous.getY() <= lr.getY() && current.getY() > lr.getY()) 190 { 191 edge = new Line2D.Double(ll, lr); 192 intersectPt = intersectPoint(previous, current, edge); 193 if (intersectPt != null) 194 { 195 ptsResult.add(intersectPt); 196 } 197 tg.set_WasClipped(true); 198 } 199 //both outside 200 if (previous.getY() > lr.getY() && current.getY() > lr.getY()) 201 { 202 continue; 203 } 204 205 //previous outside current inside 206 if (previous.getY() > lr.getY() && current.getY() <= lr.getY()) { 207 edge = new Line2D.Double(ll, lr); 208 intersectPt = intersectPoint(previous, current, edge); 209 if (intersectPt != null) { 210 ptsResult.add(intersectPt); 211 } 212 213 ptsResult.add(current); 214 tg.set_WasClipped(true); 215 } 216 } 217 } catch (Exception exc) { 218 ErrorLogger.LogException(_className, "clipBottom", 219 new RendererException("Failed inside clipBottom", exc)); 220 } 221 return ptsResult; 222 } 223 /** 224 * on the bounds is considered inside 225 * clip the right side 226 * @param pts 227 * @param clipBounds 228 * @return 229 */ 230 private static ArrayList<Point2D> clipRight(TGLight tg,ArrayList<Point2D> pts, 231 Rectangle2D clipBounds) { 232 ArrayList<Point2D> ptsResult = new ArrayList(); 233 try { 234 double uly = 0, lrx = 0, lry = 0; 235 uly = clipBounds.getMinY(); 236 lrx = clipBounds.getMaxX(); 237 lry = clipBounds.getMaxY(); 238 Point2D ur = new Point2D.Double(lrx, uly); 239 Point2D lr = new Point2D.Double(lrx, lry); 240 int j = 0; 241 Point2D current = null, previous = null; 242 Point2D intersectPt = null; 243 Line2D edge; 244 int n=pts.size(); 245 //for (j = 0; j < pts.size(); j++) 246 for (j = 0; j < n; j++) 247 { 248 current = pts.get(j); 249 if (j == 0) { 250 previous = pts.get(pts.size() - 1); 251 } else { 252 previous = pts.get(j - 1); 253 } 254 255 //both inside 256 if (previous.getX() <= lr.getX() && current.getX() <= lr.getX()) { 257 ptsResult.add(current); 258 } 259 //previous inside, current outside 260 if (previous.getX() <= lr.getX() && current.getX() > lr.getX()) { 261 edge = new Line2D.Double(ur, lr); 262 intersectPt = intersectPoint(previous, current, edge); 263 if (intersectPt != null) { 264 ptsResult.add(intersectPt); 265 } 266 tg.set_WasClipped(true); 267 } 268 //both outside 269 if (previous.getX() > lr.getX() && current.getX() > lr.getX()) { 270 continue; 271 } 272 273 //previous outside current inside 274 if (previous.getX() > lr.getX() && current.getX() <= lr.getX()) { 275 edge = new Line2D.Double(ur, lr); 276 intersectPt = intersectPoint(previous, current, edge); 277 if (intersectPt != null) { 278 ptsResult.add(intersectPt); 279 } 280 281 //if(j!=0 || clsUtility.isClosedPolygon(tg.get_LineType())==true) 282 ptsResult.add(current); 283 tg.set_WasClipped(true); 284 } 285 } 286 } catch (Exception exc) { 287 ErrorLogger.LogException(_className, "clipRight", 288 new RendererException("Failed inside clipRight", exc)); 289 } 290 return ptsResult; 291 } 292 /** 293 * on the line is considered inside 294 * clip the left side 295 * @param pts 296 * @param clipBounds 297 * @return 298 */ 299 private static ArrayList<Point2D> clipLeft(TGLight tg, ArrayList<Point2D> pts, 300 Rectangle2D clipBounds) { 301 ArrayList<Point2D> ptsResult = new ArrayList(); 302 try { 303 double ulx = 0, uly = 0, lry = 0; 304 ulx = clipBounds.getMinX(); 305 uly = clipBounds.getMinY(); 306 lry = clipBounds.getMaxY(); 307 Point2D ul = new Point2D.Double(ulx, uly); 308 Point2D ll = new Point2D.Double(ulx, lry); 309 310 int j = 0; 311 Point2D current = null, previous = null; 312 Point2D intersectPt = null; 313 Line2D edge; 314 int n=pts.size(); 315 //for (j = 0; j < pts.size(); j++) 316 for (j = 0; j < n; j++) 317 { 318 current = pts.get(j); 319 if (j == 0) 320 { 321 previous = pts.get(pts.size() - 1); 322 } 323 else 324 { 325 previous = pts.get(j - 1); 326 } 327 328 //both inside 329 if (previous.getX() >= ll.getX() && current.getX() >= ll.getX()) { 330 ptsResult.add(current); 331 } 332 //previous inside, current outside 333 if (previous.getX() >= ll.getX() && current.getX() < ll.getX()) { 334 edge = new Line2D.Double(ul, ll); 335 intersectPt = intersectPoint(previous, current, edge); 336 if (intersectPt != null) { 337 ptsResult.add(intersectPt); 338 } 339 tg.set_WasClipped(true); 340 } 341 //both outside 342 if (previous.getX() < ll.getX() && current.getX() < ll.getX()) { 343 continue; 344 } 345 346 //previous outside current inside 347 if (previous.getX() < ll.getX() && current.getX() >= ll.getX()) { 348 edge = new Line2D.Double(ul, ll); 349 intersectPt = intersectPoint(previous, current, edge); 350 if (intersectPt != null) { 351 ptsResult.add(intersectPt); 352 } 353 354 //if(j!=0 || clsUtility.isClosedPolygon(tg.get_LineType())==true) 355 ptsResult.add(current); 356 tg.set_WasClipped(true); 357 } 358 } 359 } catch (Exception exc) { 360 ErrorLogger.LogException(_className, "clipLeft", 361 new RendererException("Failed inside clipLeft", exc)); 362 } 363 return ptsResult; 364 } 365 366 /** 367 * for non-areas add points to the ends as necessary to make the algorithm work 368 * @param polygon 369 * @param clipBounds 370 */ 371 private static int AddBoundaryPointsForLines(ArrayList<Point2D> polygon, 372 Rectangle2D clipBounds) { 373 int result = 0; 374 try { 375 double ulx = 0, uly = 0, lrx = 0, lry = 0; 376 ulx = clipBounds.getMinX(); 377 uly = clipBounds.getMinY(); 378 lrx = clipBounds.getMaxX(); 379 lry = clipBounds.getMaxY(); 380 //move these inside by 10 pixels so the algoithm will treat them as inside points 381 Point2D ul = new Point2D.Double(ulx + 10, uly + 10); 382 Point2D ur = new Point2D.Double(lrx - 10, uly + 10); 383 Point2D ll = new Point2D.Double(ulx + 10, lry - 10); 384 Point2D lr = new Point2D.Double(lrx - 10, lry - 10); 385 386 Point2D pt0 = polygon.get(0); 387 Point2D ptn = polygon.get(polygon.size() - 1); 388 //double dist0 = 0, dist1 = 0; 389 Boolean addToFront = false, addToEnd = false; 390 //add a point to the begining of the array 391 if (pt0.getY() < uly) //above the top clip 392 { 393 polygon.add(0, ul); 394 addToFront = true; 395 } else if (pt0.getX() < ulx) //outside the left clip 396 { 397 polygon.add(0, ul); 398 addToFront = true; 399 } else if (pt0.getX() > lrx) //outside the right clip 400 { 401 polygon.add(0, lr); 402 addToFront = true; 403 } else if (pt0.getY() > lry) //below the bottom clip 404 { 405 polygon.add(0, lr); 406 addToFront = true; 407 } 408 409 //add a point to the end of the array 410 if (ptn.getY() < uly) //above the top clip 411 { 412 polygon.add(ul); 413 addToEnd = true; 414 } else if (ptn.getX() < ulx) //outside the left clip 415 { 416 polygon.add(ul); 417 addToEnd = true; 418 } else if (ptn.getX() > lrx) //outside the right clip 419 { 420 polygon.add(lr); 421 addToEnd = true; 422 } else if (ptn.getY() > lry) //below the bottom clip 423 { 424 polygon.add(lr); 425 addToEnd = true; 426 } 427 428 if (addToFront == false && addToEnd == false) { 429 result = 0; 430 } 431 if (addToFront == true && addToEnd == false) { 432 result = 1; 433 } 434 if (addToFront == false && addToEnd == true) { 435 result = 2; 436 } 437 if (addToFront == true && addToEnd == true) { 438 result = 3; 439 } 440 441 } catch (Exception exc) { 442 ErrorLogger.LogException(_className, "AddBoundaryPointsForLines", 443 new RendererException("Failed inside AddBoundaryPointsForLines", exc)); 444 } 445 return result; 446 } 447 /** 448 * closes an area 449 * @param tg 450 */ 451 private static void closeAreaTG(TGLight tg) 452 { 453 try 454 { 455 if(tg.Pixels==null || tg.Pixels.isEmpty()) 456 return; 457 458 POINT2 pt0=tg.Pixels.get(0); 459 POINT2 ptn=tg.Pixels.get(tg.Pixels.size()-1); 460 if(pt0.x != ptn.x || pt0.y != ptn.y) 461 tg.Pixels.add(pt0); 462 463 } 464 catch (Exception exc) { 465 ErrorLogger.LogException(_className, "closeAreaTG", 466 new RendererException("Failed inside closeAreaTG", exc)); 467 } 468 } 469 /** 470 * DMA, DMAF fill must be handled separately because of the feint 471 * @param tg 472 * @param clipBounds 473 * @return 474 */ 475 protected static ArrayList<Shape2> fillDMA(TGLight tg, 476 Rectangle2D clipBounds) 477 { 478 ArrayList<Shape2>shapes=new ArrayList(); 479 try 480 { 481 switch(tg.get_LineType()) 482 { 483 case TacticalLines.OBSFAREA: 484 case TacticalLines.OBSAREA: 485 case TacticalLines.STRONG: 486 case TacticalLines.ZONE: 487 case TacticalLines.FORT_REVD: 488 case TacticalLines.FORT: 489 case TacticalLines.ENCIRCLE: 490 case TacticalLines.ATDITCHC: 491 case TacticalLines.ATDITCHM: 492 break; 493 default: 494 return shapes; 495 } 496 Shape2 shape=null; 497 498 //create a generic area tg from the pixels and clip it 499 int j=0; 500 TGLight tg2=new TGLight(); 501 tg2.set_LineType(TacticalLines.GENERAL); 502 tg2.Pixels=new ArrayList(); 503 //to get the original pixels size 504 //int n=0; 505 int n=tg.Pixels.size(); 506 507 for(j=0;j<n;j++) 508 tg2.Pixels.add(tg.Pixels.get(j)); 509 510 closeAreaTG(tg2); 511 512 if(clipBounds != null) 513 ClipPolygon(tg2,clipBounds); 514 515 if(tg2.Pixels==null || tg2.Pixels.isEmpty()) 516 return shapes; 517 518 //shape=new Shape2(Shape2.SHAPE_TYPE_POLYLINE); 519 shape=new Shape2(Shape2.SHAPE_TYPE_FILL); 520 shape.setFillColor(tg.get_FillColor()); 521 522 shape.moveTo(tg2.Pixels.get(0)); 523 //original pixels do not include feint 524 n=tg2.Pixels.size(); 525 //for(j=1;j<tg2.Pixels.size();j++) 526 for(j=1;j<n;j++) 527 shape.lineTo(tg2.Pixels.get(j)); 528 529 shapes.add(shape); 530 } 531 catch (Exception exc) { 532 ErrorLogger.LogException(_className, "fillDMA", 533 new RendererException("Failed inside fillDMA", exc)); 534 } 535 return shapes; 536 } 537 /** 538 * for pre-clipped lines which also require fill but need the processed points 539 * to create the fill. This functioni is called after the clip, so the fill 540 * does not get clipped. 541 * @param tg 542 * @param shapes 543 */ 544 protected static void addAbatisFill(TGLight tg, 545 ArrayList<Shape2>shapes) 546 { 547 try 548 { 549 if(tg.Pixels==null || 550 tg.Pixels.size()<2 || 551 tg.get_FillColor()==null || 552 tg.get_FillColor().getAlpha()<2 || 553 shapes==null) 554 return; 555 556 int j=0,n=tg.Pixels.size(); 557 Shape2 shape=null; 558 TGLight tg2=null; 559 switch(tg.get_LineType()) 560 { 561 case TacticalLines.MSDZ: 562 double dist0=0,dist1=0,dist2=0; 563 shape=new Shape2(Shape2.SHAPE_TYPE_POLYLINE); 564 shape.setFillColor(tg.get_FillColor()); 565 if(tg.Pixels != null & tg.Pixels.size()>=300) 566 { 567 dist0=Math.abs(tg.Pixels.get(0).x-tg.Pixels.get(50).x); 568 dist1=Math.abs(tg.Pixels.get(100).x-tg.Pixels.get(150).x); 569 dist2=Math.abs(tg.Pixels.get(200).x-tg.Pixels.get(250).x); 570 int start=-1,end=-1; 571 if(dist0>=dist1 && dist0>=dist2) 572 { 573 start=0; 574 end=99; 575 } 576 else if(dist1>=dist0 && dist1>=dist2) 577 { 578 start=100; 579 end=199; 580 } 581 else 582 { 583 start=200; 584 end=299; 585 } 586 shape.moveTo(tg.Pixels.get(start)); 587 for(j=start;j<=end;j++) 588 shape.lineTo(tg.Pixels.get(j)); 589 590 //shapes.add(0,shape); 591 } 592 break; 593 case TacticalLines.ABATIS: 594 shape=new Shape2(Shape2.SHAPE_TYPE_POLYLINE); 595 shape.setFillColor(tg.get_FillColor()); 596 tg2=new TGLight(); 597 tg2.set_LineType(TacticalLines.GENERAL); 598 tg2.Pixels=new ArrayList(); 599 if(tg.Pixels != null && tg.Pixels.size()>2) 600 { 601 tg2.Pixels.add(tg.Pixels.get(n-3)); 602 tg2.Pixels.add(tg.Pixels.get(n-2)); 603 tg2.Pixels.add(tg.Pixels.get(n-1)); 604 tg2.Pixels.add(tg.Pixels.get(n-3)); 605 606 shape.moveTo(tg2.Pixels.get(0)); 607 for(j=1;j<tg2.Pixels.size();j++) 608 shape.lineTo(tg2.Pixels.get(j)); 609 610 //shapes.add(shape); 611 } 612 break; 613 default: 614 return; 615 }//end switch 616 if(shapes != null) 617 shapes.add(0,shape); 618 } 619 catch (Exception exc) { 620 ErrorLogger.LogException(_className, "addAbatisFill", 621 new RendererException("Failed inside addAbatisFill", exc)); 622 } 623 } 624 /** 625 * for lines with glyphs the fill must be handled (clipped) as a separate shape. 626 * this function needs to be called before the clipping is done to the line 627 * @param tg 628 * @param clipBounds 629 */ 630 protected static ArrayList<Shape2> LinesWithFill(TGLight tg, 631 Rectangle2D clipBounds) 632 { 633 ArrayList<Shape2>shapes=null; 634 try 635 { 636 if(tg.get_FillColor()==null || tg.get_FillColor().getAlpha()<=1 || 637 tg.Pixels==null || tg.Pixels.isEmpty()) 638 return shapes; 639 640 switch(tg.get_LineType()) 641 { 642 case TacticalLines.ABATIS: 643 case TacticalLines.SPT: 644 case TacticalLines.MAIN: 645 case TacticalLines.AAAAA: 646 case TacticalLines.AIRAOA: 647 case TacticalLines.CATK: 648 case TacticalLines.CATKBYFIRE: 649 case TacticalLines.CORDONSEARCH: 650 case TacticalLines.CORDONKNOCK: 651 case TacticalLines.SECURE: 652 case TacticalLines.OCCUPY: 653 case TacticalLines.RETAIN: 654 case TacticalLines.ISOLATE: 655 case TacticalLines.CONVOY: 656 case TacticalLines.HCONVOY: 657 return shapes; 658 case TacticalLines.PAA_RECTANGULAR: 659 case TacticalLines.RECTANGULAR_TARGET: 660 return null; 661 case TacticalLines.OBSFAREA: 662 case TacticalLines.OBSAREA: 663 case TacticalLines.STRONG: 664 case TacticalLines.ZONE: 665 case TacticalLines.FORT_REVD: 666 case TacticalLines.FORT: 667 case TacticalLines.ENCIRCLE: 668 case TacticalLines.ATDITCHC: 669 case TacticalLines.ATDITCHM: 670 return fillDMA(tg,clipBounds); 671 default: 672 break; 673 } 674 if(clsUtility.LinesWithFill(tg.get_LineType())==false) 675 return shapes; 676 677 shapes=new ArrayList(); 678 //undo any fillcolor that might have been set for the existing shape 679 //because we are divorcing fill from the line 680 Shape2 shape=null; 681 682 //create a generic area tg from the pixels and clip it 683 TGLight tg2=new TGLight(); 684 tg2.set_LineType(TacticalLines.GENERAL); 685 tg2.Pixels=new ArrayList(); 686 tg2.Pixels.addAll(tg.Pixels); 687 closeAreaTG(tg2); 688 //tg2.Pixels.add(tg.Pixels.get(0)); 689 if(clipBounds != null) 690 ClipPolygon(tg2,clipBounds); 691 692 693 if(tg2.Pixels==null || tg2.Pixels.isEmpty()) 694 return null; 695 696 int j=0; 697 //shape=new Shape2(Shape2.SHAPE_TYPE_POLYLINE); 698 shape=new Shape2(Shape2.SHAPE_TYPE_FILL); 699 shape.setFillColor(tg.get_FillColor()); 700 701 shape.moveTo(tg2.Pixels.get(0)); 702 for(j=1;j<tg2.Pixels.size();j++) 703 shape.lineTo(tg2.Pixels.get(j)); 704 705 if(tg.get_FillColor() != null || tg.get_FillColor().getAlpha()>1) 706 { 707 shapes.add(shape); 708 } 709 else 710 return null; 711 } 712 catch (Exception exc) { 713 ErrorLogger.LogException(_className, "LinesWithFill", 714 new RendererException("Failed inside LinesWithFill", exc)); 715 } 716 return shapes; 717 } 718 /** 719 * @deprecated 720 * for polygon completely outside the clip area 721 * pass back a small box to be able to continue normal processing 722 * @param clipBounds 723 * @return 724 */ 725 private static ArrayList<Point2D> buildBox(Rectangle2D clipBounds) { 726 ArrayList<Point2D> box = new ArrayList(); 727 try { 728 { 729 double ulx = 0, uly = 0, lrx = 0, lry = 0; 730 ulx = clipBounds.getMinX() - 200; 731 uly = clipBounds.getMinY() - 200; 732 lrx = clipBounds.getMaxX() + 200; 733 lry = clipBounds.getMaxY() + 200; 734 Point2D lr = new Point2D.Double(ulx, uly); 735 Point2D ll = new Point2D.Double(ulx - 10, uly); 736 Point2D ul = new Point2D.Double(ulx - 10, uly - 10); 737 Point2D ur = new Point2D.Double(ulx, uly - 10); 738 box.add(lr); 739 box.add(ll); 740 box.add(ul); 741 box.add(ur); 742 box.add(lr); 743 } 744 } catch (Exception exc) { 745 ErrorLogger.LogException(_className, "buildBox", 746 new RendererException("Failed inside buildBox", exc)); 747 } 748 return box; 749 } 750 /** 751 * Works for tactical lines and areas 752 * @param tg 753 * @param clipBounds 754 * @return 755 */ 756 public static ArrayList<Point2D> ClipPolygon(TGLight tg, 757 Rectangle2D clipBounds) { 758 ArrayList<Point2D> poly = new ArrayList(); 759 try { 760 ArrayList polygon = clsUtilityCPOF.POINT2toPoint2D(tg.Pixels); 761 Boolean isClosed = clsUtility.isClosedPolygon(tg.get_LineType()); 762 //create a hashtable to hold the original points 763 Map<String,Object>hashMap=new HashMap<String,Object>(); 764 int j=0; 765 for(j=0;j<polygon.size();j++) 766 { 767 hashMap.put(Integer.toString(j), polygon.get(j)); 768 } 769 770 Rectangle2D clipBounds2 = new Rectangle2D.Double(clipBounds.getX() - 50, clipBounds.getY() - 50, clipBounds.getWidth() + 100, clipBounds.getHeight() + 100); 771 772 int addedLinePoints = 0; 773 if (isClosed) { 774 polygon.remove(polygon.size() - 1); 775 isClosed = true; 776 } else { 777 //for tactical lines it always seems to work if the 0th and last points are inside the area 778 //add points on the edge as needed to make that happen 779 addedLinePoints = AddBoundaryPointsForLines(polygon, clipBounds2); 780 } 781 //expand the clip bounds by 10 pixels 782 783 poly = clipRight(tg, polygon, clipBounds2); 784 poly = clipTop(tg, poly, clipBounds2); 785 poly = clipLeft(tg, poly, clipBounds2); 786 poly = clipBottom(tg, poly, clipBounds2); 787 788 if (isClosed) 789 { 790 if (poly.size() > 0) 791 { 792 poly.add(poly.get(0)); 793 } 794 } 795 else 796 { 797 switch (addedLinePoints) 798 { 799 case 0: //no points were added, do nothing 800 break; 801 case 1: //point was added to the front to make algorithm work, remove segment 802 if (poly.size() > 0) { 803 poly.remove(0); 804 } 805 if (poly.size() > 0) { 806 poly.remove(0); 807 } 808 break; 809 case 2: //point was added to the end to make algorithm work, remove segment 810 if (poly.size() > 0) { 811 poly.remove(poly.size() - 1); 812 } 813 if (poly.size() > 0) { 814 poly.remove(poly.size() - 1); 815 } 816 break; 817 case 3: //point was added to the front and end to make algorithm work, remove segments 818 if (poly.size() > 0) { 819 poly.remove(0); 820 } 821 if (poly.size() > 0) { 822 poly.remove(0); 823 } 824 if (poly.size() > 0) { 825 poly.remove(poly.size() - 1); 826 } 827 if (poly.size() > 0) { 828 poly.remove(poly.size() - 1); 829 } 830 break; 831 } 832 } 833 834 if (isClosed == true) 835 { 836 if (poly.size() > 2) 837 { 838 //tg.Pixels = clsUtilityCPOF.Point2DtoPOINT2(poly); 839 tg.Pixels = clsUtilityCPOF.Point2DtoPOINT2Mapped(poly,hashMap); 840 } 841 else 842 { 843 //poly = buildBox(clipBounds); 844 //tg.Pixels = clsUtilityCPOF.Point2DtoPOINT2(poly); 845 tg.Pixels=new ArrayList(); 846 } 847 848 } 849 else 850 { 851 if (poly.size() > 1) 852 { 853 tg.Pixels = clsUtilityCPOF.Point2DtoPOINT2Mapped(poly,hashMap); 854 } 855 else 856 { 857 tg.Pixels=new ArrayList(); 858 } 859 } 860 861 } catch (Exception exc) { 862 ErrorLogger.LogException(_className, "ClipPolygon", 863 new RendererException("Failed inside ClipPolygon", exc)); 864 } 865 return poly; 866 } 867}