Added Arc and friends.
This commit is contained in:
@@ -0,0 +1,356 @@
|
||||
//
|
||||
// $Id$
|
||||
|
||||
package pythagoras.f;
|
||||
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
/**
|
||||
* Provides most of the implementation of {@link IArc}, obtaining only the frame and other metrics
|
||||
* from the derived class.
|
||||
*/
|
||||
public abstract class AbstractArc extends RectangularShape implements IArc
|
||||
{
|
||||
@Override // from interface IArc
|
||||
public Point getStartPoint () {
|
||||
return getStartPoint(new Point());
|
||||
}
|
||||
|
||||
@Override // from interface IArc
|
||||
public Point getStartPoint (Point target) {
|
||||
float a = (float)Math.toRadians(getAngleStart());
|
||||
target.setLocation(getX() + (1f + (float)Math.cos(a)) * getWidth() / 2f,
|
||||
getY() + (1f - (float)Math.sin(a)) * getHeight() / 2f);
|
||||
return target;
|
||||
}
|
||||
|
||||
@Override // from interface IArc
|
||||
public Point getEndPoint () {
|
||||
return getEndPoint(new Point());
|
||||
}
|
||||
|
||||
@Override // from interface IArc
|
||||
public Point getEndPoint (Point target) {
|
||||
float a = (float)Math.toRadians(getAngleStart() + getAngleExtent());
|
||||
target.setLocation(getX() + (1f + (float)Math.cos(a)) * getWidth() / 2f,
|
||||
getY() + (1f - (float)Math.sin(a)) * getHeight() / 2f);
|
||||
return target;
|
||||
}
|
||||
|
||||
@Override // from interface IArc
|
||||
public boolean containsAngle (float angle) {
|
||||
float extent = getAngleExtent();
|
||||
if (extent >= 360f) {
|
||||
return true;
|
||||
}
|
||||
angle = getNormAngle(angle);
|
||||
float a1 = getNormAngle(getAngleStart());
|
||||
float a2 = a1 + extent;
|
||||
if (a2 > 360f) {
|
||||
return angle >= a1 || angle <= a2 - 360f;
|
||||
}
|
||||
if (a2 < 0f) {
|
||||
return angle >= a2 + 360f || angle <= a1;
|
||||
}
|
||||
return (extent > 0f) ? a1 <= angle && angle <= a2 : a2 <= angle && angle <= a1;
|
||||
}
|
||||
|
||||
@Override // from interface IArc
|
||||
public Arc clone () {
|
||||
return new Arc(getX(), getY(), getWidth(), getHeight(), getAngleStart(), getAngleExtent(),
|
||||
getArcType());
|
||||
}
|
||||
|
||||
@Override // from RectangularShape
|
||||
public boolean isEmpty () {
|
||||
return getArcType() == OPEN || super.isEmpty();
|
||||
}
|
||||
|
||||
@Override // from RectangularShape
|
||||
public boolean contains (float px, float py) {
|
||||
// normalize point
|
||||
float nx = (px - getX()) / getWidth() - 0.5f;
|
||||
float ny = (py - getY()) / getHeight() - 0.5f;
|
||||
if ((nx * nx + ny * ny) > 0.25) {
|
||||
return false;
|
||||
}
|
||||
|
||||
float extent = getAngleExtent();
|
||||
float absExtent = Math.abs(extent);
|
||||
if (absExtent >= 360f) {
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean containsAngle = containsAngle((float)Math.toDegrees(-Math.atan2(ny, nx)));
|
||||
if (getArcType() == PIE) {
|
||||
return containsAngle;
|
||||
}
|
||||
if (absExtent <= 180f && !containsAngle) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Line l = new Line(getStartPoint(), getEndPoint());
|
||||
int ccw1 = l.relativeCCW(px, py);
|
||||
int ccw2 = l.relativeCCW(getCenterX(), getCenterY());
|
||||
return ccw1 == 0 || ccw2 == 0 || ((ccw1 + ccw2) == 0 ^ absExtent > 180f);
|
||||
}
|
||||
|
||||
@Override // from RectangularShape
|
||||
public boolean contains (float rx, float ry, float rw, float rh) {
|
||||
if (!(contains(rx, ry) && contains(rx + rw, ry) &&
|
||||
contains(rx + rw, ry + rh) && contains(rx, ry + rh))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
float absExtent = Math.abs(getAngleExtent());
|
||||
if (getArcType() != PIE || absExtent <= 180f || absExtent >= 360f) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Rectangle r = new Rectangle(rx, ry, rw, rh);
|
||||
float cx = getCenterX(), cy = getCenterY();
|
||||
if (r.contains(cx, cy)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Point p1 = getStartPoint(), p2 = getEndPoint();
|
||||
return !r.intersectsLine(cx, cy, p1.getX(), p1.getY()) &&
|
||||
!r.intersectsLine(cx, cy, p2.getX(), p2.getY());
|
||||
}
|
||||
|
||||
@Override // from RectangularShape
|
||||
public boolean intersects (float rx, float ry, float rw, float rh) {
|
||||
if (isEmpty() || rw <= 0f || rh <= 0f) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// check: does arc contain rectangle's points
|
||||
if (contains(rx, ry) || contains(rx + rw, ry) ||
|
||||
contains(rx, ry + rh) || contains(rx + rw, ry + rh)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
float cx = getCenterX(), cy = getCenterY();
|
||||
Point p1 = getStartPoint(), p2 = getEndPoint();
|
||||
|
||||
// check: does rectangle contain arc's points
|
||||
Rectangle r = new Rectangle(rx, ry, rw, rh);
|
||||
if (r.contains(p1) || r.contains(p2) || (getArcType() == PIE && r.contains(cx, cy))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (getArcType() == PIE) {
|
||||
if (r.intersectsLine(p1.getX(), p1.getY(), cx, cy) ||
|
||||
r.intersectsLine(p2.getX(), p2.getY(), cx, cy)) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (r.intersectsLine(p1.getX(), p1.getY(), p2.getX(), p2.getY())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// nearest rectangle point
|
||||
float nx = cx < rx ? rx : (cx > rx + rw ? rx + rw : cx);
|
||||
float ny = cy < ry ? ry : (cy > ry + rh ? ry + rh : cy);
|
||||
return contains(nx, ny);
|
||||
}
|
||||
|
||||
@Override // from RectangularShape
|
||||
public Rectangle getBounds (Rectangle target) {
|
||||
if (isEmpty()) {
|
||||
target.setBounds(getX(), getY(), getWidth(), getHeight());
|
||||
return target;
|
||||
}
|
||||
|
||||
float rx1 = getX();
|
||||
float ry1 = getY();
|
||||
float rx2 = rx1 + getWidth();
|
||||
float ry2 = ry1 + getHeight();
|
||||
|
||||
Point p1 = getStartPoint(), p2 = getEndPoint();
|
||||
|
||||
float bx1 = containsAngle(180f) ? rx1 : Math.min(p1.getX(), p2.getX());
|
||||
float by1 = containsAngle(90f) ? ry1 : Math.min(p1.getY(), p2.getY());
|
||||
float bx2 = containsAngle(0f) ? rx2 : Math.max(p1.getX(), p2.getX());
|
||||
float by2 = containsAngle(270f) ? ry2 : Math.max(p1.getY(), p2.getY());
|
||||
|
||||
if (getArcType() == PIE) {
|
||||
float cx = getCenterX();
|
||||
float cy = getCenterY();
|
||||
bx1 = Math.min(bx1, cx);
|
||||
by1 = Math.min(by1, cy);
|
||||
bx2 = Math.max(bx2, cx);
|
||||
by2 = Math.max(by2, cy);
|
||||
}
|
||||
target.setBounds(bx1, by1, bx2 - bx1, by2 - by1);
|
||||
return target;
|
||||
}
|
||||
|
||||
@Override // from interface IShape
|
||||
public PathIterator getPathIterator (AffineTransform at) {
|
||||
return new Iterator(this, at);
|
||||
}
|
||||
|
||||
/** Returns a normalized angle (bound between 0 and 360 degrees). */
|
||||
protected float getNormAngle (float angle) {
|
||||
return angle - (float)Math.floor(angle / 360f) * 360f;
|
||||
}
|
||||
|
||||
/** An iterator over an {@link IArc}. */
|
||||
protected static class Iterator implements PathIterator
|
||||
{
|
||||
/** The x coordinate of left-upper corner of the arc rectangle bounds */
|
||||
private float x;
|
||||
|
||||
/** The y coordinate of left-upper corner of the arc rectangle bounds */
|
||||
private float y;
|
||||
|
||||
/** The width of the arc rectangle bounds */
|
||||
private float width;
|
||||
|
||||
/** The height of the arc rectangle bounds */
|
||||
private float height;
|
||||
|
||||
/** The start angle of the arc in degrees */
|
||||
private float angle;
|
||||
|
||||
/** The angle extent in degrees */
|
||||
private float extent;
|
||||
|
||||
/** The closure type of the arc */
|
||||
private int type;
|
||||
|
||||
/** The path iterator transformation */
|
||||
private AffineTransform t;
|
||||
|
||||
/** The current segmenet index */
|
||||
private int index;
|
||||
|
||||
/** The number of arc segments the source arc subdivided to be approximated by Bezier
|
||||
* curves. Depends on extent value. */
|
||||
private int arcCount;
|
||||
|
||||
/** The number of line segments. Depends on closure type. */
|
||||
private int lineCount;
|
||||
|
||||
/** The step to calculate next arc subdivision point */
|
||||
private float step;
|
||||
|
||||
/** The tempopary value of cosinus of the current angle */
|
||||
private float cos;
|
||||
|
||||
/** The tempopary value of sinus of the current angle */
|
||||
private float sin;
|
||||
|
||||
/** The coefficient to calculate control points of Bezier curves */
|
||||
private float k;
|
||||
|
||||
/** The tempopary value of x coordinate of the Bezier curve control vector */
|
||||
private float kx;
|
||||
|
||||
/** The tempopary value of y coordinate of the Bezier curve control vector */
|
||||
private float ky;
|
||||
|
||||
/** The x coordinate of the first path point (MOVE_TO) */
|
||||
private float mx;
|
||||
|
||||
/** The y coordinate of the first path point (MOVE_TO) */
|
||||
private float my;
|
||||
|
||||
Iterator (IArc a, AffineTransform t) {
|
||||
this.width = a.getWidth() / 2f;
|
||||
this.height = a.getHeight() / 2f;
|
||||
this.x = a.getX() + width;
|
||||
this.y = a.getY() + height;
|
||||
this.angle = -(float)Math.toRadians(a.getAngleStart());
|
||||
this.extent = -a.getAngleExtent();
|
||||
this.type = a.getArcType();
|
||||
this.t = t;
|
||||
|
||||
if (width < 0 || height < 0) {
|
||||
arcCount = 0;
|
||||
lineCount = 0;
|
||||
index = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (Math.abs(extent) >= 360f) {
|
||||
arcCount = 4;
|
||||
k = 4f / 3f * ((float)Math.sqrt(2f) - 1f);
|
||||
step = (float)Math.PI / 2f;
|
||||
if (extent < 0f) {
|
||||
step = -step;
|
||||
k = -k;
|
||||
}
|
||||
} else {
|
||||
arcCount = (int)Math.rint(Math.abs(extent) / 90f);
|
||||
step = (float)Math.toRadians(extent / arcCount);
|
||||
k = 4f / 3f * (1f - (float)Math.cos(step / 2f)) / (float)Math.sin(step / 2f);
|
||||
}
|
||||
|
||||
lineCount = 0;
|
||||
if (type == CHORD) {
|
||||
lineCount++;
|
||||
} else if (type == PIE) {
|
||||
lineCount += 2;
|
||||
}
|
||||
}
|
||||
|
||||
@Override public int getWindingRule () {
|
||||
return WIND_NON_ZERO;
|
||||
}
|
||||
|
||||
@Override public boolean isDone () {
|
||||
return index > arcCount + lineCount;
|
||||
}
|
||||
|
||||
@Override public void next () {
|
||||
index++;
|
||||
}
|
||||
|
||||
@Override public int currentSegment (float[] coords) {
|
||||
if (isDone()) {
|
||||
throw new NoSuchElementException("Iterator out of bounds");
|
||||
}
|
||||
int type;
|
||||
int count;
|
||||
if (index == 0) {
|
||||
type = SEG_MOVETO;
|
||||
count = 1;
|
||||
cos = (float)Math.cos(angle);
|
||||
sin = (float)Math.sin(angle);
|
||||
kx = k * width * sin;
|
||||
ky = k * height * cos;
|
||||
coords[0] = mx = x + cos * width;
|
||||
coords[1] = my = y + sin * height;
|
||||
} else if (index <= arcCount) {
|
||||
type = SEG_CUBICTO;
|
||||
count = 3;
|
||||
coords[0] = mx - kx;
|
||||
coords[1] = my + ky;
|
||||
angle += step;
|
||||
cos = (float)Math.cos(angle);
|
||||
sin = (float)Math.sin(angle);
|
||||
kx = k * width * sin;
|
||||
ky = k * height * cos;
|
||||
coords[4] = mx = x + cos * width;
|
||||
coords[5] = my = y + sin * height;
|
||||
coords[2] = mx + kx;
|
||||
coords[3] = my - ky;
|
||||
} else if (index == arcCount + lineCount) {
|
||||
type = SEG_CLOSE;
|
||||
count = 0;
|
||||
} else {
|
||||
type = SEG_LINETO;
|
||||
count = 1;
|
||||
coords[0] = x;
|
||||
coords[1] = y;
|
||||
}
|
||||
if (t != null) {
|
||||
t.transform(coords, 0, coords, 0, count);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,239 @@
|
||||
//
|
||||
// $Id$
|
||||
|
||||
package pythagoras.f;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Represents an arc defined by a framing rectangle, start angle, angular extend, and closure type.
|
||||
*/
|
||||
public class Arc extends AbstractArc implements Serializable
|
||||
{
|
||||
/** The x-coordinate of this arc's framing rectangle. */
|
||||
public float x;
|
||||
|
||||
/** The y-coordinate of this arc's framing rectangle. */
|
||||
public float y;
|
||||
|
||||
/** The width of this arc's framing rectangle. */
|
||||
public float width;
|
||||
|
||||
/** The height of this arc's framing rectangle. */
|
||||
public float height;
|
||||
|
||||
/** The starting angle of this arc. */
|
||||
public float start;
|
||||
|
||||
/** The angular extent of this arc. */
|
||||
public float extent;
|
||||
|
||||
/**
|
||||
* Creates an open arc with frame (0x0+0+0) and zero angles.
|
||||
*/
|
||||
public Arc () {
|
||||
this(OPEN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an arc of the specified type with frame (0x0+0+0) and zero angles.
|
||||
*/
|
||||
public Arc (int type) {
|
||||
setArcType(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an arc of the specified type with the specified framing rectangle, starting angle
|
||||
* and angular extent.
|
||||
*/
|
||||
public Arc (float x, float y, float width, float height, float start, float extent, int type) {
|
||||
setArc(x, y, width, height, start, extent, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an arc of the specified type with the supplied framing rectangle, starting angle and
|
||||
* angular extent.
|
||||
*/
|
||||
public Arc (IRectangle bounds, float start, float extent, int type) {
|
||||
setArc(bounds.getX(), bounds.getY(), bounds.getWidth(), bounds.getHeight(),
|
||||
start, extent, type);
|
||||
}
|
||||
|
||||
@Override // from interface IArc
|
||||
public int getArcType () {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override // from interface IArc
|
||||
public float getX () {
|
||||
return x;
|
||||
}
|
||||
|
||||
@Override // from interface IArc
|
||||
public float getY () {
|
||||
return y;
|
||||
}
|
||||
|
||||
@Override // from interface IArc
|
||||
public float getWidth () {
|
||||
return width;
|
||||
}
|
||||
|
||||
@Override // from interface IArc
|
||||
public float getHeight () {
|
||||
return height;
|
||||
}
|
||||
|
||||
@Override // from interface IArc
|
||||
public float getAngleStart () {
|
||||
return start;
|
||||
}
|
||||
|
||||
@Override // from interface IArc
|
||||
public float getAngleExtent () {
|
||||
return extent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the type of this arc to the specified value.
|
||||
*/
|
||||
public void setArcType (int type) {
|
||||
if (type != OPEN && type != CHORD && type != PIE) {
|
||||
throw new IllegalArgumentException("Invalid Arc type: " + type);
|
||||
}
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the starting angle of this arc to the specified value.
|
||||
*/
|
||||
public void setAngleStart (float start) {
|
||||
this.start = start;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the angular extent of this arc to the specified value.
|
||||
*/
|
||||
public void setAngleExtent (float extent) {
|
||||
this.extent = extent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the location, size, angular extents, and closure type of this arc to the specified
|
||||
* values.
|
||||
*/
|
||||
public void setArc (float x, float y, float width, float height,
|
||||
float start, float extent, int type) {
|
||||
setArcType(type);
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.start = start;
|
||||
this.extent = extent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the location, size, angular extents, and closure type of this arc to the specified
|
||||
* values.
|
||||
*/
|
||||
public void setArc (IPoint point, IDimension size, float start, float extent, int type) {
|
||||
setArc(point.getX(), point.getY(), size.getWidth(), size.getHeight(), start, extent, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the location, size, angular extents, and closure type of this arc to the specified
|
||||
* values.
|
||||
*/
|
||||
public void setArc (IRectangle rect, float start, float extent, int type) {
|
||||
setArc(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight(), start, extent, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the location, size, angular extents, and closure type of this arc to the same values as
|
||||
* the supplied arc.
|
||||
*/
|
||||
public void setArc (IArc arc) {
|
||||
setArc(arc.getX(), arc.getY(), arc.getWidth(), arc.getHeight(), arc.getAngleStart(),
|
||||
arc.getAngleExtent(), arc.getArcType());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the location, size, angular extents, and closure type of this arc based on the
|
||||
* specified values.
|
||||
*/
|
||||
public void setArcByCenter (float x, float y, float radius,
|
||||
float start, float extent, int type) {
|
||||
setArc(x - radius, y - radius, radius * 2f, radius * 2f, start, extent, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the location, size, angular extents, and closure type of this arc based on the
|
||||
* specified values.
|
||||
*/
|
||||
public void setArcByTangent (IPoint p1, IPoint p2, IPoint p3, float radius) {
|
||||
// use simple geometric calculations of arc center, radius and angles by tangents
|
||||
float a1 = -(float)Math.atan2(p1.getY() - p2.getY(), p1.getX() - p2.getX());
|
||||
float a2 = -(float)Math.atan2(p3.getY() - p2.getY(), p3.getX() - p2.getX());
|
||||
float am = (a1 + a2) / 2f;
|
||||
float ah = a1 - am;
|
||||
float d = radius / Math.abs((float)Math.sin(ah));
|
||||
float x = p2.getX() + d * (float)Math.cos(am);
|
||||
float y = p2.getY() - d * (float)Math.sin(am);
|
||||
ah = ah >= 0f ? (float)Math.PI * 1.5f - ah : (float)Math.PI * 0.5f - ah;
|
||||
a1 = getNormAngle((float)Math.toDegrees(am - ah));
|
||||
a2 = getNormAngle((float)Math.toDegrees(am + ah));
|
||||
float delta = a2 - a1;
|
||||
if (delta <= 0f) {
|
||||
delta += 360f;
|
||||
}
|
||||
setArcByCenter(x, y, radius, a1, delta, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the starting angle of this arc to the angle defined by the supplied point relative to
|
||||
* the center of this arc.
|
||||
*/
|
||||
public void setAngleStart (IPoint point) {
|
||||
float angle = (float)Math.atan2(point.getY() - getCenterY(), point.getX() - getCenterX());
|
||||
setAngleStart(getNormAngle(-(float)Math.toDegrees(angle)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the starting angle and angular extent of this arc using two sets of coordinates. The
|
||||
* first set of coordinates is used to determine the angle of the starting point relative to
|
||||
* the arc's center. The second set of coordinates is used to determine the angle of the end
|
||||
* point relative to the arc's center. The arc will always be non-empty and extend
|
||||
* counterclockwise from the first point around to the second point.
|
||||
*/
|
||||
public void setAngles (float x1, float y1, float x2, float y2) {
|
||||
float cx = getCenterX();
|
||||
float cy = getCenterY();
|
||||
float a1 = getNormAngle(-(float)Math.toDegrees(Math.atan2(y1 - cy, x1 - cx)));
|
||||
float a2 = getNormAngle(-(float)Math.toDegrees(Math.atan2(y2 - cy, x2 - cx)));
|
||||
a2 -= a1;
|
||||
if (a2 <= 0f) {
|
||||
a2 += 360f;
|
||||
}
|
||||
setAngleStart(a1);
|
||||
setAngleExtent(a2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the starting angle and angular extent of this arc using two sets of coordinates. The
|
||||
* first set of coordinates is used to determine the angle of the starting point relative to
|
||||
* the arc's center. The second set of coordinates is used to determine the angle of the end
|
||||
* point relative to the arc's center. The arc will always be non-empty and extend
|
||||
* counterclockwise from the first point around to the second point.
|
||||
*/
|
||||
public void setAngles (IPoint p1, IPoint p2) {
|
||||
setAngles(p1.getX(), p1.getY(), p2.getX(), p2.getY());
|
||||
}
|
||||
|
||||
@Override // from RectangularShape
|
||||
public void setFrame (float x, float y, float width, float height) {
|
||||
setArc(x, y, width, height, getAngleStart(), getAngleExtent(), type);
|
||||
}
|
||||
|
||||
private int type;
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
//
|
||||
// $Id$
|
||||
|
||||
package pythagoras.f;
|
||||
|
||||
/**
|
||||
* Provides read-only access to an {@link Arc}.
|
||||
*/
|
||||
public interface IArc extends IRectangularShape, Cloneable
|
||||
{
|
||||
/** An arc type indicating a simple, unconnected curve. */
|
||||
int OPEN = 0;
|
||||
|
||||
/** An arc type indicating a closed curve, connected by a straight line from the starting to
|
||||
* the ending point of the arc. */
|
||||
int CHORD = 1;
|
||||
|
||||
/** An arc type indicating a closed curve, connected by a line from the starting point of the
|
||||
* arc to the center of the circle defining the arc, and another straight line from that center
|
||||
* to the ending point of the arc. */
|
||||
int PIE = 2;
|
||||
|
||||
/** Returns the type of this arc: {@link #OPEN}, etc. */
|
||||
int getArcType ();
|
||||
|
||||
/** Returns the starting angle of this arc. */
|
||||
float getAngleStart ();
|
||||
|
||||
/** Returns the angular extent of this arc. */
|
||||
float getAngleExtent ();
|
||||
|
||||
/** Returns the intersection of the ray from the center (defined by the starting angle) and the
|
||||
* elliptical boundary of the arc. */
|
||||
Point getStartPoint ();
|
||||
|
||||
/** Writes the intersection of the ray from the center (defined by the starting angle) and the
|
||||
* elliptical boundary of the arc into {@code target}.
|
||||
* @return the supplied point. */
|
||||
Point getStartPoint (Point target);
|
||||
|
||||
/** Returns the intersection of the ray from the center (defined by the starting angle plus the
|
||||
* angular extent of the arc) and the elliptical boundary of the arc. */
|
||||
Point getEndPoint ();
|
||||
|
||||
/** Writes the intersection of the ray from the center (defined by the starting angle plus the
|
||||
* angular extent of the arc) and the elliptical boundary of the arc into {@code target}.
|
||||
* @return the supplied point. */
|
||||
Point getEndPoint (Point target);
|
||||
|
||||
/** Returns whether the specified angle is within the angular extents of this arc. */
|
||||
boolean containsAngle (float angle);
|
||||
|
||||
/** Returns a mutable copy of this arc. */
|
||||
Arc clone ();
|
||||
}
|
||||
Reference in New Issue
Block a user