/*******************************************************************************
* Copyright (c) 2011, 2016 itemis AG and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Alexander Nyßen (itemis AG) - initial API and implementation
* Matthias Wienand (itemis AG) - contribution for Bugzilla #355997
*
*******************************************************************************/
package org.eclipse.gef.geometry.planar;
/**
* An instance of the {@link CubicCurve} class represents a {@link BezierCurve}
* of degree 3, having a start and an end {@link Point} and two handle
* {@link Point}s.
*
* @author anyssen
* @author mwienand
*
*/
public class CubicCurve extends BezierCurve {
private static final long serialVersionUID = 1L;
/**
* Constructs a new {@link CubicCurve} object with the given sequence of x
* and y coordinates of the start {@link Point}, the two handle
* {@link Point}s, and the end {@link Point}.
*
* @param coordinates
* the sequence of x and y coordinates specifying this
* {@link CubicCurve}'s control {@link Point}s
* @see CubicCurve#CubicCurve(double, double, double, double, double,
* double, double, double)
*/
public CubicCurve(double... coordinates) {
this(coordinates[0], coordinates[1], coordinates[2], coordinates[3],
coordinates[4], coordinates[5], coordinates[6], coordinates[7]);
if (coordinates.length != 8) {
throw new IllegalArgumentException(
"A CubicCurve may only be defined by 8 coordinates (4 points), while "
+ coordinates.length + " were passed in.");
}
}
/**
* Constructs a new {@link CubicCurve} object from the given control
* {@link Point} coordinates.
*
* @param x1
* the x coordinate of the start {@link Point}
* @param y1
* the y coordinate of the start {@link Point}
* @param ctrl1X
* the x coordinate of the first handle {@link Point}
* @param ctrl1Y
* the y coordinate of the first handle {@link Point}
* @param ctrl2X
* the x coordinate of the second handle {@link Point}
* @param ctrl2Y
* the y coordinate of the second handle {@link Point}
* @param x2
* the x coordinate of the end {@link Point}
* @param y2
* the y coordinate of the end {@link Point}
*/
public CubicCurve(double x1, double y1, double ctrl1X, double ctrl1Y,
double ctrl2X, double ctrl2Y, double x2, double y2) {
super(x1, y1, ctrl1X, ctrl1Y, ctrl2X, ctrl2Y, x2, y2);
}
/**
* Constructs a new {@link CubicCurve} from the given sequence of
* {@link Point}s, which is expected to be in the order: start {@link Point}
* , first and second handle {@link Point}s, and end {@link Point}.
*
* @param points
* the sequence of {@link Point}s from which this
* {@link CubicCurve} is constructed
* @see CubicCurve#CubicCurve(Point, Point, Point, Point)
* @see CubicCurve#CubicCurve(double, double, double, double, double,
* double, double, double)
*/
public CubicCurve(Point... points) {
this(points[0].x, points[0].y, points[1].x, points[1].y, points[2].x,
points[2].y, points[3].x, points[3].y);
if (points.length != 4) {
throw new IllegalArgumentException(
"A CubicCurve may only be defined by 4 points, while "
+ points.length + " were passed in.");
}
}
/**
* Constructs a new {@link CubicCurve} object from the given control
* {@link Point}s.
*
* @param start
* the start {@link Point}
* @param ctrl1
* the first handle {@link Point}
* @param ctrl2
* the second handle {@link Point}
* @param end
* the end {@link Point}
* @see CubicCurve#CubicCurve(double, double, double, double, double,
* double, double, double)
*/
public CubicCurve(Point start, Point ctrl1, Point ctrl2, Point end) {
this(start.x, start.y, ctrl1.x, ctrl1.y, ctrl2.x, ctrl2.y, end.x,
end.y);
}
/**
* Returns a new {@link CubicCurve}, which has the same control
* {@link Point}s as this one.
*
* @return a new {@link CubicCurve} with the same control {@link Point}s as
* this one
*/
@Override
public CubicCurve getCopy() {
return new CubicCurve(getP1(), getCtrl1(), getCtrl2(), getP2());
}
/**
* Returns the first handle {@link Point}.
*
* @return the first handle {@link Point}
*/
public Point getCtrl1() {
return new Point(getCtrlX1(), getCtrlY1());
}
/**
* Returns the second handle {@link Point}.
*
* @return the second handle {@link Point}
*/
public Point getCtrl2() {
return new Point(getCtrlX2(), getCtrlY2());
}
/**
* Returns the first handle {@link Point}'s x coordinate.
*
* @return the first handle {@link Point}'s x coordinate
*/
public double getCtrlX1() {
return getPoint(1).x;
}
/**
* Returns the second handle {@link Point}'s x coordinate.
*
* @return the second handle {@link Point}'s x coordinate
*/
public double getCtrlX2() {
return getPoint(2).x;
}
/**
* Returns the first handle {@link Point}'s y coordinate.
*
* @return the first handle {@link Point}'s y coordinate
*/
public double getCtrlY1() {
return getPoint(1).y;
}
/**
* Returns the second handle {@link Point}'s y coordinate.
*
* @return the second handle {@link Point}'s y coordinate
*/
public double getCtrlY2() {
return getPoint(2).y;
}
@Override
public CubicCurve getTransformed(AffineTransform t) {
return new CubicCurve(t.getTransformed(getPoints()));
}
/**
* Sets the first handle {@link Point} of this {@link CubicCurve} to the
* given {@link Point}.
*
* @param ctrl1
* the new first handle {@link Point}
* @return <code>this</code> for convenience
*/
public CubicCurve setCtrl1(Point ctrl1) {
setCtrl1X(ctrl1.x);
setCtrl1Y(ctrl1.y);
return this;
}
/**
* Sets the x coordinate of the first handle {@link Point} of this
* {@link CubicCurve} to the given value.
*
* @param ctrl1x
* the new x coordinate of the first handle {@link Point} of this
* {@link CubicCurve}
* @return <code>this</code> for convenience
*/
public CubicCurve setCtrl1X(double ctrl1x) {
setPoint(1, new Point(ctrl1x, getCtrlY1()));
return this;
}
/**
* Sets the y coordinate of the first handle {@link Point} of this
* {@link CubicCurve} to the given value.
*
* @param ctrl1y
* the new y coordinate of the first handle {@link Point} of this
* {@link CubicCurve}
* @return <code>this</code> for convenience
*/
public CubicCurve setCtrl1Y(double ctrl1y) {
setPoint(1, new Point(getCtrlX1(), ctrl1y));
return this;
}
/**
* Sets the second handle {@link Point} of this {@link CubicCurve} to the
* given {@link Point}.
*
* @param ctrl2
* the new second handle {@link Point} of this {@link CubicCurve}
* @return <code>this</code> for convenience
*/
public CubicCurve setCtrl2(Point ctrl2) {
setCtrl2X(ctrl2.x);
setCtrl2Y(ctrl2.y);
return this;
}
/**
* Sets the x coordinate of the second handle {@link Point} of this
* {@link CubicCurve} to the given value.
*
* @param ctrl2x
* the new x coordinate of the second handle {@link Point} of
* this {@link CubicCurve}
* @return <code>this</code> for convenience
*/
public CubicCurve setCtrl2X(double ctrl2x) {
setPoint(2, new Point(ctrl2x, getCtrlY2()));
return this;
}
/**
* Sets the y coordinate of the second handle {@link Point} of this
* {@link CubicCurve} to the given value.
*
* @param ctrl2y
* the new y coordinate of the second handle {@link Point} of
* this {@link CubicCurve}
* @return <code>this</code> for convenience
*/
public CubicCurve setCtrl2Y(double ctrl2y) {
setPoint(2, new Point(getCtrlX2(), ctrl2y));
return this;
}
/**
* Sets all control {@link Point}s of this {@link CubicCurve} to the given
* {@link Point}s.
*
* @param p1
* the new start {@link Point}
* @param ctrl1
* the new first control {@link Point}
* @param ctrl2
* the new second control {@link Point}
* @param p2
* the new end {@link Point}
* @return <code>this</code> for convenience
*/
public CubicCurve setCurve(Point p1, Point ctrl1, Point ctrl2, Point p2) {
setP1(p1);
setCtrl1(ctrl1);
setCtrl2(ctrl2);
setP2(p2);
return this;
}
@Override
public CubicCurve[] split(double t) {
BezierCurve[] split = super.split(t);
return new CubicCurve[] { split[0].toCubic(), split[1].toCubic() };
}
@Override
public Path toPath() {
Path p = new Path();
p.moveTo(getX1(), getY1());
p.cubicTo(getCtrlX1(), getCtrlY1(), getCtrlX2(), getCtrlY2(), getX2(),
getY2());
return p;
}
@Override
public String toString() {
return "CubicCurve(x1 = " + getX1() + ", y1 = " + getY1()
+ ", ctrl1X = " + getCtrlX1() + ", ctrl1Y = " + getCtrlY1()
+ ", ctrl2X = " + getCtrlX2() + ", ctrl2Y = " + getCtrlY2()
+ ", x2 = " + getX2() + ", y2 = " + getY2() + ")";
}
}