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.graphics2d.*; 011import armyc2.c5isr.renderer.utilities.ErrorLogger; 012import armyc2.c5isr.renderer.utilities.RendererException; 013import armyc2.c5isr.JavaLineArray.POINT2; 014import armyc2.c5isr.JavaLineArray.TacticalLines; 015import armyc2.c5isr.JavaLineArray.Shape2; 016import armyc2.c5isr.JavaLineArray.lineutility; 017import armyc2.c5isr.graphics2d.Line2D; 018import armyc2.c5isr.graphics2d.Point2D; 019import armyc2.c5isr.graphics2d.Polygon; 020 021import java.util.HashMap; 022import java.util.Map; 023 024/** 025 * Class to clip polygons 026* 027 */ 028public final class clsClipQuad { 029 private static final String _className = "clsClipQuad"; 030 /** 031 * Use the new version which takes an array for polygon clip bounds instead of rectangle 032 * @param polygon 033 * @param clipBounds 034 * @return 035 */ 036 private static int AddBoundaryPointsForLines(ArrayList<Point2D> polygon, 037 ArrayList<Point2D> clipBounds) 038 { 039 int result=0; 040 try 041 { 042 Point2D pt02d=polygon.get(0); 043 Point2D ptLast2d=polygon.get((polygon.size()-1)); 044 POINT2 pt0=new POINT2(pt02d.getX(),pt02d.getY()); 045 POINT2 ptLast=new POINT2(ptLast2d.getX(),ptLast2d.getY()); 046 Point2D nearestPt=new Point2D.Double(); 047 Polygon clipArray=new Polygon(); 048 int j=0; 049 double minDist=Double.MAX_VALUE; 050 double dist=0; 051 POINT2 sidePt=new POINT2(); 052 Boolean addToFront = false, addToEnd = false; 053 //int n=clipBounds.size(); 054 //for(j=0;j<clipBounds.size();j++) 055 for(j=0;j<clipBounds.size();j++) //was n 056 { 057 clipArray.addPoint((int)clipBounds.get(j).getX(), (int)clipBounds.get(j).getY()); 058 } 059 060 double totalX=0,totalY=0; 061 int counter=0; 062 //for(j=0;j<clipBounds.size()-1;j++) 063 for(j=0;j<clipBounds.size()-1;j++) //was n-1 064 { 065 totalX+=clipBounds.get(j).getX(); 066 totalY+=clipBounds.get(j).getY(); 067 counter++; 068 } 069 //if clipBounds is not closed add the jth point 070 if( clipBounds.get(0).getX()!=clipBounds.get(j).getX() || 071 clipBounds.get(0).getY()!=clipBounds.get(j).getY() ) 072 { 073 totalX+=clipBounds.get(j).getX(); 074 totalY+=clipBounds.get(j).getY(); 075 counter++; 076 } 077 double avgX=totalX/counter; 078 double avgY=totalY/counter; 079 POINT2 ptCenter=new POINT2(avgX,avgY); 080 POINT2 ptNear=null; 081 //first point outside the clip bounds 082 if(clipArray.contains(pt02d)==false) 083 { 084 //add nearest segment midpoint to the front 085 //for(j=0;j<clipBounds.size();j++) 086 for(j=0;j<clipBounds.size();j++) //was n 087 { 088 sidePt.x=clipBounds.get(j).getX(); 089 sidePt.y=clipBounds.get(j).getY(); 090 dist=lineutility.CalcDistanceDouble(pt0, sidePt); 091 if(dist<minDist) 092 { 093 minDist=dist; 094 //minDistIndex=j; 095 nearestPt.setLocation(sidePt.x,sidePt.y); 096 } 097 } 098 //move nearestPt in a bit to not get clipped 099 ptNear=new POINT2(nearestPt.getX(),nearestPt.getY()); 100 ptNear=lineutility.ExtendAlongLineDouble(ptNear, ptCenter, 2); 101 nearestPt.setLocation(ptNear.x, ptNear.y); 102 polygon.add(0, nearestPt); 103 addToFront=true; 104 } 105 //re-initialize variables 106 nearestPt=new Point2D.Double(); 107 minDist=Double.MAX_VALUE; 108 //last point outside the clip bounds 109 if(clipArray.contains(ptLast2d)==false) 110 { 111 //add nearest segment midpoint to the front 112 //for(j=0;j<clipBounds.size();j++) 113 for(j=0;j<clipBounds.size();j++) //was n 114 { 115 sidePt.x=clipBounds.get(j).getX(); 116 sidePt.y=clipBounds.get(j).getY(); 117 dist=lineutility.CalcDistanceDouble(ptLast, sidePt); 118 if(dist<minDist) 119 { 120 minDist=dist; 121 //minDistIndex=j; 122 nearestPt.setLocation(sidePt.x,sidePt.y); 123 } 124 } 125 //move nearestPt in a bit to not get clipped 126 ptNear=new POINT2(nearestPt.getX(),nearestPt.getY()); 127 ptNear=lineutility.ExtendAlongLineDouble(ptNear, ptCenter, 2); 128 nearestPt.setLocation(ptNear.x, ptNear.y); 129 polygon.add(nearestPt); 130 addToEnd=true; 131 } 132 if (addToFront == false && addToEnd == false) { 133 result = 0; 134 } 135 else if (addToFront == true && addToEnd == false) { 136 result = 1; 137 } 138 else if (addToFront == false && addToEnd == true) { 139 result = 2; 140 } 141 else if (addToFront == true && addToEnd == true) { 142 result = 3; 143 } 144 } 145 catch (Exception exc) 146 { 147 ErrorLogger.LogException(_className, "AddBoundaryPointsForLines", 148 new RendererException("Failed inside AddBoundaryPointsForLines", exc)); 149 } 150 return result; 151 } 152 private static Point2D CalcTrueIntersectDouble(double m1, 153 double b1, 154 double m2, 155 double b2, 156 int bolVertical1, 157 int bolVertical2, 158 double X1, //x intercept if line1 is vertical 159 double X2) 160 { 161 Point2D ptIntersect=new Point2D.Double(X1,X2); 162 try 163 { 164 double x=0,y=0; 165 166 if(bolVertical1==0 && bolVertical2==0) //both lines vertical 167 return ptIntersect; 168 //the following 3 if blocks are the only ways to get an intersection 169 if(bolVertical1==0 && bolVertical2==1) //line1 vertical, line2 not 170 { 171 ptIntersect.setLocation(X1, m2*X1+b2); 172 return ptIntersect; 173 } 174 if(bolVertical1==1 && bolVertical2==0) //line2 vertical, line1 not 175 { 176 ptIntersect.setLocation(X2, m1*X2+b1); 177 return ptIntersect; 178 } 179 //if either of the lines is vertical function has already returned 180 //so both m1 and m2 should be valid 181 //should always be using this ocase because the lines are neither vertical 182 //or horizontal and are perpendicular 183 if(m1 != m2) 184 { 185 x=(b2-b1)/(m1-m2); //cannot blow up 186 y=(m1*x+b1); 187 ptIntersect.setLocation(x, y); 188 return ptIntersect; 189 } 190 } 191 catch(Exception exc) 192 { 193 ErrorLogger.LogException(_className ,"CalcTrueIntersectDouble", 194 new RendererException("Failed inside CalcTrueIntersectDouble", exc)); 195 } 196 return ptIntersect; 197 } 198 /** 199 * Gets theoretical intersection of an edge with the line connecting previous and current points. 200 * @param previous 201 * @param current 202 * @param currentEdge the current edge of the clip area, assumed to not be vertical 203 * @return 204 */ 205 private static Point2D intersectPoint2(Point2D previous, 206 Point2D current, 207 Line2D currentEdge) 208 { 209 210 Point2D ptIntersect=null; 211 try 212 { 213 Point2D ll=currentEdge.getP1(); 214 Point2D ul=currentEdge.getP2(); 215 216 //no vertical client segments 217 //if(current.getX()==previous.getX()) 218 if(Math.abs(current.getX()-previous.getX())<1) 219 current.setLocation(current.getX()+1, current.getY()); 220 221 double m1=( ul.getY()-ll.getY() )/( ul.getX()-ll.getX() ); 222 double m2=( current.getY()-previous.getY() )/( current.getX()-previous.getX() ); 223 double b1=ul.getY()-m1*ul.getX(); 224 double b2=current.getY()-m2*current.getX(); 225 ptIntersect=CalcTrueIntersectDouble(m1,b1,m2,b2,1,1,0,0); 226 } 227 catch (Exception exc) { 228 ErrorLogger.LogException(_className, "intersectPoint2", 229 new RendererException("Failed inside intersectPoint2", exc)); 230 } 231 return ptIntersect; 232 } 233 234 /** 235 * clips array of pts against a side of the clip bounds polygon 236 * assumes clipBounds has no vertical or horizontal segments 237 * @param pts array of points to clip against the clip bounds 238 * @param index starting index of clipBounds for the side to clip against 239 * @param clipBounds a quadrilateral or a polygon array that is the clipping area 240 * @return the clipped array of points 241 */ 242 private static ArrayList<Point2D> clipSide(TGLight tg, ArrayList<Point2D> pts, 243 int index, 244 ArrayList<Point2D> clipBounds) 245 { 246 ArrayList<Point2D> ptsResult=null; 247 try 248 { 249 Point2D pt1=new Point2D.Double(clipBounds.get(index).getX(),clipBounds.get(index).getY());//first point of clip side 250 Point2D pt2=new Point2D.Double(clipBounds.get(index+1).getX(),clipBounds.get(index+1).getY());//last point of clip side 251 Point2D clipBoundsPoint=null;//some point in the clipbounds not on the side 252 Point2D ptClipBoundsIntersect=null;//some point in the clipbounds not on the side 253 double m1=0,m2=0,b1=0,b2=0,b3=0,b4=0; 254 Point2D ptPreviousIntersect=null,ptCurrentIntersect=null; 255 int j = 0,clipBoundsQuadrant=-1,previousQuadrant=-1,currentQuadrant=-1; //quadrants relative to side 256 Point2D current = null, previous = null; 257 Point2D intersectPt = null; 258 Line2D edge; 259 ptsResult=new ArrayList(); 260 //set some point in the array which is not in the side 261 //this point will be used to define which side of the clipping side the rest of the clipbounds points are on 262 //then it can be used to figure out whether a given point is to be clipped 263 //for this scheme to work it needs to be a convex clipping area 264 if(index==0) 265 { 266 clipBoundsPoint=new Point2D.Double(clipBounds.get(index+2).getX(),clipBounds.get(index+2).getY()); 267 } 268 else if(index>1) 269 { 270 clipBoundsPoint=new Point2D.Double(clipBounds.get(index-2).getX(),clipBounds.get(index-2).getY()); 271 } 272 else if(index==1) 273 { 274 clipBoundsPoint=new Point2D.Double(clipBounds.get(0).getX(),clipBounds.get(0).getY()); 275 } 276 277 //no vertical segments 278 //if(pt2.getX()==pt1.getX()) 279 if(Math.abs(pt2.getX()-pt1.getX())<1) 280 pt2.setLocation(pt2.getX()+1, pt2.getY()); 281 //if(pt2.getY()==pt1.getY()) 282 if(Math.abs(pt2.getY()-pt1.getY())<1) 283 pt2.setLocation(pt2.getX(), pt2.getY()+1); 284 285 for (j = 0; j < pts.size(); j++) 286 { 287 current = pts.get(j); 288 if (j == 0) 289 { 290 previous = pts.get(pts.size() - 1); 291 } 292 else 293 { 294 previous = pts.get(j - 1); 295 } 296 297 m1=(pt2.getY()-pt1.getY())/(pt2.getX()-pt1.getX()); 298 m2=-1d/m1; //the slope of the line perpendicular to m1,b1 299 b1=pt2.getY()-m1*pt2.getX(); 300 b2=previous.getY()-m2*previous.getX(); 301 b3=current.getY()-m2*current.getX(); 302 b4=clipBoundsPoint.getY()-m2*clipBoundsPoint.getX(); 303 ptPreviousIntersect=CalcTrueIntersectDouble(m1,b1,m2,b2,1,1,0,0); 304 ptCurrentIntersect=CalcTrueIntersectDouble(m1,b1,m2,b3,1,1,0,0); 305 ptClipBoundsIntersect=CalcTrueIntersectDouble(m1,b1,m2,b4,1,1,0,0); 306 clipBoundsQuadrant=lineutility.GetQuadrantDouble(clipBoundsPoint.getX(), clipBoundsPoint.getY(), ptClipBoundsIntersect.getX(), ptClipBoundsIntersect.getY()); 307 previousQuadrant=lineutility.GetQuadrantDouble(previous.getX(), previous.getY(), ptPreviousIntersect.getX(), ptPreviousIntersect.getY()); 308 currentQuadrant=lineutility.GetQuadrantDouble(current.getX(), current.getY(), ptCurrentIntersect.getX(), ptCurrentIntersect.getY()); 309 310 //case: both inside 311 if(previousQuadrant==clipBoundsQuadrant && currentQuadrant==clipBoundsQuadrant) 312 ptsResult.add(current); 313 else if(previousQuadrant==clipBoundsQuadrant && currentQuadrant!=clipBoundsQuadrant)//previous inside, current outside 314 { 315 edge = new Line2D.Double(pt1, pt2); 316 intersectPt = intersectPoint2(previous, current, edge); 317 if (intersectPt != null) 318 { 319 ptsResult.add(intersectPt); 320 } 321 tg.set_WasClipped(true); 322 } 323 else if(previousQuadrant!=clipBoundsQuadrant && currentQuadrant==clipBoundsQuadrant)//current inside, previous outside 324 { 325 edge = new Line2D.Double(pt1, pt2); 326 intersectPt = intersectPoint2(previous, current, edge); 327 if (intersectPt != null) 328 { 329 ptsResult.add(intersectPt); 330 } 331 ptsResult.add(current); 332 tg.set_WasClipped(true); 333 } 334 else if(previousQuadrant!=clipBoundsQuadrant && currentQuadrant!=clipBoundsQuadrant) 335 continue; 336 }//end for j=0 to pts.size()-1 337 }//end try 338 catch (Exception exc) { 339 ErrorLogger.LogException(_className, "clipSide", 340 new RendererException("Failed inside clipSide", exc)); 341 } 342 return ptsResult; 343 } 344 /** 345 * for pre-clipped lines which also require fill but need the processed points 346 * to create the fill. This function is called after the clip, so the fill 347 * does not get clipped. 348 * @param tg 349 * @param shapes 350 */ 351 protected static void addAbatisFill(TGLight tg, 352 ArrayList<Shape2>shapes) 353 { 354 try 355 { 356 if(tg.Pixels==null || 357 tg.Pixels.size()<2 || 358 tg.get_FillColor()==null || 359 tg.get_FillColor().getAlpha()<2 || 360 shapes==null) 361 return; 362 363 int j=0,n=tg.Pixels.size(); 364 Shape2 shape=null; 365 TGLight tg2=null; 366 switch(tg.get_LineType()) 367 { 368 case TacticalLines.MSDZ: 369 double dist0=0,dist1=0,dist2=0; 370 shape=new Shape2(Shape2.SHAPE_TYPE_POLYLINE); 371 shape.setFillColor(tg.get_FillColor()); 372 if(tg.Pixels != null & tg.Pixels.size()>=300) 373 { 374 dist0=Math.abs(tg.Pixels.get(0).x-tg.Pixels.get(50).x); 375 dist1=Math.abs(tg.Pixels.get(100).x-tg.Pixels.get(150).x); 376 dist2=Math.abs(tg.Pixels.get(200).x-tg.Pixels.get(250).x); 377 int start=-1,end=-1; 378 if(dist0>=dist1 && dist0>=dist2) 379 { 380 start=0; 381 end=99; 382 } 383 else if(dist1>=dist0 && dist1>=dist2) 384 { 385 start=100; 386 end=199; 387 } 388 else 389 { 390 start=200; 391 end=299; 392 } 393 shape.moveTo(tg.Pixels.get(start)); 394 for(j=start;j<=end;j++) 395 shape.lineTo(tg.Pixels.get(j)); 396 397 //shapes.add(0,shape); 398 } 399 break; 400 case TacticalLines.ABATIS: 401 shape=new Shape2(Shape2.SHAPE_TYPE_POLYLINE); 402 shape.setFillColor(tg.get_FillColor()); 403 tg2=new TGLight(); 404 tg2.set_LineType(TacticalLines.GENERAL); 405 tg2.Pixels=new ArrayList(); 406 if(tg.Pixels != null && tg.Pixels.size()>2) 407 { 408 tg2.Pixels.add(tg.Pixels.get(n-3)); 409 tg2.Pixels.add(tg.Pixels.get(n-2)); 410 tg2.Pixels.add(tg.Pixels.get(n-1)); 411 tg2.Pixels.add(tg.Pixels.get(n-3)); 412 413 shape.moveTo(tg2.Pixels.get(0)); 414 for(j=1;j<tg2.Pixels.size();j++) 415 shape.lineTo(tg2.Pixels.get(j)); 416 417 //shapes.add(shape); 418 } 419 break; 420 default: 421 return; 422 }//end switch 423 if(shapes != null) 424 shapes.add(0,shape); 425 } 426 catch (Exception exc) { 427 ErrorLogger.LogException(_className, "addAbatisFill", 428 new RendererException("Failed inside addAbatisFill", exc)); 429 } 430 } 431 /** 432 * for lines with glyphs the fill must be handled (clipped) as a separate shape. 433 * this function needs to be called before the clipping is done to the line 434 * @param tg 435 * @param clipBounds 436 */ 437 protected static ArrayList<Shape2> LinesWithFill(TGLight tg, 438 ArrayList<Point2D> clipBounds) 439 { 440 ArrayList<Shape2>shapes=null; 441 try 442 { 443 if(tg.get_FillColor()==null || tg.get_FillColor().getAlpha()<=1 || 444 tg.Pixels==null || tg.Pixels.isEmpty()) 445 return shapes; 446 447 switch(tg.get_LineType()) 448 { 449 case TacticalLines.ABATIS: 450 case TacticalLines.SPT: 451 case TacticalLines.MAIN: 452 case TacticalLines.AAAAA: 453 case TacticalLines.AIRAOA: 454 case TacticalLines.CATK: 455 case TacticalLines.CATKBYFIRE: 456 case TacticalLines.CORDONSEARCH: 457 case TacticalLines.CORDONKNOCK: 458 case TacticalLines.SECURE: 459 case TacticalLines.OCCUPY: 460 case TacticalLines.RETAIN: 461 case TacticalLines.ISOLATE: 462 case TacticalLines.CONVOY: 463 case TacticalLines.HCONVOY: 464 return shapes; 465 case TacticalLines.PAA_RECTANGULAR: 466 case TacticalLines.RECTANGULAR_TARGET: 467 return null; 468 case TacticalLines.OBSFAREA: 469 case TacticalLines.OBSAREA: 470 case TacticalLines.STRONG: 471 case TacticalLines.ZONE: 472 case TacticalLines.FORT_REVD: 473 case TacticalLines.FORT: 474 case TacticalLines.ENCIRCLE: 475 case TacticalLines.ATDITCHC: 476 case TacticalLines.ATDITCHM: 477 return fillDMA(tg,clipBounds); 478 default: 479 break; 480 } 481 if(clsUtility.LinesWithFill(tg.get_LineType())==false) 482 return shapes; 483 484 shapes=new ArrayList(); 485 //undo any fillcolor that might have been set for the existing shape 486 //because we are divorcing fill from the line 487 Shape2 shape=null; 488 489 //create a generic area tg from the pixels and clip it 490 TGLight tg2=new TGLight(); 491 tg2.set_LineType(TacticalLines.GENERAL); 492 tg2.Pixels=new ArrayList(); 493 tg2.Pixels.addAll(tg.Pixels); 494 closeAreaTG(tg2); 495 //tg2.Pixels.add(tg.Pixels.get(0)); 496 if(clipBounds != null) 497 ClipPolygon(tg2,clipBounds); 498 499 500 if(tg2.Pixels==null || tg2.Pixels.isEmpty()) 501 return null; 502 503 int j=0; 504 shape=new Shape2(Shape2.SHAPE_TYPE_POLYLINE); 505 shape.setFillColor(tg.get_FillColor()); 506 507 shape.moveTo(tg2.Pixels.get(0)); 508 for(j=1;j<tg2.Pixels.size();j++) 509 shape.lineTo(tg2.Pixels.get(j)); 510 511 if(tg.get_FillColor() != null || tg.get_FillColor().getAlpha()>1) 512 { 513 shapes.add(shape); 514 } 515 else 516 return null; 517 } 518 catch (Exception exc) { 519 ErrorLogger.LogException(_className, "LinesWithFill", 520 new RendererException("Failed inside LinesWithFill", exc)); 521 } 522 return shapes; 523 } 524 /** 525 * closes an area 526 * @param tg 527 */ 528 private static void closeAreaTG(TGLight tg) 529 { 530 try 531 { 532 if(tg.Pixels==null || tg.Pixels.isEmpty()) 533 return; 534 535 POINT2 pt0=tg.Pixels.get(0); 536 POINT2 ptn=tg.Pixels.get(tg.Pixels.size()-1); 537 if(pt0.x != ptn.x || pt0.y != ptn.y) 538 tg.Pixels.add(pt0); 539 540 } 541 catch (Exception exc) { 542 ErrorLogger.LogException(_className, "closeAreaTG", 543 new RendererException("Failed inside closeAreaTG", exc)); 544 } 545 } 546 /** 547 * DMA, DMAF fill must be handled separately because of the feint 548 * @param tg 549 * @param clipBounds 550 * @return 551 */ 552 protected static ArrayList<Shape2> fillDMA(TGLight tg, 553 ArrayList<Point2D> clipBounds) 554 { 555 ArrayList<Shape2>shapes=new ArrayList(); 556 try 557 { 558 switch(tg.get_LineType()) 559 { 560 case TacticalLines.OBSFAREA: 561 case TacticalLines.OBSAREA: 562 case TacticalLines.STRONG: 563 case TacticalLines.ZONE: 564 case TacticalLines.FORT_REVD: 565 case TacticalLines.FORT: 566 case TacticalLines.ENCIRCLE: 567 case TacticalLines.ATDITCHC: 568 case TacticalLines.ATDITCHM: 569 break; 570 default: 571 return shapes; 572 } 573 Shape2 shape=null; 574 575 //create a generic area tg from the pixels and clip it 576 int j=0; 577 TGLight tg2=new TGLight(); 578 tg2.set_LineType(TacticalLines.GENERAL); 579 tg2.Pixels=new ArrayList(); 580 //to get the original pixels size 581 int n=0; 582 n=tg.Pixels.size(); 583 584 for(j=0;j<n;j++) 585 tg2.Pixels.add(tg.Pixels.get(j)); 586 587 closeAreaTG(tg2); 588 589 if(clipBounds != null) 590 ClipPolygon(tg2,clipBounds); 591 592 if(tg2.Pixels==null || tg2.Pixels.isEmpty()) 593 return shapes; 594 595 shape=new Shape2(Shape2.SHAPE_TYPE_POLYLINE); 596 shape.setFillColor(tg.get_FillColor()); 597 598 shape.moveTo(tg2.Pixels.get(0)); 599 //original pixels do not include feint 600 for(j=1;j<tg2.Pixels.size();j++) 601 shape.lineTo(tg2.Pixels.get(j)); 602 603 shapes.add(shape); 604 } 605 catch (Exception exc) { 606 ErrorLogger.LogException(_className, "fillDMA", 607 new RendererException("Failed inside fillDMA", exc)); 608 } 609 return shapes; 610 } 611// private static Boolean isClosed(ArrayList<POINT2>pts) 612// { 613// boolean closed=false; 614// POINT2 pt0=pts.get(0); 615// POINT2 ptLast=pts.get(pts.size()-1); 616// if(pt0.x==ptLast.x && pt0.y==ptLast.y) 617// closed=true; 618// return closed; 619// } 620 /** 621 * 622 * @param tg 623 * @param clipBounds polygon representing clipping area 624 * @return 625 */ 626 protected static ArrayList<Point2D> ClipPolygon(TGLight tg, 627 ArrayList<Point2D> clipBounds) { 628 ArrayList<Point2D> poly = new ArrayList(); 629 try 630 { 631 //diagnostic 632 Boolean isClosed = clsUtility.isClosedPolygon(tg.get_LineType()); 633 //Boolean isClosed = isClosed(tg.Pixels); 634 //M. Deutch commented one line 12-27-12 635 //clipBounds=clsUtilityGE.expandPolygon(clipBounds, 20); 636 clipBounds=clsUtilityGE.expandPolygon(clipBounds, 20); 637 //int n=clipBounds.size(); 638 ArrayList polygon = clsUtilityCPOF.POINT2toPoint2D(tg.Pixels); 639 640 int j=0; 641 Map<String,Object>hashMap=new HashMap<String,Object>(); 642 //int hashCode=0; 643 for(j=0;j<polygon.size();j++) 644 hashMap.put(Integer.toString(j), polygon.get(j)); 645 646 //close the clipbounds if necessary 647 Point2D clipBoundsPtStart=clipBounds.get(0); 648 Point2D clipBoundsPtEnd=clipBounds.get(clipBounds.size()-1); 649 if(clipBoundsPtStart.getX() != clipBoundsPtEnd.getX() || 650 clipBoundsPtStart.getY() != clipBoundsPtEnd.getY()) 651 clipBounds.add(clipBoundsPtStart); 652 653 int addedLinePoints = 0; 654 if (isClosed) 655 polygon.remove(polygon.size() - 1); 656 else 657 { 658 addedLinePoints = AddBoundaryPointsForLines(polygon, clipBounds); 659 } 660 661 //for(j=0;j<clipBounds.size()-1;j++) 662 for(j=0;j<clipBounds.size()-1;j++) 663 { 664 if(j==0) 665 poly=clipSide(tg,polygon,j,clipBounds); 666 else 667 poly=clipSide(tg,poly,j,clipBounds); 668 } 669 670 671 if (isClosed) 672 { 673 if (poly.size() > 0) 674 { 675 poly.add(poly.get(0)); 676 } 677 } 678 else 679 { 680 switch (addedLinePoints) 681 { 682 case 0: //no points were added, do nothing 683 break; 684 case 1: //point was added to the front to make algorithm work, remove segment 685 if (poly.size() > 0) { 686 poly.remove(0); 687 } 688 if (poly.size() > 0) { 689 poly.remove(0); 690 } 691 break; 692 case 2: //point was added to the end to make algorithm work, remove segment 693 if (poly.size() > 0) { 694 poly.remove(poly.size() - 1); 695 } 696 if (poly.size() > 0) { 697 poly.remove(poly.size() - 1); 698 } 699 break; 700 case 3: //point was added to the front and end to make algorithm work, remove segments 701 if (poly.size() > 0) { 702 poly.remove(0); 703 } 704 if (poly.size() > 0) { 705 poly.remove(0); 706 } 707 if (poly.size() > 0) { 708 poly.remove(poly.size() - 1); 709 } 710 if (poly.size() > 0) { 711 poly.remove(poly.size() - 1); 712 } 713 break; 714 } 715 } 716 717 if (isClosed == true) 718 { 719 if (poly.size() > 2) 720 { 721 tg.Pixels = clsUtilityCPOF.Point2DtoPOINT2Mapped(poly,hashMap); 722 } 723 else 724 { 725 tg.Pixels=new ArrayList(); 726 } 727 728 } 729 else 730 { 731 if (poly.size() > 1) 732 { 733 tg.Pixels = clsUtilityCPOF.Point2DtoPOINT2Mapped(poly,hashMap); 734 } 735 else 736 { 737 tg.Pixels=new ArrayList(); 738 } 739 } 740 741 } catch (Exception exc) { 742 ErrorLogger.LogException(_className, "ClipPolygon", 743 new RendererException("Failed inside ClipPolygon", exc)); 744 } 745 return poly; 746 } 747}