1 7 package java.awt; 8 9 import java.awt.geom.AffineTransform ; 10 import java.awt.geom.PathIterator ; 11 import java.awt.geom.Point2D ; 12 import java.awt.geom.Rectangle2D ; 13 import sun.awt.geom.Crossings; 14 15 40 public class Polygon implements Shape , java.io.Serializable { 41 42 52 public int npoints; 53 54 65 public int xpoints[]; 66 67 78 public int ypoints[]; 79 80 89 protected Rectangle bounds; 90 91 94 private static final long serialVersionUID = -6460061437900069969L; 95 96 99 public Polygon() { 100 xpoints = new int[4]; 101 ypoints = new int[4]; 102 } 103 104 119 public Polygon(int xpoints[], int ypoints[], int npoints) { 120 if (npoints > xpoints.length || npoints > ypoints.length) { 123 throw new IndexOutOfBoundsException ("npoints > xpoints.length || npoints > ypoints.length"); 124 } 125 this.npoints = npoints; 126 this.xpoints = new int[npoints]; 127 this.ypoints = new int[npoints]; 128 System.arraycopy(xpoints, 0, this.xpoints, 0, npoints); 129 System.arraycopy(ypoints, 0, this.ypoints, 0, npoints); 130 } 131 132 149 public void reset() { 150 npoints = 0; 151 bounds = null; 152 } 153 154 166 public void invalidate() { 167 bounds = null; 168 } 169 170 178 public void translate(int deltaX, int deltaY) { 179 for (int i = 0; i < npoints; i++) { 180 xpoints[i] += deltaX; 181 ypoints[i] += deltaY; 182 } 183 if (bounds != null) { 184 bounds.translate(deltaX, deltaY); 185 } 186 } 187 188 195 void calculateBounds(int xpoints[], int ypoints[], int npoints) { 196 int boundsMinX = Integer.MAX_VALUE; 197 int boundsMinY = Integer.MAX_VALUE; 198 int boundsMaxX = Integer.MIN_VALUE; 199 int boundsMaxY = Integer.MIN_VALUE; 200 201 for (int i = 0; i < npoints; i++) { 202 int x = xpoints[i]; 203 boundsMinX = Math.min(boundsMinX, x); 204 boundsMaxX = Math.max(boundsMaxX, x); 205 int y = ypoints[i]; 206 boundsMinY = Math.min(boundsMinY, y); 207 boundsMaxY = Math.max(boundsMaxY, y); 208 } 209 bounds = new Rectangle (boundsMinX, boundsMinY, 210 boundsMaxX - boundsMinX, 211 boundsMaxY - boundsMinY); 212 } 213 214 218 void updateBounds(int x, int y) { 219 if (x < bounds.x) { 220 bounds.width = bounds.width + (bounds.x - x); 221 bounds.x = x; 222 } 223 else { 224 bounds.width = Math.max(bounds.width, x - bounds.x); 225 } 227 228 if (y < bounds.y) { 229 bounds.height = bounds.height + (bounds.y - y); 230 bounds.y = y; 231 } 232 else { 233 bounds.height = Math.max(bounds.height, y - bounds.y); 234 } 236 } 237 238 250 public void addPoint(int x, int y) { 251 if (npoints == xpoints.length) { 252 int tmp[]; 253 254 tmp = new int[npoints * 2]; 255 System.arraycopy(xpoints, 0, tmp, 0, npoints); 256 xpoints = tmp; 257 258 tmp = new int[npoints * 2]; 259 System.arraycopy(ypoints, 0, tmp, 0, npoints); 260 ypoints = tmp; 261 } 262 xpoints[npoints] = x; 263 ypoints[npoints] = y; 264 npoints++; 265 if (bounds != null) { 266 updateBounds(x, y); 267 } 268 } 269 270 279 public Rectangle getBounds() { 280 return getBoundingBox(); 281 } 282 283 289 @Deprecated 290 public Rectangle getBoundingBox() { 291 if (npoints == 0) { 292 return new Rectangle (); 293 } 294 if (bounds == null) { 295 calculateBounds(xpoints, ypoints, npoints); 296 } 297 return bounds.getBounds(); 298 } 299 300 308 public boolean contains(Point p) { 309 return contains(p.x, p.y); 310 } 311 312 324 public boolean contains(int x, int y) { 325 return contains((double) x, (double) y); 326 } 327 328 340 @Deprecated 341 public boolean inside(int x, int y) { 342 return contains((double) x, (double) y); 343 } 344 345 350 public Rectangle2D getBounds2D() { 351 return getBounds(); 352 } 353 354 363 public boolean contains(double x, double y) { 364 if (npoints <= 2 || !getBoundingBox().contains(x, y)) { 365 return false; 366 } 367 int hits = 0; 368 369 int lastx = xpoints[npoints - 1]; 370 int lasty = ypoints[npoints - 1]; 371 int curx, cury; 372 373 for (int i = 0; i < npoints; lastx = curx, lasty = cury, i++) { 375 curx = xpoints[i]; 376 cury = ypoints[i]; 377 378 if (cury == lasty) { 379 continue; 380 } 381 382 int leftx; 383 if (curx < lastx) { 384 if (x >= lastx) { 385 continue; 386 } 387 leftx = curx; 388 } else { 389 if (x >= curx) { 390 continue; 391 } 392 leftx = lastx; 393 } 394 395 double test1, test2; 396 if (cury < lasty) { 397 if (y < cury || y >= lasty) { 398 continue; 399 } 400 if (x < leftx) { 401 hits++; 402 continue; 403 } 404 test1 = x - curx; 405 test2 = y - cury; 406 } else { 407 if (y < lasty || y >= cury) { 408 continue; 409 } 410 if (x < leftx) { 411 hits++; 412 continue; 413 } 414 test1 = x - lastx; 415 test2 = y - lasty; 416 } 417 418 if (test1 < (test2 / (lasty - cury) * (lastx - curx))) { 419 hits++; 420 } 421 } 422 423 return ((hits & 1) != 0); 424 } 425 426 private Crossings getCrossings(double xlo, double ylo, 427 double xhi, double yhi) 428 { 429 Crossings cross = new Crossings.EvenOdd(xlo, ylo, xhi, yhi); 430 int lastx = xpoints[npoints - 1]; 431 int lasty = ypoints[npoints - 1]; 432 int curx, cury; 433 434 for (int i = 0; i < npoints; i++) { 436 curx = xpoints[i]; 437 cury = ypoints[i]; 438 if (cross.accumulateLine(lastx, lasty, curx, cury)) { 439 return null; 440 } 441 lastx = curx; 442 lasty = cury; 443 } 444 445 return cross; 446 } 447 448 457 public boolean contains(Point2D p) { 458 return contains(p.getX(), p.getY()); 459 } 460 461 477 public boolean intersects(double x, double y, double w, double h) { 478 if (npoints <= 0 || !getBoundingBox().intersects(x, y, w, h)) { 479 return false; 480 } 481 482 Crossings cross = getCrossings(x, y, x+w, y+h); 483 return (cross == null || !cross.isEmpty()); 484 } 485 486 495 public boolean intersects(Rectangle2D r) { 496 return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight()); 497 } 498 499 513 public boolean contains(double x, double y, double w, double h) { 514 if (npoints <= 0 || !getBoundingBox().intersects(x, y, w, h)) { 515 return false; 516 } 517 518 Crossings cross = getCrossings(x, y, x+w, y+h); 519 return (cross != null && cross.covers(y, y+h)); 520 } 521 522 531 public boolean contains(Rectangle2D r) { 532 return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight()); 533 } 534 535 547 public PathIterator getPathIterator(AffineTransform at) { 548 return new PolygonPathIterator(this, at); 549 } 550 551 571 public PathIterator getPathIterator(AffineTransform at, double flatness) { 572 return getPathIterator(at); 573 } 574 575 class PolygonPathIterator implements PathIterator { 576 Polygon poly; 577 AffineTransform transform; 578 int index; 579 580 public PolygonPathIterator(Polygon pg, AffineTransform at) { 581 poly = pg; 582 transform = at; 583 if (pg.npoints == 0) { 584 index = 1; 586 } 587 } 588 589 595 public int getWindingRule() { 596 return WIND_EVEN_ODD; 597 } 598 599 604 public boolean isDone() { 605 return index > poly.npoints; 606 } 607 608 613 public void next() { 614 index++; 615 } 616 617 635 public int currentSegment(float[] coords) { 636 if (index >= poly.npoints) { 637 return SEG_CLOSE; 638 } 639 coords[0] = poly.xpoints[index]; 640 coords[1] = poly.ypoints[index]; 641 if (transform != null) { 642 transform.transform(coords, 0, coords, 0, 1); 643 } 644 return (index == 0 ? SEG_MOVETO : SEG_LINETO); 645 } 646 647 666 public int currentSegment(double[] coords) { 667 if (index >= poly.npoints) { 668 return SEG_CLOSE; 669 } 670 coords[0] = poly.xpoints[index]; 671 coords[1] = poly.ypoints[index]; 672 if (transform != null) { 673 transform.transform(coords, 0, coords, 0, 1); 674 } 675 return (index == 0 ? SEG_MOVETO : SEG_LINETO); 676 } 677 } 678 } 679 | Popular Tags |