public class SplineInterpolator extends Interpolator
Basically, a cubic Bezier curve is created with start point (0,0) and endpoint (1,1). The other two control points (px1, py1) and (px2, py2) are given by the user, where px1, py1, px1, and px2 are all in the range [0,1]. A property of this specially constrained Bezier curve is that it is strictly monotonically increasing in both X and Y with t in range [0,1].
The interpolator works by giving it a value for X. It then finds what parameter t would generate this X value for the curve. Then this t parameter is applied to the curve to solve for Y. As X increases from 0 to 1, t also increases from 0 to 1, and correspondingly Y increases from 0 to 1. The X-to-Y mapping is not a function of path/curve length.
Modifier and Type | Field and Description |
---|---|
private boolean |
isCurveLinear
Do the input control points form a line with (0,0) and (1,1), i.e., x1 ==
y1 and x2 == y2 -- if so, then all x(t) == y(t) for the curve.
|
private static double |
SAMPLE_INCREMENT
Difference in t used to calculate each of the xSamples values -- power of
2 sample size should provide exact representation of this value and its
integer multiples (integer in range of [0..SAMPLE_SIZE].
|
private static int |
SAMPLE_SIZE
Power of 2 sample size for lookup table of x values.
|
private double |
x1
The coordinates of the 2 2D control points for a cubic Bezier curve, with
implicit start point (0,0) and end point (1,1) -- each individual
coordinate value must be in range [0,1].
|
private double |
x2
The coordinates of the 2 2D control points for a cubic Bezier curve, with
implicit start point (0,0) and end point (1,1) -- each individual
coordinate value must be in range [0,1].
|
private double[] |
xSamples
X values for the bezier curve, sampled at increments of 1/SAMPLE_SIZE --
this is used to find the good initial guess for parameter t, given an x.
|
private double |
y1
The coordinates of the 2 2D control points for a cubic Bezier curve, with
implicit start point (0,0) and end point (1,1) -- each individual
coordinate value must be in range [0,1].
|
private double |
y2
The coordinates of the 2 2D control points for a cubic Bezier curve, with
implicit start point (0,0) and end point (1,1) -- each individual
coordinate value must be in range [0,1].
|
Constructor and Description |
---|
SplineInterpolator(double px1,
double py1,
double px2,
double py2)
Creates a new instance with control points (0,0) (px1,py1) (px2,py2)
(1,1) -- px1, py1, px2, py2 all in range [0,1].
|
Modifier and Type | Method and Description |
---|---|
double |
curve(double x)
Returns the y-value of the cubic bezier curve that corresponds to the x
input.
|
boolean |
equals(java.lang.Object obj) |
private double |
eval(double t,
double p1,
double p2)
Use Bernstein basis to evaluate 1D cubic Bezier curve (quicker and more
numerically stable than power basis) -- 1D control coordinates are (0,
p1, p2, 1), where p1 and p2 are in range [0,1], and there is no ordering
constraint on p1 and p2, i.e., p1 <= p2 does not have to be true.
|
private double |
evalDerivative(double t,
double p1,
double p2)
Evaluates Bernstein basis derivative of 1D cubic Bezier curve, where 1D
control points are (0, p1, p2, 1), where p1 and p2 are in range [0,1],
and there is no ordering constraint on p1 and p2, i.e., p1 <= p2 does
not have to be true.
|
private double |
findTForX(double x)
Finds the parameter t that produces the given x-value for the curve --
uses Newton-Raphson to refine the value as opposed to subdividing until
we are within some tolerance.
|
private double |
getInitialGuessForT(double x)
Find an initial good guess for what parameter t might produce the x-value
on the Bezier curve -- uses linear interpolation on the x-value sample
array that was created on construction.
|
double |
getX1() |
double |
getX2() |
double |
getY1() |
double |
getY2() |
int |
hashCode() |
java.lang.String |
toString() |
interpolate, interpolate, interpolate, interpolate, interpolate, SPLINE, TANGENT, TANGENT
private final double x1
private final double y1
private final double x2
private final double y2
private final boolean isCurveLinear
private static final int SAMPLE_SIZE
private static final double SAMPLE_INCREMENT
private final double[] xSamples
public SplineInterpolator(double px1, double py1, double px2, double py2)
px1
- X coordinate of first control point, in range [0,1]py1
- Y coordinate of first control point, in range [0,1]px2
- X coordinate of second control point, in range [0,1]py2
- Y coordinate of second control point, in range [0,1]public double getX1()
public double getY1()
public double getX2()
public double getY2()
public int hashCode()
hashCode
in class java.lang.Object
public boolean equals(java.lang.Object obj)
equals
in class java.lang.Object
public double curve(double x)
curve
in class Interpolator
x
- is x-value of cubic bezier curve, in range [0,1]private double eval(double t, double p1, double p2)
t
- is the paramaterized value in range [0,1]p1
- is 1st control point coordinate in range [0,1]p2
- is 2nd control point coordinate in range [0,1]private double evalDerivative(double t, double p1, double p2)
t
- is the paramaterized value in range [0,1]p1
- is 1st control point coordinate in range [0,1]p2
- is 2nd control point coordinate in range [0,1]private double getInitialGuessForT(double x)
x
- is x-value of cubic bezier curve, in range [0,1]private double findTForX(double x)
x
- is x-value of cubic bezier curve, in range [0,1]public java.lang.String toString()
toString
in class java.lang.Object