org.piccolo2d.nodes.PPath Maven / Gradle / Ivy
/*
* Copyright (c) 2008-2012, Piccolo2D project, http://piccolo2d.org
* Copyright (c) 1998-2008, University of Maryland
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided
* that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions
* and the following disclaimer in the documentation and/or other materials provided with the
* distribution.
*
* None of the name of the University of Maryland, the name of the Piccolo2D project, or the names of its
* contributors may be used to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.piccolo2d.nodes;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.geom.AffineTransform;
import java.awt.geom.Arc2D;
import java.awt.geom.CubicCurve2D;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Path2D;
import java.awt.geom.QuadCurve2D;
import java.awt.geom.Rectangle2D;
import java.awt.geom.RoundRectangle2D;
import java.awt.geom.PathIterator;
/**
* Abstract path node.
*/
public abstract class PPath extends PShape {
/** Path for this path node. */
private final Path2D path;
/**
* Create a new path node with the specified path.
*
* @param path path
*/
private PPath(final Path2D path) {
this.path = (Path2D) path.clone();
updateBoundsFromShape();
}
/**
* Create a new path node with the specified path and stroke.
*
* @param path path
* @param stroke stroke
*/
private PPath(final Path2D path, final Stroke stroke) {
this.path = (Path2D) path.clone();
setStroke(stroke);
}
/**
* Path node with coordinates stored in single precision floating point.
*/
public static class Float extends PPath {
/**
* Create a new empty path node.
*/
public Float() {
super(new Path2D.Float());
}
/**
* Create a new empty path node with the specified stroke.
*
* @param stroke stroke
*/
public Float(final Stroke stroke) {
super(new Path2D.Float(), stroke);
}
/**
* Create a new path node with the specified shape.
*
* @param shape shape, must not be null
* @throws NullPointerException if shape is null
*/
public Float(final Shape shape) {
super(new Path2D.Float(shape));
}
/**
* Create a new path node with the specified shape and stroke.
*
* @param shape shape, must not be null
* @param stroke stroke
* @throws NullPointerException if shape is null
*/
public Float(final Shape shape, final Stroke stroke) {
super(new Path2D.Float(shape), stroke);
}
/**
* Create a new path node with the specified path.
*
* @param path path, must not be null
* @throws NullPointerException if path is null
*/
public Float(final Path2D.Float path) {
super(path);
}
/**
* Create a new path node with the specified path and stroke.
*
* @param path path, must not be null
* @param stroke stroke, must not be null
* @throws NullPointerException if path is null
*/
public Float(final Path2D.Float path, final Stroke stroke) {
super(path, stroke);
}
}
/**
* Path node with coordinates stored in double precision floating point.
*/
public static class Double extends PPath {
/**
* Create a new empty path node.
*/
public Double() {
super(new Path2D.Double());
}
/**
* Create a new empty path node with the specified stroke.
*
* @param stroke stroke
*/
public Double(final Stroke stroke) {
super(new Path2D.Double(), stroke);
}
/**
* Create a new path node with the specified shape.
*
* @param shape shape, must not be null
* @throws NullPointerException if shape is null
*/
public Double(final Shape shape) {
super(new Path2D.Double(shape));
}
/**
* Create a new path node with the specified shape and stroke.
*
* @param shape shape, must not be null
* @param stroke stroke
* @throws NullPointerException if shape is null
*/
public Double(final Shape shape, final Stroke stroke) {
super(new Path2D.Double(shape), stroke);
}
/**
* Create a new path node with the specified path.
*
* @param path path, must not be null
* @throws NullPointerException if path is null
*/
public Double(final Path2D.Double path) {
super(path);
}
/**
* Create a new path node with the specified path and stroke.
*
* @param path path, must not be null
* @param stroke stroke
* @throws NullPointerException if path is null
*/
public Double(final Path2D.Double path, final Stroke stroke) {
super(path, stroke);
}
}
/**
* Create and return a new path node with the specified arc in single
* precision floating point coordinates.
*
* @param x x coordinate of the upper-left corner of the arc's framing rectangle
* @param y y coordinate of the upper-left corner of the arc's framing rectangle
* @param width width of the full ellipse of which this arc is a partial section
* @param height height of the full ellipse of which this arc is a partial section
* @param start starting angle of the arc in degrees
* @param extent angular extent of the arc in degrees
* @param type closure type for the arc, one of {@link Arc2D#OPEN}, {@link Arc2D#CHORD},
* or {@link Arc2D#PIE}
* @return a new path node with the specified arc in single
* precision floating point coordinates
*/
public static final PPath createArc(final float x,
final float y,
final float width,
final float height,
final float start,
final float extent,
final int type) {
return new PPath.Float(new Arc2D.Float(x, y, width, height, start, extent, type));
}
/**
* Create and return a new path node with the specified cubic curve in single
* precision floating point coordinates.
*
* @param x1 x coordinate of the start point
* @param y1 y coordinate of the start point
* @param ctrlx1 x coordinate of the first control point
* @param ctrly1 y coordinate of the first control point
* @param ctrlx2 x coordinate of the second control point
* @param ctrly2 y coordinate of the second control point
* @param x2 x coordinate of the end point
* @param y2 y coordinate of the end point
* @return a new path node with the specified cubic curve in single
* precision floating point coordinates
*/
public static final PPath createCubicCurve(final float x1,
final float y1,
final float ctrlx1,
final float ctrly1,
final float ctrlx2,
final float ctrly2,
final float x2,
final float y2) {
return new PPath.Float(new CubicCurve2D.Float(x1, y1, ctrlx1, ctrly1, ctrlx2, ctrly2, x2, y2));
}
/**
* Create and return a new path node with the specified ellipse in single
* precision floating point coordinates.
*
* @param x x coordinate
* @param y y coordinate
* @param width width
* @param height height
* @return a new path node with the specified ellipse in single
* precision floating point coordinates
*/
public static final PPath createEllipse(final float x, final float y, final float width, final float height) {
return new PPath.Float(new Ellipse2D.Float(x, y, width, height));
}
/**
* Create and return a new path node with the specified line in single
* precision floating point coordinates.
*
* @param x1 x coordinate of the start point
* @param y1 y coordinate of the start point
* @param x2 x coordinate of the end point
* @param y2 y coordinate of the end point
* @return a new path node with the specified line in single
* precision floating point coordinates
*/
public static final PPath createLine(final float x1, final float y1, final float x2, final float y2) {
return new PPath.Float(new Line2D.Float(x1, y1, x2, y2));
}
/*
need setPathToPolyline
public static final PPath createPolyline(final float[] xp, final float[] yp) {
}
public static final PPath createPolyline(final Point2D.Float[] points) {
}
*/
/**
* Create and return a new path node with the specified quadratic curve in single
* precision floating point coordinates.
*
* @param x1 x coordinate of the start point
* @param y1 y coordinate of the start point
* @param ctrlx x coordinate of the control point
* @param ctrly y coordinate of the control point
* @param x2 x coordinate of the end point
* @param y2 y coordinate of the end point
* @return a new path node with the specified quadratic curve in single
* precision floating point coordinates
*/
public static final PPath createQuadCurve(final float x1,
final float y1,
final float ctrlx,
final float ctrly,
final float x2,
final float y2) {
return new PPath.Float(new QuadCurve2D.Float(x1, y1, ctrlx, ctrly, x2, y2));
}
/**
* Create and return a new path node with the specified rectangle in single
* precision floating point coordinates.
*
* @param x x coordinate
* @param y y coordinate
* @param width width
* @param height height
* @return a new path node with the specified rectangle in single
* precision floating point coordinates
*/
public static final PPath createRectangle(final float x, final float y, final float width, final float height) {
return new PPath.Float(new Rectangle2D.Float(x, y, width, height));
}
/**
* Create and return a new path node with the specified round rectangle in single
* precision floating point coordinates.
*
* @param x x coordinate
* @param y y coordinate
* @param width width
* @param height height
* @param arcWidth width of the arc that rounds off the corners
* @param arcHeight height of the arc that rounds off the corners
* @return a new path node with the specified round rectangle in single
* precision floating point coordinates
*/
public static final PPath createRoundRectangle(final float x,
final float y,
final float width,
final float height,
final float arcWidth,
final float arcHeight) {
return new PPath.Float(new RoundRectangle2D.Float(x, y, width, height, arcWidth, arcHeight));
}
/**
* Create and return a new path node with the specified arc in double
* precision floating point coordinates.
*
* @param x x coordinate of the upper-left corner of the arc's framing rectangle
* @param y y coordinate of the upper-left corner of the arc's framing rectangle
* @param width width of the full ellipse of which this arc is a partial section
* @param height height of the full ellipse of which this arc is a partial section
* @param start starting angle of the arc in degrees
* @param extent angular extent of the arc in degrees
* @param type closure type for the arc, one of {@link Arc2D#OPEN}, {@link Arc2D#CHORD},
* or {@link Arc2D#PIE}
* @return a new path node with the specified arc in double
* precision floating point coordinates
*/
public static final PPath createArc(final double x,
final double y,
final double width,
final double height,
final double start,
final double extent,
final int type) {
return new PPath.Double(new Arc2D.Double(x, y, width, height, start, extent, type));
}
/**
* Create and return a new path node with the specified cubic curve in double
* precision floating point coordinates.
*
* @param x1 x coordinate of the start point
* @param y1 y coordinate of the start point
* @param ctrlx1 x coordinate of the first control point
* @param ctrly1 y coordinate of the first control point
* @param ctrlx2 x coordinate of the second control point
* @param ctrly2 y coordinate of the second control point
* @param x2 x coordinate of the end point
* @param y2 y coordinate of the end point
* @return a new path node with the specified cubic curve in double
* precision floating point coordinates
*/
public static final PPath createCubicCurve(final double x1,
final double y1,
final double ctrlx1,
final double ctrly1,
final double ctrlx2,
final double ctrly2,
final double x2,
final double y2) {
return new PPath.Double(new CubicCurve2D.Double(x1, y1, ctrlx1, ctrly1, ctrlx2, ctrly2, x2, y2));
}
/**
* Create and return a new path node with the specified ellipse in double
* precision floating point coordinates.
*
* @param x x coordinate
* @param y y coordinate
* @param width width
* @param height height
* @return a new path node with the specified ellipse in double
* precision floating point coordinates
*/
public static final PPath createEllipse(final double x, final double y, final double width, final double height) {
return new PPath.Double(new Ellipse2D.Double(x, y, width, height));
}
/**
* Create and return a new path node with the specified line in double
* precision floating point coordinates.
*
* @param x1 x coordinate of the start point
* @param y1 y coordinate of the start point
* @param x2 x coordinate of the end point
* @param y2 y coordinate of the end point
* @return a new path node with the specified line in double
* precision floating point coordinates
*/
public static final PPath createLine(final double x1, final double y1, final double x2, final double y2) {
return new PPath.Double(new Line2D.Double(x1, y1, x2, y2));
}
/*
public static final PPath createPolyline(final double[] xp, final double[] yp) {
}
public static final PPath createPolyline(final Point2D.Double[] points) {
}
*/
/**
* Create and return a new path node with the specified quadratic curve in double
* precision floating point coordinates.
*
* @param x1 x coordinate of the start point
* @param y1 y coordinate of the start point
* @param ctrlx x coordinate of the control point
* @param ctrly y coordinate of the control point
* @param x2 x coordinate of the end point
* @param y2 y coordinate of the end point
* @return a new path node with the specified quadratic curve in double
* precision floating point coordinates
*/
public static final PPath createQuadCurve(final double x1,
final double y1,
final double ctrlx,
final double ctrly,
final double x2,
final double y2) {
return new PPath.Double(new QuadCurve2D.Double(x1, y1, ctrlx, ctrly, x2, y2));
}
/**
* Create and return a new path node with the specified rectangle in double
* precision floating point coordinates.
*
* @param x x coordinate
* @param y y coordinate
* @param width width
* @param height height
* @return a new path node with the specified rectangle in double
* precision floating point coordinates
*/
public static final PPath createRectangle(final double x, final double y, final double width, final double height) {
return new PPath.Double(new Rectangle2D.Double(x, y, width, height));
}
/**
* Create and return a new path node with the specified round rectangle in double
* precision floating point coordinates.
*
* @param x x coordinate
* @param y y coordinate
* @param width width
* @param height height
* @param arcWidth width of the arc that rounds off the corners
* @param arcHeight height of the arc that rounds off the corners
* @return a new path node with the specified round rectangle in double
* precision floating point coordinates
*/
public static final PPath createRoundRectangle(final double x,
final double y,
final double width,
final double height,
final double arcWidth,
final double arcHeight) {
return new PPath.Double(new RoundRectangle2D.Double(x, y, width, height, arcWidth, arcHeight));
}
/**
* Return a copy of the path backing this path node.
*
* @return a copy of the path backing this path node
*/
public final Path2D getPath() {
return (Path2D) path.clone();
}
/**
* Return the path backing this node. The returned path must not be
* modified or the bounds of this node may no longer be valid and any
* path
property change listeners will not be notified.
*
* @return the path backing this path node
*/
public final Path2D getPathReference() {
return path;
}
/**
* Append the geometry of the specified shape to this path node, possibly
* connecting the new geometry to the existing path segments with a line
* segment. If the connect parameter is true and the path is not empty then
* any initial moveTo
in the geometry of the appended shape is turned into
* a lineTo
segment. If the destination coordinates of such a connecting
* lineTo
segment match the ending coordinates of a currently open subpath
* then the segment is omitted as superfluous. The winding rule of the specified
* shape is ignored and the appended geometry is governed by the winding
* rule specified for this path node.
*
* @param shape shape to append to this path node
* @param connect true to turn an initial moveTo
segment into a
* lineTo
segment to connect the new geometry to the existing path
*/
public final void append(final Shape shape, final boolean connect) {
Path2D oldPath = (Path2D) path.clone();
path.append(shape, connect);
updateBoundsFromShape();
firePropertyChange(-1, "path", oldPath, getPath());
}
/**
* Append the geometry of the specified path iterator to this path node, possibly
* connecting the new geometry to the existing path segments with a line segment.
* If the connect parameter is true and the path is not empty then any initial moveTo
* in the geometry of the appended path iterator is turned into a lineTo
segment.
* If the destination coordinates of such a connecting lineTo
segment match
* the ending coordinates of a currently open subpath then the segment is omitted
* as superfluous.
*
* @param pathIterator path iterator to append to this path node
* @param connect true to turn an initial moveTo
segment into a
* lineTo
segment to connect the new geometry to the existing path
*/
public final void append(final PathIterator pathIterator, final boolean connect) {
Path2D oldPath = (Path2D) path.clone();
path.append(pathIterator, connect);
updateBoundsFromShape();
firePropertyChange(-1, "path", oldPath, getPath());
}
/**
* Add a curved segment, defined by three new points, to this path node by drawing
* a Bézier curve that intersects both the current coordinates and the specified
* coordinates (x3,y3)
, using the specified points (x1,y1)
* and (x2,y2)
as Bézier control points. All coordinates are specified in
* double precision.
*
* @param x1 x coordinate of the first Bézier control point
* @param y1 y coordinate of the first Bézier control point
* @param x2 x coordinate of the second Bézier control point
* @param y2 y coordinate of the second Bézier control point
* @param x3 x coordinate of the final end point
* @param y3 y coordinate of the final end point
*/
public final void curveTo(final double x1,
final double y1,
final double x2,
final double y2,
final double x3,
final double y3) {
Path2D oldPath = (Path2D) path.clone();
path.curveTo(x1, y1, x2, y2, x3, y3);
updateBoundsFromShape();
firePropertyChange(-1, "path", oldPath, getPath());
}
/**
* Add a point to this path node by drawing a straight line from the
* current coordinates to the new specified coordinates specified in double precision.
*
* @param x x coordinate
* @param y y coordinate
*/
public final void lineTo(final double x, final double y) {
Path2D oldPath = (Path2D) path.clone();
path.lineTo(x, y);
updateBoundsFromShape();
firePropertyChange(-1, "path", oldPath, getPath());
}
/**
* Add a point to this path node by moving to the specified coordinates
* specified in double precision.
*
* @param x x coordinate
* @param y y coordinate
*/
public final void moveTo(final double x, final double y) {
Path2D oldPath = (Path2D) path.clone();
path.moveTo(x, y);
updateBoundsFromShape();
firePropertyChange(-1, "path", oldPath, getPath());
}
/**
* Add a curved segment, defined by two new points, to this path node by
* drawing a Quadratic curve that intersects both the current coordinates and
* the specified coordinates (x2,y2)
, using the specified point
* (x1,y1)
as a quadratic parametric control point. All coordinates
* are specified in double precision.
*
* @param x1 x coordinate of the quadratic control point
* @param y1 y coordinate of the quadratic control point
* @param x2 x coordinate of the final end point
* @param y2 y coordinate of the final end point
*/
public final void quadTo(final double x1, final double y1, final double x2, final double y2) {
Path2D oldPath = (Path2D) path.clone();
path.quadTo(x1, y1, x2, y2);
updateBoundsFromShape();
firePropertyChange(-1, "path", oldPath, getPath());
}
/**
* Reset the geometry for this path node to empty.
*/
public final void reset() {
Path2D oldPath = (Path2D) path.clone();
path.reset();
updateBoundsFromShape();
firePropertyChange(-1, "path", oldPath, getPath());
}
/**
* Close the current subpath by drawing a straight line back to the coordinates
* of the last moveTo
. If the path is already closed then this method
* has no effect.
*/
public final void closePath() {
Path2D oldPath = (Path2D) path.clone();
path.closePath();
updateBoundsFromShape();
firePropertyChange(-1, "path", oldPath, getPath());
}
// todo: setPathTo...
/** {@inheritDoc} */
protected final Shape getShape() {
return path;
}
/** {@inheritDoc} */
protected final void transform(final AffineTransform transform) {
path.transform(transform);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy