arc2d.java
来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· Java 代码 · 共 1,091 行 · 第 1/3 页
JAVA
1,091 行
protected abstract Rectangle2D makeBounds(double x, double y, double w, double h);
/**
* Tests if the given angle, in degrees, is included in the arc.
*
* XXX Does this normalize all angles to -180 - 180 first?
*
* @param a the angle to test
* @return true if it is contained
*/
public boolean containsAngle(double a) {
// XXX Implement.
throw new Error("not implemented");
}
/**
* Determines if the arc contains the given point. If the bounding box
* is empty, then this will return false.
*
* @param x the x coordinate to test
* @param y the y coordinate to test
* @return true if the point is inside the arc
*/
public boolean contains(double x, double y) {
double w = getWidth();
double h = getHeight();
if (w <= 0 || h <= 0)
return false;
// XXX Finish implementing.
throw new Error("not implemented");
}
/**
* Tests if a given rectangle intersects the area of the arc.
*
* @param x the x coordinate of the rectangle
* @param y the y coordinate of the rectangle
* @param w the width of the rectangle
* @param h the height of the rectangle
* @return true if the two shapes share common points
*/
public boolean intersects(double x, double y, double w, double h) {
double mw = getWidth();
double mh = getHeight();
if (mw <= 0 || mh <= 0 || w <= 0 || h <= 0)
return false;
// XXX Finish implementing.
throw new Error("not implemented");
}
/**
* Tests if a given rectangle is contained in the area of the arc.
*
* @param x the x coordinate of the rectangle
* @param y the y coordinate of the rectangle
* @param w the width of the rectangle
* @param h the height of the rectangle
* @return true if the arc contains the rectangle
*/
public boolean contains(double x, double y, double w, double h) {
double mw = getWidth();
double mh = getHeight();
if (mw <= 0 || mh <= 0 || w <= 0 || h <= 0)
return false;
// XXX Finish implementing.
throw new Error("not implemented");
}
/**
* Tests if a given rectangle is contained in the area of the arc.
*
* @param r the rectangle
* @return true if the arc contains the rectangle
*/
public boolean contains(Rectangle2D r) {
return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight());
}
/**
* Returns an iterator over this arc, with an optional transformation.
* This iterator is threadsafe, so future modifications to the arc do not
* affect the iteration.
*
* @param at the transformation, or null
* @return a path iterator
*/
public PathIterator getPathIterator(AffineTransform at) {
return new ArcIterator(this, at);
}
/**
* This class is used to iterate over an arc. Since ellipses are a subclass
* of arcs, this is used by Ellipse2D as well.
*
* @author Eric Blake <ebb9@email.byu.edu>
*/
static final class ArcIterator implements PathIterator {
/** The current iteration. */
private int current;
/** The last iteration. */
private final int limit;
/** The optional transformation. */
private final AffineTransform xform;
/** The x coordinate of the bounding box. */
private final double x;
/** The y coordinate of the bounding box. */
private final double y;
/** The width of the bounding box. */
private final double w;
/** The height of the bounding box. */
private final double h;
/** The start angle, in radians (not degrees). */
private final double startAngRad;
/** The extent angle, in radians (not degrees). */
private final double extentAngRad;
/** The arc closure type. */
private final int type;
private final double angExtDeg;
private final double increment;
/**
* Construct a new iterator over an arc.
*
* @param a the arc
* @param xform the transform
*/
ArcIterator(Arc2D a, AffineTransform xform) {
this.xform = xform;
x = a.getX();
y = a.getY();
w = a.getWidth();
h = a.getHeight();
angExtDeg = a.getAngleExtent();
startAngRad = a.getAngleStart() * (Math.PI / 180);
extentAngRad = angExtDeg * (Math.PI / 180);
type = a.getArcType();
double e = extentAngRad < 0 ? -extentAngRad : extentAngRad;
if (w < 0 || h < 0)
limit = -1;
else if (e == 0)
limit = type;
else if (e <= 90)
limit = type + 1;
else if (e <= 180)
limit = type + 2;
else if (e <= 270)
limit = type + 3;
else
limit = type + 4;
double increment = angExtDeg;
if (increment > 360.0) {
increment = 360.0;
} else if (increment < -360.0) {
increment = -360.0;
}
increment /= limit;
this.increment = Math.toRadians(increment);
}
/**
* Construct a new iterator over an ellipse.
*
* @param e the ellipse
* @param xform the transform
*/
ArcIterator(Ellipse2D e, AffineTransform xform) {
this.xform = xform;
x = e.getX();
y = e.getY();
w = e.getWidth();
h = e.getHeight();
startAngRad = 0;
extentAngRad = -2 * Math.PI;
angExtDeg = -360;
type = CHORD;
limit = (w < 0 || h < 0) ? -1 : 5;
this.increment = Math.toRadians(angExtDeg / limit);
}
/**
* Return the winding rule.
*
* @return {@link PathIterator#WIND_NON_ZERO}
*/
public int getWindingRule() {
return WIND_NON_ZERO;
}
/**
* Test if the iteration is complete.
*
* @return true if more segments exist
*/
public boolean isDone() {
return current > limit;
}
/**
* Advance the iterator.
*/
public void next() {
current++;
}
/**
* Put the current segment into the array, and return the segment type.
*
* @param coords an array of 6 elements
* @return the segment type
* @throws NullPointerException if coords is null
* @throws ArrayIndexOutOfBoundsException if coords is too small
*/
public int currentSegment(float[] coords) {
if (current > limit) {
throw new NoSuchElementException("arc iterator out of bounds");
}
if (current == 0) {
coords[0] = (float) (Math.cos(startAngRad) * w + x) / 2;
coords[1] = (float) (Math.sin(startAngRad) * h + y) / 2;
if (xform != null) {
xform.transform(coords, 0, coords, 0, 1);
}
return SEG_MOVETO;
}
if (type != OPEN && current == limit) {
return SEG_CLOSE;
}
if (type == PIE && current == limit - 1) {
coords[0] = (float) (x + w / 2);
coords[1] = (float) (y + h / 2);
if (xform != null) {
xform.transform(coords, 0, coords, 0, 1);
}
return SEG_LINETO;
}
// XXX Fill coords with 2 control points and next quarter point
double angle = startAngRad;
angle += increment * (current - 1);
double relx = Math.cos(angle);
double rely = Math.sin(angle);
double z = btan(increment);
coords[0] = (float) (x + (relx - z * rely) * w);
coords[1] = (float) (y + (rely + z * relx) * h);
angle += increment;
relx = Math.cos(angle);
rely = Math.sin(angle);
coords[2] = (float) (x + (relx + z * rely) * w);
coords[3] = (float) (y + (rely - z * relx) * h);
coords[4] = (float) (x + relx * w);
coords[5] = (float) (y + rely * h);
if (xform != null) {
xform.transform(coords, 0, coords, 0, 3);
}
return SEG_CUBICTO;
}
/**
* Put the current segment into the array, and return the segment type.
*
* @param coords an array of 6 elements
* @return the segment type
* @throws NullPointerException if coords is null
* @throws ArrayIndexOutOfBoundsException if coords is too small
*/
public int currentSegment(double[] coords) {
if (current > limit)
throw new NoSuchElementException("arc iterator out of bounds");
if (current == 0) {
coords[0] = (Math.cos(startAngRad) * w + x) / 2;
coords[1] = (Math.sin(startAngRad) * h + y) / 2;
if (xform != null)
xform.transform(coords, 0, coords, 0, 1);
return SEG_MOVETO;
}
if (type != OPEN && current == limit)
return SEG_CLOSE;
if (type == PIE && current == limit - 1) {
coords[0] = (float) (x + w / 2);
coords[1] = (float) (y + h / 2);
if (xform != null)
xform.transform(coords, 0, coords, 0, 1);
return SEG_LINETO;
}
double angle = startAngRad;
angle += increment * (current - 1);
double relx = Math.cos(angle);
double rely = Math.sin(angle);
double z = btan(increment);
coords[0] = (x + (relx - z * rely) * w);
coords[1] = (y + (rely + z * relx) * h);
angle += increment;
relx = Math.cos(angle);
rely = Math.sin(angle);
coords[2] = (x + (relx + z * rely) * w);
coords[3] = (y + (rely - z * relx) * h);
coords[4] = (x + relx * w);
coords[5] = (y + rely * h);
if (xform != null) {
xform.transform(coords, 0, coords, 0, 3);
}
return SEG_CUBICTO;
}
private static double btan(double increment) {
increment /= 2.0;
double a = 1.0 - Math.cos(increment);
double b = Math.tan(increment);
double c = Math.sqrt(1.0 + b * b) - 1.0 + a;
return 4.0 / 3.0 * a * b / c;
}
} // class ArcIterator
/**
* This class implements an arc in double precision.
*
* @author Eric Blake <ebb9@email.byu.edu
* @since 1.2
*/
public static class Double extends Arc2D {
/** The x coordinate of the box bounding the ellipse of this arc. */
public double x;
/** The y coordinate of the box bounding the ellipse of this arc. */
public double y;
/** The width of the box bounding the ellipse of this arc. */
public double width;
/** The height of the box bounding the ellipse of this arc. */
public double height;
/** The start angle of this arc, in degrees. */
public double start;
/** The extent angle of this arc, in degrees. */
public double extent;
/**
* Create a new, open arc at (0,0) with 0 extent.
*/
public Double() {
super(OPEN);
}
/**
* Create a new arc of the given type at (0,0) with 0 extent.
*
* @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
* @throws IllegalArgumentException if type is invalid
*/
public Double(int type) {
super(type);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?