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 + -
显示快捷键?