QuadCurve2D.java revision 9066cfe9886ac131c34d59ed0e2d287b0e3c0087
1/* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17/** 18 * @author Denis M. Kishenko 19 * @version $Revision$ 20 */ 21 22package java.awt.geom; 23 24import java.awt.Rectangle; 25import java.awt.Shape; 26import java.util.NoSuchElementException; 27 28import org.apache.harmony.awt.gl.Crossing; 29import org.apache.harmony.awt.internal.nls.Messages; 30 31/** 32 * The Class QuadCurve2D is a Shape that represents a segment of a quadratic 33 * (Bezier) curve. The curved segment is determined by three points: a start 34 * point, an end point, and a control point. The line from the control point to 35 * the starting point gives the tangent to the curve at the starting point, and 36 * the line from the control point to the end point gives the tangent to the 37 * curve at the end point. 38 * 39 * @since Android 1.0 40 */ 41public abstract class QuadCurve2D implements Shape, Cloneable { 42 43 /** 44 * The Class Float is the subclass of QuadCurve2D that has all of its data 45 * values stored with float-level precision. 46 * 47 * @since Android 1.0 48 */ 49 public static class Float extends QuadCurve2D { 50 51 /** 52 * The x coordinate of the starting point of the curved segment. 53 */ 54 public float x1; 55 56 /** 57 * The y coordinate of the starting point of the curved segment. 58 */ 59 public float y1; 60 61 /** 62 * The x coordinate of the control point. 63 */ 64 public float ctrlx; 65 66 /** 67 * The y coordinate of the control point. 68 */ 69 public float ctrly; 70 71 /** 72 * The x coordinate of the end point of the curved segment. 73 */ 74 public float x2; 75 76 /** 77 * The y coordinate of the end point of the curved segment. 78 */ 79 public float y2; 80 81 /** 82 * Instantiates a new float-valued QuadCurve2D with all coordinate 83 * values set to zero. 84 */ 85 public Float() { 86 } 87 88 /** 89 * Instantiates a new float-valued QuadCurve2D with the specified 90 * coordinate values. 91 * 92 * @param x1 93 * the x coordinate of the starting point of the curved 94 * segment. 95 * @param y1 96 * the y coordinate of the starting point of the curved 97 * segment. 98 * @param ctrlx 99 * the x coordinate of the control point. 100 * @param ctrly 101 * the y coordinate of the control point. 102 * @param x2 103 * the x coordinate of the end point of the curved segment. 104 * @param y2 105 * the y coordinate of the end point of the curved segment. 106 */ 107 public Float(float x1, float y1, float ctrlx, float ctrly, float x2, float y2) { 108 setCurve(x1, y1, ctrlx, ctrly, x2, y2); 109 } 110 111 @Override 112 public double getX1() { 113 return x1; 114 } 115 116 @Override 117 public double getY1() { 118 return y1; 119 } 120 121 @Override 122 public double getCtrlX() { 123 return ctrlx; 124 } 125 126 @Override 127 public double getCtrlY() { 128 return ctrly; 129 } 130 131 @Override 132 public double getX2() { 133 return x2; 134 } 135 136 @Override 137 public double getY2() { 138 return y2; 139 } 140 141 @Override 142 public Point2D getP1() { 143 return new Point2D.Float(x1, y1); 144 } 145 146 @Override 147 public Point2D getCtrlPt() { 148 return new Point2D.Float(ctrlx, ctrly); 149 } 150 151 @Override 152 public Point2D getP2() { 153 return new Point2D.Float(x2, y2); 154 } 155 156 @Override 157 public void setCurve(double x1, double y1, double ctrlx, double ctrly, double x2, double y2) { 158 this.x1 = (float)x1; 159 this.y1 = (float)y1; 160 this.ctrlx = (float)ctrlx; 161 this.ctrly = (float)ctrly; 162 this.x2 = (float)x2; 163 this.y2 = (float)y2; 164 } 165 166 /** 167 * Sets the data values of the curve. 168 * 169 * @param x1 170 * the x coordinate of the starting point of the curved 171 * segment. 172 * @param y1 173 * the y coordinate of the starting point of the curved 174 * segment. 175 * @param ctrlx 176 * the x coordinate of the control point. 177 * @param ctrly 178 * the y coordinate of the control point. 179 * @param x2 180 * the x coordinate of the end point of the curved segment. 181 * @param y2 182 * the y coordinate of the end point of the curved segment. 183 */ 184 public void setCurve(float x1, float y1, float ctrlx, float ctrly, float x2, float y2) { 185 this.x1 = x1; 186 this.y1 = y1; 187 this.ctrlx = ctrlx; 188 this.ctrly = ctrly; 189 this.x2 = x2; 190 this.y2 = y2; 191 } 192 193 public Rectangle2D getBounds2D() { 194 float rx0 = Math.min(Math.min(x1, x2), ctrlx); 195 float ry0 = Math.min(Math.min(y1, y2), ctrly); 196 float rx1 = Math.max(Math.max(x1, x2), ctrlx); 197 float ry1 = Math.max(Math.max(y1, y2), ctrly); 198 return new Rectangle2D.Float(rx0, ry0, rx1 - rx0, ry1 - ry0); 199 } 200 } 201 202 /** 203 * The Class Double is the subclass of QuadCurve2D that has all of its data 204 * values stored with double-level precision. 205 * 206 * @since Android 1.0 207 */ 208 public static class Double extends QuadCurve2D { 209 210 /** 211 * The x coordinate of the starting point of the curved segment. 212 */ 213 public double x1; 214 215 /** 216 * The y coordinate of the starting point of the curved segment. 217 */ 218 public double y1; 219 220 /** 221 * The x coordinate of the control point. 222 */ 223 public double ctrlx; 224 225 /** 226 * The y coordinate of the control point. 227 */ 228 public double ctrly; 229 230 /** 231 * The x coordinate of the end point of the curved segment. 232 */ 233 public double x2; 234 235 /** 236 * The y coordinate of the end point of the curved segment. 237 */ 238 public double y2; 239 240 /** 241 * Instantiates a new double-valued QuadCurve2D with all coordinate 242 * values set to zero. 243 */ 244 public Double() { 245 } 246 247 /** 248 * Instantiates a new double-valued QuadCurve2D with the specified 249 * coordinate values. 250 * 251 * @param x1 252 * the x coordinate of the starting point of the curved 253 * segment. 254 * @param y1 255 * the y coordinate of the starting point of the curved 256 * segment. 257 * @param ctrlx 258 * the x coordinate of the control point. 259 * @param ctrly 260 * the y coordinate of the control point. 261 * @param x2 262 * the x coordinate of the end point of the curved segment. 263 * @param y2 264 * the y coordinate of the end point of the curved segment. 265 */ 266 public Double(double x1, double y1, double ctrlx, double ctrly, double x2, double y2) { 267 setCurve(x1, y1, ctrlx, ctrly, x2, y2); 268 } 269 270 @Override 271 public double getX1() { 272 return x1; 273 } 274 275 @Override 276 public double getY1() { 277 return y1; 278 } 279 280 @Override 281 public double getCtrlX() { 282 return ctrlx; 283 } 284 285 @Override 286 public double getCtrlY() { 287 return ctrly; 288 } 289 290 @Override 291 public double getX2() { 292 return x2; 293 } 294 295 @Override 296 public double getY2() { 297 return y2; 298 } 299 300 @Override 301 public Point2D getP1() { 302 return new Point2D.Double(x1, y1); 303 } 304 305 @Override 306 public Point2D getCtrlPt() { 307 return new Point2D.Double(ctrlx, ctrly); 308 } 309 310 @Override 311 public Point2D getP2() { 312 return new Point2D.Double(x2, y2); 313 } 314 315 @Override 316 public void setCurve(double x1, double y1, double ctrlx, double ctrly, double x2, double y2) { 317 this.x1 = x1; 318 this.y1 = y1; 319 this.ctrlx = ctrlx; 320 this.ctrly = ctrly; 321 this.x2 = x2; 322 this.y2 = y2; 323 } 324 325 public Rectangle2D getBounds2D() { 326 double rx0 = Math.min(Math.min(x1, x2), ctrlx); 327 double ry0 = Math.min(Math.min(y1, y2), ctrly); 328 double rx1 = Math.max(Math.max(x1, x2), ctrlx); 329 double ry1 = Math.max(Math.max(y1, y2), ctrly); 330 return new Rectangle2D.Double(rx0, ry0, rx1 - rx0, ry1 - ry0); 331 } 332 } 333 334 /* 335 * QuadCurve2D path iterator 336 */ 337 /** 338 * The PathIterator for a Quad2D curve. 339 */ 340 class Iterator implements PathIterator { 341 342 /** 343 * The source QuadCurve2D object. 344 */ 345 QuadCurve2D c; 346 347 /** 348 * The path iterator transformation. 349 */ 350 AffineTransform t; 351 352 /** 353 * The current segment index. 354 */ 355 int index; 356 357 /** 358 * Constructs a new QuadCurve2D.Iterator for given curve and 359 * transformation 360 * 361 * @param q 362 * the source QuadCurve2D object. 363 * @param t 364 * the AffineTransform that acts on the coordinates before 365 * returning them (or null). 366 */ 367 Iterator(QuadCurve2D q, AffineTransform t) { 368 this.c = q; 369 this.t = t; 370 } 371 372 public int getWindingRule() { 373 return WIND_NON_ZERO; 374 } 375 376 public boolean isDone() { 377 return (index > 1); 378 } 379 380 public void next() { 381 index++; 382 } 383 384 public int currentSegment(double[] coords) { 385 if (isDone()) { 386 // awt.4B=Iterator out of bounds 387 throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$ 388 } 389 int type; 390 int count; 391 if (index == 0) { 392 type = SEG_MOVETO; 393 coords[0] = c.getX1(); 394 coords[1] = c.getY1(); 395 count = 1; 396 } else { 397 type = SEG_QUADTO; 398 coords[0] = c.getCtrlX(); 399 coords[1] = c.getCtrlY(); 400 coords[2] = c.getX2(); 401 coords[3] = c.getY2(); 402 count = 2; 403 } 404 if (t != null) { 405 t.transform(coords, 0, coords, 0, count); 406 } 407 return type; 408 } 409 410 public int currentSegment(float[] coords) { 411 if (isDone()) { 412 // awt.4B=Iterator out of bounds 413 throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$ 414 } 415 int type; 416 int count; 417 if (index == 0) { 418 type = SEG_MOVETO; 419 coords[0] = (float)c.getX1(); 420 coords[1] = (float)c.getY1(); 421 count = 1; 422 } else { 423 type = SEG_QUADTO; 424 coords[0] = (float)c.getCtrlX(); 425 coords[1] = (float)c.getCtrlY(); 426 coords[2] = (float)c.getX2(); 427 coords[3] = (float)c.getY2(); 428 count = 2; 429 } 430 if (t != null) { 431 t.transform(coords, 0, coords, 0, count); 432 } 433 return type; 434 } 435 436 } 437 438 /** 439 * Instantiates a new quadratic curve. 440 */ 441 protected QuadCurve2D() { 442 } 443 444 /** 445 * Gets the x coordinate of the starting point. 446 * 447 * @return the x coordinate of the starting point. 448 */ 449 public abstract double getX1(); 450 451 /** 452 * Gets the y coordinate of the starting point. 453 * 454 * @return the y coordinate of the starting point. 455 */ 456 public abstract double getY1(); 457 458 /** 459 * Gets the starting point. 460 * 461 * @return the starting point. 462 */ 463 public abstract Point2D getP1(); 464 465 /** 466 * Gets the x coordinate of the control point. 467 * 468 * @return the x coordinate of the control point. 469 */ 470 public abstract double getCtrlX(); 471 472 /** 473 * Gets the y coordinate of the control point. 474 * 475 * @return y coordinate of the control point. 476 */ 477 public abstract double getCtrlY(); 478 479 /** 480 * Gets the control point. 481 * 482 * @return the control point. 483 */ 484 public abstract Point2D getCtrlPt(); 485 486 /** 487 * Gets the x coordinate of the end point. 488 * 489 * @return the x coordinate of the end point. 490 */ 491 public abstract double getX2(); 492 493 /** 494 * Gets the y coordinate of the end point. 495 * 496 * @return the y coordinate of the end point. 497 */ 498 public abstract double getY2(); 499 500 /** 501 * Gets the end point. 502 * 503 * @return the end point. 504 */ 505 public abstract Point2D getP2(); 506 507 /** 508 * Sets the data of the curve. 509 * 510 * @param x1 511 * the x coordinate of the starting point of the curved segment. 512 * @param y1 513 * the y coordinate of the starting point of the curved segment. 514 * @param ctrlx 515 * the x coordinate of the control point. 516 * @param ctrly 517 * the y coordinate of the control point. 518 * @param x2 519 * the x coordinate of the end point of the curved segment. 520 * @param y2 521 * the y coordinate of the end point of the curved segment. 522 */ 523 public abstract void setCurve(double x1, double y1, double ctrlx, double ctrly, double x2, 524 double y2); 525 526 /** 527 * Sets the data of the curve. 528 * 529 * @param p1 530 * the starting point of the curved segment. 531 * @param cp 532 * the control point. 533 * @param p2 534 * the end point of the curved segment. 535 * @throws NullPointerException 536 * if any of the three points is null. 537 */ 538 public void setCurve(Point2D p1, Point2D cp, Point2D p2) { 539 setCurve(p1.getX(), p1.getY(), cp.getX(), cp.getY(), p2.getX(), p2.getY()); 540 } 541 542 /** 543 * Sets the data of the curve by reading the data from an array of values. 544 * The values are read in the same order as the arguments of the method 545 * {@link QuadCurve2D#setCurve(double, double, double, double, double, double)} 546 * . 547 * 548 * @param coords 549 * the array of values containing the new coordinates. 550 * @param offset 551 * the offset of the data to read within the array. 552 * @throws ArrayIndexOutOfBoundsException 553 * if {@code coords.length} < offset + 6. 554 * @throws NullPointerException 555 * if the coordinate array is null. 556 */ 557 public void setCurve(double[] coords, int offset) { 558 setCurve(coords[offset + 0], coords[offset + 1], coords[offset + 2], coords[offset + 3], 559 coords[offset + 4], coords[offset + 5]); 560 } 561 562 /** 563 * Sets the data of the curve by reading the data from an array of points. 564 * The values are read in the same order as the arguments of the method 565 * {@link QuadCurve2D#setCurve(Point2D, Point2D, Point2D)}. 566 * 567 * @param points 568 * the array of points containing the new coordinates. 569 * @param offset 570 * the offset of the data to read within the array. 571 * @throws ArrayIndexOutOfBoundsException 572 * if points.length < offset + 3. 573 * @throws NullPointerException 574 * if the point array is null. 575 */ 576 public void setCurve(Point2D[] points, int offset) { 577 setCurve(points[offset + 0].getX(), points[offset + 0].getY(), points[offset + 1].getX(), 578 points[offset + 1].getY(), points[offset + 2].getX(), points[offset + 2].getY()); 579 } 580 581 /** 582 * Sets the data of the curve by copying it from another QuadCurve2D. 583 * 584 * @param curve 585 * the curve to copy the data points from. 586 * @throws NullPointerException 587 * if the curve is null. 588 */ 589 public void setCurve(QuadCurve2D curve) { 590 setCurve(curve.getX1(), curve.getY1(), curve.getCtrlX(), curve.getCtrlY(), curve.getX2(), 591 curve.getY2()); 592 } 593 594 /** 595 * Gets the square of the distance from the control point to the straight 596 * line segment connecting the start point and the end point for this curve. 597 * 598 * @return the square of the distance from the control point to the straight 599 * line segment connecting the start point and the end point. 600 */ 601 public double getFlatnessSq() { 602 return Line2D.ptSegDistSq(getX1(), getY1(), getX2(), getY2(), getCtrlX(), getCtrlY()); 603 } 604 605 /** 606 * Gets the square of the distance from the control point to the straight 607 * line segment connecting the start point and the end point. 608 * 609 * @param x1 610 * the x coordinate of the starting point of the curved segment. 611 * @param y1 612 * the y coordinate of the starting point of the curved segment. 613 * @param ctrlx 614 * the x coordinate of the control point. 615 * @param ctrly 616 * the y coordinate of the control point. 617 * @param x2 618 * the x coordinate of the end point of the curved segment. 619 * @param y2 620 * the y coordinate of the end point of the curved segment. 621 * @return the square of the distance from the control point to the straight 622 * line segment connecting the start point and the end point. 623 */ 624 public static double getFlatnessSq(double x1, double y1, double ctrlx, double ctrly, double x2, 625 double y2) { 626 return Line2D.ptSegDistSq(x1, y1, x2, y2, ctrlx, ctrly); 627 } 628 629 /** 630 * Gets the square of the distance from the control point to the straight 631 * line segment connecting the start point and the end point by reading the 632 * coordinates of the points from an array of values. The values are read in 633 * the same order as the arguments of the method 634 * {@link QuadCurve2D#getFlatnessSq(double, double, double, double, double, double)} 635 * . 636 * 637 * @param coords 638 * the array of points containing the coordinates to use for the 639 * calculation 640 * @param offset 641 * the offset of the data to read within the array 642 * @return the square of the distance from the control point to the straight 643 * line segment connecting the start point and the end point. 644 * @throws ArrayIndexOutOfBoundsException 645 * if {@code coords.length} < offset + 6. 646 * @throws NullPointerException 647 * if the coordinate array is null. 648 */ 649 public static double getFlatnessSq(double coords[], int offset) { 650 return Line2D.ptSegDistSq(coords[offset + 0], coords[offset + 1], coords[offset + 4], 651 coords[offset + 5], coords[offset + 2], coords[offset + 3]); 652 } 653 654 /** 655 * Gets the distance from the control point to the straight line segment 656 * connecting the start point and the end point of this QuadCurve2D. 657 * 658 * @return the the distance from the control point to the straight line 659 * segment connecting the start point and the end point of this 660 * QuadCurve2D. 661 */ 662 public double getFlatness() { 663 return Line2D.ptSegDist(getX1(), getY1(), getX2(), getY2(), getCtrlX(), getCtrlY()); 664 } 665 666 /** 667 * Gets the distance from the control point to the straight line segment 668 * connecting the start point and the end point. 669 * 670 * @param x1 671 * the x coordinate of the starting point of the curved segment. 672 * @param y1 673 * the y coordinate of the starting point of the curved segment. 674 * @param ctrlx 675 * the x coordinate of the control point. 676 * @param ctrly 677 * the y coordinate of the control point. 678 * @param x2 679 * the x coordinate of the end point of the curved segment. 680 * @param y2 681 * the y coordinate of the end point of the curved segment. 682 * @return the the distance from the control point to the straight line 683 * segment connecting the start point and the end point. 684 */ 685 public static double getFlatness(double x1, double y1, double ctrlx, double ctrly, double x2, 686 double y2) { 687 return Line2D.ptSegDist(x1, y1, x2, y2, ctrlx, ctrly); 688 } 689 690 /** 691 * Gets the the distance from the control point to the straight line segment 692 * connecting the start point and the end point. The values are read in the 693 * same order as the arguments of the method 694 * {@link QuadCurve2D#getFlatness(double, double, double, double, double, double)} 695 * . 696 * 697 * @param coords 698 * the array of points containing the coordinates to use for the 699 * calculation. 700 * @param offset 701 * the offset of the data to read within the array. 702 * @return the the distance from the control point to the straight line 703 * segment connecting the start point and the end point. 704 * @throws ArrayIndexOutOfBoundsException 705 * if {code coords.length} < offset + 6. 706 * @throws NullPointerException 707 * if the coordinate array is null. 708 */ 709 public static double getFlatness(double coords[], int offset) { 710 return Line2D.ptSegDist(coords[offset + 0], coords[offset + 1], coords[offset + 4], 711 coords[offset + 5], coords[offset + 2], coords[offset + 3]); 712 } 713 714 /** 715 * Creates the data for two quadratic curves by dividing this curve in two. 716 * The division point is the point on the curve that is closest to this 717 * curve's control point. The data of this curve is left unchanged. 718 * 719 * @param left 720 * the QuadCurve2D where the left (start) segment's data is 721 * written. 722 * @param right 723 * the QuadCurve2D where the right (end) segment's data is 724 * written. 725 * @throws NullPointerException 726 * if either curve is null. 727 */ 728 public void subdivide(QuadCurve2D left, QuadCurve2D right) { 729 subdivide(this, left, right); 730 } 731 732 /** 733 * Creates the data for two quadratic curves by dividing a source curve in 734 * two. The division point is the point on the curve that is closest to the 735 * source curve's control point. The data of the source curve is left 736 * unchanged. 737 * 738 * @param src 739 * the curve that provides the initial data. 740 * @param left 741 * the QuadCurve2D where the left (start) segment's data is 742 * written. 743 * @param right 744 * the QuadCurve2D where the right (end) segment's data is 745 * written. 746 * @throws NullPointerException 747 * if one of the curves is null. 748 */ 749 public static void subdivide(QuadCurve2D src, QuadCurve2D left, QuadCurve2D right) { 750 double x1 = src.getX1(); 751 double y1 = src.getY1(); 752 double cx = src.getCtrlX(); 753 double cy = src.getCtrlY(); 754 double x2 = src.getX2(); 755 double y2 = src.getY2(); 756 double cx1 = (x1 + cx) / 2.0; 757 double cy1 = (y1 + cy) / 2.0; 758 double cx2 = (x2 + cx) / 2.0; 759 double cy2 = (y2 + cy) / 2.0; 760 cx = (cx1 + cx2) / 2.0; 761 cy = (cy1 + cy2) / 2.0; 762 if (left != null) { 763 left.setCurve(x1, y1, cx1, cy1, cx, cy); 764 } 765 if (right != null) { 766 right.setCurve(cx, cy, cx2, cy2, x2, y2); 767 } 768 } 769 770 /** 771 * Creates the data for two quadratic curves by dividing a source curve in 772 * two. The division point is the point on the curve that is closest to the 773 * source curve's control point. The data for the three curves is read and 774 * written from arrays of values in the usual order: x1, y1, cx, cy, x2, y2. 775 * 776 * @param src 777 * the array that gives the data values for the source curve. 778 * @param srcoff 779 * the offset in the src array to read the values from. 780 * @param left 781 * the array where the coordinates of the start curve should be 782 * written. 783 * @param leftOff 784 * the offset in the left array to start writing the values. 785 * @param right 786 * the array where the coordinates of the end curve should be 787 * written. 788 * @param rightOff 789 * the offset in the right array to start writing the values. 790 * @throws ArrayIndexOutOfBoundsException 791 * if {@code src.length} < srcoff + 6 or if {@code left.length} 792 * < leftOff + 6 or if {@code right.length} < rightOff + 6. 793 * @throws NullPointerException 794 * if one of the arrays is null. 795 */ 796 public static void subdivide(double src[], int srcoff, double left[], int leftOff, 797 double right[], int rightOff) { 798 double x1 = src[srcoff + 0]; 799 double y1 = src[srcoff + 1]; 800 double cx = src[srcoff + 2]; 801 double cy = src[srcoff + 3]; 802 double x2 = src[srcoff + 4]; 803 double y2 = src[srcoff + 5]; 804 double cx1 = (x1 + cx) / 2.0; 805 double cy1 = (y1 + cy) / 2.0; 806 double cx2 = (x2 + cx) / 2.0; 807 double cy2 = (y2 + cy) / 2.0; 808 cx = (cx1 + cx2) / 2.0; 809 cy = (cy1 + cy2) / 2.0; 810 if (left != null) { 811 left[leftOff + 0] = x1; 812 left[leftOff + 1] = y1; 813 left[leftOff + 2] = cx1; 814 left[leftOff + 3] = cy1; 815 left[leftOff + 4] = cx; 816 left[leftOff + 5] = cy; 817 } 818 if (right != null) { 819 right[rightOff + 0] = cx; 820 right[rightOff + 1] = cy; 821 right[rightOff + 2] = cx2; 822 right[rightOff + 3] = cy2; 823 right[rightOff + 4] = x2; 824 right[rightOff + 5] = y2; 825 } 826 } 827 828 /** 829 * Finds the roots of the quadratic polynomial. This is accomplished by 830 * finding the (real) values of x that solve the following equation: 831 * eqn[2]*x*x + eqn[1]*x + eqn[0] = 0. The solutions are written back into 832 * the array eqn starting from the index 0 in the array. The return value 833 * tells how many array elements have been changed by this method call. 834 * 835 * @param eqn 836 * an array containing the coefficients of the quadratic 837 * polynomial to solve. 838 * @return the number of roots of the quadratic polynomial. 839 * @throws ArrayIndexOutOfBoundsException 840 * if {@code eqn.length} < 3. 841 * @throws NullPointerException 842 * if the array is null. 843 */ 844 public static int solveQuadratic(double eqn[]) { 845 return solveQuadratic(eqn, eqn); 846 } 847 848 /** 849 * Finds the roots of the quadratic polynomial. This is accomplished by 850 * finding the (real) values of x that solve the following equation: 851 * eqn[2]*x*x + eqn[1]*x + eqn[0] = 0. The solutions are written into the 852 * array res starting from the index 0 in the array. The return value tells 853 * how many array elements have been written by this method call. 854 * 855 * @param eqn 856 * an array containing the coefficients of the quadratic 857 * polynomial to solve. 858 * @param res 859 * the array that this method writes the results into. 860 * @return the number of roots of the quadratic polynomial. 861 * @throws ArrayIndexOutOfBoundsException 862 * if {@code eqn.length} < 3 or if {@code res.length} is less 863 * than the number of roots. 864 * @throws NullPointerException 865 * if either array is null. 866 */ 867 public static int solveQuadratic(double eqn[], double res[]) { 868 return Crossing.solveQuad(eqn, res); 869 } 870 871 public boolean contains(double px, double py) { 872 return Crossing.isInsideEvenOdd(Crossing.crossShape(this, px, py)); 873 } 874 875 public boolean contains(double rx, double ry, double rw, double rh) { 876 int cross = Crossing.intersectShape(this, rx, ry, rw, rh); 877 return cross != Crossing.CROSSING && Crossing.isInsideEvenOdd(cross); 878 } 879 880 public boolean intersects(double rx, double ry, double rw, double rh) { 881 int cross = Crossing.intersectShape(this, rx, ry, rw, rh); 882 return cross == Crossing.CROSSING || Crossing.isInsideEvenOdd(cross); 883 } 884 885 public boolean contains(Point2D p) { 886 return contains(p.getX(), p.getY()); 887 } 888 889 public boolean intersects(Rectangle2D r) { 890 return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight()); 891 } 892 893 public boolean contains(Rectangle2D r) { 894 return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight()); 895 } 896 897 public Rectangle getBounds() { 898 return getBounds2D().getBounds(); 899 } 900 901 public PathIterator getPathIterator(AffineTransform t) { 902 return new Iterator(this, t); 903 } 904 905 public PathIterator getPathIterator(AffineTransform t, double flatness) { 906 return new FlatteningPathIterator(getPathIterator(t), flatness); 907 } 908 909 @Override 910 public Object clone() { 911 try { 912 return super.clone(); 913 } catch (CloneNotSupportedException e) { 914 throw new InternalError(); 915 } 916 } 917 918} 919