1600 */ |
1600 */ |
1601 public boolean contains(double x, double y, double w, double h) { |
1601 public boolean contains(double x, double y, double w, double h) { |
1602 if (w <= 0 || h <= 0) { |
1602 if (w <= 0 || h <= 0) { |
1603 return false; |
1603 return false; |
1604 } |
1604 } |
1605 // Assertion: Cubic curves closed by connecting their |
1605 |
1606 // endpoints form either one or two convex halves with |
1606 int numCrossings = rectCrossings(x, y, w, h); |
1607 // the closing line segment as an edge of both sides. |
1607 return !(numCrossings == 0 || numCrossings == Curve.RECT_INTERSECTS); |
1608 if (!(contains(x, y) && |
1608 } |
1609 contains(x + w, y) && |
1609 |
1610 contains(x + w, y + h) && |
1610 private int rectCrossings(double x, double y, double w, double h) { |
1611 contains(x, y + h))) { |
1611 int crossings = 0; |
1612 return false; |
1612 if (!(getX1() == getX2() && getY1() == getY2())) { |
1613 } |
1613 crossings = Curve.rectCrossingsForLine(crossings, |
1614 // Either the rectangle is entirely inside one of the convex |
1614 x, y, |
1615 // halves or it crosses from one to the other, in which case |
1615 x+w, y+h, |
1616 // it must intersect the closing line segment. |
1616 getX1(), getY1(), |
1617 Rectangle2D rect = new Rectangle2D.Double(x, y, w, h); |
1617 getX2(), getY2()); |
1618 return !rect.intersectsLine(getX1(), getY1(), getX2(), getY2()); |
1618 if (crossings == Curve.RECT_INTERSECTS) { |
|
1619 return crossings; |
|
1620 } |
|
1621 } |
|
1622 // we call this with the curve's direction reversed, because we wanted |
|
1623 // to call rectCrossingsForLine first, because it's cheaper. |
|
1624 return Curve.rectCrossingsForCubic(crossings, |
|
1625 x, y, |
|
1626 x+w, y+h, |
|
1627 getX2(), getY2(), |
|
1628 getCtrlX2(), getCtrlY2(), |
|
1629 getCtrlX1(), getCtrlY1(), |
|
1630 getX1(), getY1(), 0); |
1619 } |
1631 } |
1620 |
1632 |
1621 /** |
1633 /** |
1622 * {@inheritDoc} |
1634 * {@inheritDoc} |
1623 * @since 1.2 |
1635 * @since 1.2 |