

PREV CLASS NEXT CLASS  FRAMES NO FRAMES  
SUMMARY: NESTED  FIELD  CONSTR  METHOD  DETAIL: FIELD  CONSTR  METHOD 
java.lang.Object com.caffeineowl.graphics.bezier.BezierUtils
public class BezierUtils
Utility functions for processing Bézier curves.
Nested Class Summary  

static class 
BezierUtils.CubicArrayListConsumer
A CubicSegmentConsumer that stores the
received
cubic segments in an array list . 
(package private) static class 
BezierUtils.MidPointApproxSubdivCriterion
The adaptive halving criterion for approximating a cubic by the midpoint approximation quadratic. 
(package private) static class 
BezierUtils.MidPointApproxTransformer
A CubicSegmentConsumer that wraps around a
QuadSegmentConsumer and, upon receiving
a cubic segment,
applies the
mid point approximation and passed the resulted segment
into the wrapped consumer. 
static class 
BezierUtils.QuadArrayListConsumer
A QuadSegmentConsumer that stores the
received
quad segments in an array list . 
Field Summary  

static double 
minPrecision

Constructor Summary  

BezierUtils()

Method Summary  

static java.awt.geom.QuadCurve2D[] 
adaptiveDegreeReduction(java.awt.geom.CubicCurve2D cubic,
double precision)
The adaptive degree reduction algorithm, implemented to return the resulted "daisychain" of the approximating quadratic segments as an array. 
static void 
adaptiveDegreeReduction(java.awt.geom.CubicCurve2D cubic,
double precision,
QuadSegmentConsumer resultHere)
The adaptive degree reduction algorithm, implemented to return the resulted "daisychain" of the approximating quadratic segments as an array. 
static java.awt.geom.CubicCurve2D[] 
adaptiveHalving(java.awt.geom.CubicCurve2D curve,
CubicSubdivisionCriterion subdivCriterion)
Performs an adaptive halving of a cubic Bézier, base on a provided CubicSubdivisionCriterion (which tells when a cubic Bézier
is good enough not to need splitting in two anymore). 
static void 
adaptiveHalving(java.awt.geom.CubicCurve2D curve,
CubicSubdivisionCriterion subdivCriterion,
CubicSegmentConsumer segConsumer)
Method to perform an adaptive halving of a cubic Bézier, based on a CubicSubdivisionCriterion (which tells when a cubic
is good enough not to need splitting in two anymore). 
static java.awt.geom.QuadCurve2D[] 
adaptiveHalving(java.awt.geom.QuadCurve2D curve,
QuadSubdivisionCriterion subdivCriterion)
Performs an adaptive halving of a quadratic Bézier, base on a provided QuadSubdivisionCriterion (which tells when a quad Bézier
is good enough not to need splitting in two anymore). 
static void 
adaptiveHalving(java.awt.geom.QuadCurve2D curve,
QuadSubdivisionCriterion subdivCriterion,
QuadSegmentConsumer segConsumer)
Method to perform an adaptive halving of a quadratic Bézier, based on a QuadSubdivisionCriterion (which tells when a quad Bézier
is good enough not to need splitting in two anymore). 
static void 
adaptiveHalvingDegreeReduction(java.awt.geom.CubicCurve2D cubic,
double precision,
QuadSegmentConsumer resultHere)

static int 
computeInflexion(java.awt.geom.CubicCurve2D curve,
double[] params)
Computes the parameter values corresponding to the inflexion points of a cubic Bézier (if any) and returns them within a provided double[]
array. 
static boolean 
halfSplitCurve(java.awt.geom.CubicCurve2D cubic,
java.awt.geom.CubicCurve2D first,
java.awt.geom.CubicCurve2D second)
Subdivides a cubic Bézier at a value for the curve's parameter of 1/2 . 
static boolean 
halfSplitCurve(java.awt.geom.QuadCurve2D quad,
java.awt.geom.QuadCurve2D first,
java.awt.geom.QuadCurve2D second)
Subdivides a quadratic Bézier at a value for the curve's parameter of 1/2 . 
static void 
midPointAndTangentOnCurve(java.awt.geom.CubicCurve2D curve,
java.awt.geom.Point2D point,
java.awt.geom.Line2D tangent)

static void 
minPointAndTangentOnCurve(java.awt.geom.QuadCurve2D curve,
java.awt.geom.Point2D point,
java.awt.geom.Line2D tangent)

static void 
pointAndTangentOnCurve(double t,
java.awt.geom.CubicCurve2D curve,
java.awt.geom.Point2D point,
java.awt.geom.Line2D tangent)

static void 
pointAndTangentOnCurve(double t,
java.awt.geom.QuadCurve2D curve,
java.awt.geom.Point2D point,
java.awt.geom.Line2D tangent)

static java.awt.geom.Point2D 
pointOnCurve(double t,
java.awt.geom.CubicCurve2D curve,
java.awt.geom.Point2D resultHere)
Computes the location of the point on a cubic Bézier corresponding to a given value of the parameter t , and returns the position in
an output parameter (if provided). 
static java.awt.geom.Point2D 
pointOnCurve(double t,
java.awt.geom.QuadCurve2D curve,
java.awt.geom.Point2D resultHere)
Computes the location of the point on a quadratic Bézier corresponding to a given value of the parameter t , and returns the position in
an output parameter (if provided). 
static java.awt.geom.CubicCurve2D[] 
splitCurve(java.awt.geom.CubicCurve2D curve,
double[] params,
java.awt.geom.CubicCurve2D[] resultsHere)
Subdivides a cubic Bézier in more than one subdivision points. 
static boolean 
splitCurve(java.awt.geom.CubicCurve2D cubic,
double tSplit,
java.awt.geom.CubicCurve2D first,
java.awt.geom.CubicCurve2D second)
Subdivides a cubic Bézier at a given value for the curve's parameter. 
static java.awt.geom.QuadCurve2D[] 
splitCurve(java.awt.geom.QuadCurve2D curve,
double[] params,
java.awt.geom.QuadCurve2D[] resultsHere)
Subdivides a quadratic Bézier in more than one subdivision points. 
static boolean 
splitCurve(java.awt.geom.QuadCurve2D quad,
double tSplit,
java.awt.geom.QuadCurve2D first,
java.awt.geom.QuadCurve2D second)
Subdivides a quadratic Bézier at a given value for the curve's parameter. 
Methods inherited from class java.lang.Object 

clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait 
Field Detail 

public static final double minPrecision
Constructor Detail 

public BezierUtils()
Method Detail 

public static boolean halfSplitCurve(java.awt.geom.CubicCurve2D cubic, java.awt.geom.CubicCurve2D first, java.awt.geom.CubicCurve2D second)
1/2
. The method will return the resulted cubic segments
in the two output parameters (first
and second
).
It is safe for whichever of them to be the same as the provided cubic,
the computation will be correct, however the original cubic will be
overwritten. The method will not check if the both of the
result cubic segments point to the same instance:
in this case the last to be computed (the second
)
will overwrite the previous.
cubic
 the cubic Bézier to splitfirst
 the place where the first half cubic that results
upon subdivision is stored. If null
,
the method will interpret this as "don't care about first
segment" and will not compute it.second
 the place where the second half cubic that results
upon subdivision is stored. If null
,
the method will interpret this as "don't care about second
segment" and will not compute it.
true
if the computation was performed and finished
successfuly, false
otherwise (i.e a null
value
for the cubic
parameter).public static boolean halfSplitCurve(java.awt.geom.QuadCurve2D quad, java.awt.geom.QuadCurve2D first, java.awt.geom.QuadCurve2D second)
1/2
. The method will return the resulted quadratic Bézier segments
in the two output parameters (first
and second
).
It is safe for whichever of them to be the same as the provided quadratic,
the computation will be correct, however the original quadratic will be
overwritten. The method will not check if the both of the
result quadratic curves point to the same instance:
in this case the last to be computed (the second
)
will overwrite the previous.
quad
 the cubic Bézier to splitfirst
 the place where the first quadratic half that results
upon subdivision is stored. If null
,
the method will interpret this as "don't care about first
segment" and will not compute it.second
 the place where the second quadratic half that results
upon subdivision is stored. If null
,
the method will interpret this as "don't care about second
segment" and will not compute it.
true
if the computation was performed and finished
Successfully, false
otherwise (i.e a null
value
for the quad
parameter).public static boolean splitCurve(java.awt.geom.CubicCurve2D cubic, double tSplit, java.awt.geom.CubicCurve2D first, java.awt.geom.CubicCurve2D second)
first
and second
).
It is safe for whichever of them to be the same as the provided cubic,
the computation will be correct, however the original cubic will be
overwritten. The method will not check if the both of the
result cubic segments point to the same instance:
in this case the last to be computed (the second
)
will overwrite the previous.
cubic
 the cubic Bézier to splittSplit
 the value for parameter where the split should occur.
If out of the 0..1 range, the function does nothing
and returns false
.first
 the place where the first cubic segment that results
upon subdivision is stored. If null
,
the method will interpret this as "don't care about first
segment" and will not compute it.second
 the place where the second cubic segment that results
upon subdivision is stored. If null
,
the method will interpret this as "don't care about second
segment" and will not compute it.
true
if the computation was performed and finished
successfully, false
otherwise (i.e a null
value
for the cubic
parameter, or a value for the tSplit
out of the [0..1]
range).public static boolean splitCurve(java.awt.geom.QuadCurve2D quad, double tSplit, java.awt.geom.QuadCurve2D first, java.awt.geom.QuadCurve2D second)
first
and second
).
It is safe for whichever of them to be the same as the provided quadratic,
the computation will be correct, however the original quadratic will be
overwritten. The method will not check if the both of the
result quadratic curves point to the same instance:
in this case the last to be computed (the second
)
will overwrite the previous.
quad
 the cubic Bézier to splittSplit
 the value for parameter where the split should occur.
If out of the 0..1 range, the function does nothing
and returns false
.first
 the place where the first quadratic segment that results
upon subdivision is placed. If null
,
the method will interpret this as "don't care about first
segment" and will not compute it.second
 the place where the second quadratic segment that results
upon subdivision is placed. If null
,
the method will interpret this as "don't care about second
segment" and will not compute it.
true
if the computation was performed and finished
successfully, false
otherwise (i.e a null
value
for the quad
parameter, or a value for the tSplit
out of the [0..1]
range).public static java.awt.geom.CubicCurve2D[] splitCurve(java.awt.geom.CubicCurve2D curve, double[] params, java.awt.geom.CubicCurve2D[] resultsHere)
single
point split
method.
curve
 the curve to subdivideparams
 the array of curve parameters where to split the curve.
Of course, they need to be in the [0..1) range (1.0 excluded)  otherwise
unpredictable results might happen (in fact they are quite predictable, by I'm
too lazy to check the effect). The method does not check this. Uh, by the
way, the params are supposed to be sorted in ascending order: the method
calls java.utils.Arrays.sort(double[])
to make sure they are
(so, if they are not, be warned  the method will have a side effect
on the parameters).resultsHere
 array to store the
resultHere
has enough space to accommodate, then the
first params.length+1
are filled in and resultsHere
is returned. If the resultHere
is not large enough to
contain all the resulted points (or is null
),
the array is reallocated (old content is copied into the newly allocated
one), filled in and returned.public static java.awt.geom.QuadCurve2D[] splitCurve(java.awt.geom.QuadCurve2D curve, double[] params, java.awt.geom.QuadCurve2D[] resultsHere)
single
point split
method.
curve
 the curve to subdivideparams
 the array of curve parameters where to split the curve.
Of course, they need to be in the [0..1) range (1.0 excluded)  otherwise
unpredictable results might happen (in fact they are quite predictable, by I'm
too lazy to check the effect). The method does not check this. Uh, by the
way, the params are supposed to be sorted in ascending order: the method
calls java.utils.Arrays.sort(double[])
to make sure they are
(so, if they are not, be warned  the method will have a side effect
on the parameters).resultsHere
 array to store the
resultHere
has enough space to accommodate, then the
first params.length+1
are filled in and resultsHere
is returned. If the resultHere
is not large enough to
contain all the resulted points (or is null
),
the array is reallocated (old content is copied into the newly allocated
one), filled in and returned.public static java.awt.geom.Point2D pointOnCurve(double t, java.awt.geom.CubicCurve2D curve, java.awt.geom.Point2D resultHere)
t
, and returns the position in
an output parameter (if provided). If the provided output parameter is
null
, the method will allocate a Point2D
and return it. Otherwise, if successful, the method will return the
provided Point2D
instance to be used for storing the result.t
parameter to values between [0..1]
, using whichever value is
provided.
The method uses the parametrical expression of the cubic Bézier:
this is because it requires 20
additions/substractions
and 10
multiplications,
while the de Casteljau algorithm requires 24
additions
and 12
multiplications.
t
 value for the curve parameter for which to compute the
corresponding positioncurve
 the cubic curve. If null
, the method will
return null
.resultHere
 the output parameter where the position is to be stored.
If null
, the method will create a new Point2D
instance, use it for storing the requested value and return it.
t
, or null
if the provided
curve
is null
.public static java.awt.geom.Point2D pointOnCurve(double t, java.awt.geom.QuadCurve2D curve, java.awt.geom.Point2D resultHere)
t
, and returns the position in
an output parameter (if provided). If the provided output parameter is
null
, the method will allocate a Point2D
and return it. Otherwise, if successful, the method will return the
provided Point2D
instance to be used for storing the result.t
parameter to values between [0..1]
, using whichever value is
provided.
Uses the parametric expression of the quadratic Bézier:
this is because it requires 10
additions/substractions
and 6
multiplications,
while the de Casteljau algorithm requires 12
additions
and 6
multiplications.
t
 value for the curve parameter for which to compute the
corresponding position.curve
 the quadratic curve. If null
, the method will
return null
.resultHere
 the output parameter where the position is to be stored.
If null
, the method will create a new Point2D
instance, use it for storing the requested value and return it.
t
, or null
if the provided
curve
is null
.public static void pointAndTangentOnCurve(double t, java.awt.geom.CubicCurve2D curve, java.awt.geom.Point2D point, java.awt.geom.Line2D tangent)
public static void pointAndTangentOnCurve(double t, java.awt.geom.QuadCurve2D curve, java.awt.geom.Point2D point, java.awt.geom.Line2D tangent)
public static void midPointAndTangentOnCurve(java.awt.geom.CubicCurve2D curve, java.awt.geom.Point2D point, java.awt.geom.Line2D tangent)
public static void minPointAndTangentOnCurve(java.awt.geom.QuadCurve2D curve, java.awt.geom.Point2D point, java.awt.geom.Line2D tangent)
public static int computeInflexion(java.awt.geom.CubicCurve2D curve, double[] params)
double[]
array. To be on a safe side, the array have to be preallocated to a minimum
length of 2 (a cubic Bézier can have up to 2
inflexion points).(0, 1)
range (excluding the
range ends).2
inflexion points, they will be
placed into the results array in increasing order of their corresponding
curve's parameter values.
To obtain the (x, y)
location of the inflexion point(s),
use the pointOnCurve(double, CubicCurve2D, Point2D)
method.
See also: http://www.caffeineowl.com/graphics/2d/vectorial/cubicinflexion.html
curve
 the cubic Bézier for which the inflexion points are
to be computed for. If null
, the method will throw a
NullPointerException
.params
 the array where the values (in the (0, 1)
range)
for the curve parameter corresponding to the inflexion points are to be
returned. If null
, a NullPointerException
will be thrown if the curve has inflexion points. If the length of
the array is not enough to accommodate all the values (at most 2
),
an ArrayIndexOutOfBoundsException
is thrown.
public static void adaptiveHalving(java.awt.geom.CubicCurve2D curve, CubicSubdivisionCriterion subdivCriterion, CubicSegmentConsumer segConsumer)
CubicSubdivisionCriterion
(which tells when a cubic
is good enough not to need splitting in two anymore). The result
of the subdivision is guaranteed to make a "daisychain" from the
original curve (i.e. the end of the prev cubic segment will always
be the start of the new one). The results of the subdivision are fed
into a CubicSegmentConsumer
for custom further processing.
curve
 the curve to be splitsubdivCriterion
 the subdivision criterion telling when the curve
no longer needs splittingsegConsumer
 the consumer of cubic segments that will be "fed"
with the cubic segments resulting from subdivision (may just accumulate
them perform a processing on them  like transforming them into lie segments).public static void adaptiveHalving(java.awt.geom.QuadCurve2D curve, QuadSubdivisionCriterion subdivCriterion, QuadSegmentConsumer segConsumer)
QuadSubdivisionCriterion
(which tells when a quad Bézier
is good enough not to need splitting in two anymore). The result
of the subdivision is guaranteed to make a "daisychain" from the
original curve (i.e. the end of the prev cubic segment will always
be the start of the new one).The results of the subdivision are fed
into a CubicSegmentConsumer
for custom further processing.
curve
 the curve to be splitsubdivCriterion
 the subdivision criterion telling when the curve
no longer needs splittingsegConsumer
 the consumer of cubic segments that will be "fed"
with the cubic segments resulting from subdivision (may just accumulate
them perform a processing on them  like transforming them into lie segments).public static java.awt.geom.CubicCurve2D[] adaptiveHalving(java.awt.geom.CubicCurve2D curve, CubicSubdivisionCriterion subdivCriterion)
CubicSubdivisionCriterion
(which tells when a cubic Bézier
is good enough not to need splitting in two anymore). The result
of the subdivision is returned as an array of cubics, guaranteed to
make a "daisychain" from the original curve (i.e. the end of the
prev cubic segment will always be the start of the new one).
The method simply calls into
adaptiveHalving(CubicCurve2D, CubicSubdivisionCriterion, CubicSegmentConsumer)
using an BezierUtils.CubicArrayListConsumer
as an accumulator, returning
the accumulated values once the halving ends.
curve
 the curve to be subdividedsubdivCriterion
 the subdivision criterion
public static java.awt.geom.QuadCurve2D[] adaptiveHalving(java.awt.geom.QuadCurve2D curve, QuadSubdivisionCriterion subdivCriterion)
QuadSubdivisionCriterion
(which tells when a quad Bézier
is good enough not to need splitting in two anymore). The result
of the subdivision is returned as an array of cubics, guaranteed to
make a "daisychain" from the original curve (i.e. the end of the
prev cubic segment will always be the start of the new one).
The method simply calls into
adaptiveHalving(QuadCurve2D, QuadSubdivisionCriterion, QuadSegmentConsumer)
using an BezierUtils.QuadArrayListConsumer
as an accumulator, returning
the accumulated values once the halving finishes.
curve
 the curve to be subdividedsubdivCriterion
 the subdivision criterion
public static java.awt.geom.QuadCurve2D[] adaptiveDegreeReduction(java.awt.geom.CubicCurve2D cubic, double precision)
adaptiveDegreeReduction(CubicCurve2D, double, QuadSegmentConsumer)
with a
BezierUtils.QuadArrayListConsumer
accumulator, and returns the accumulated segments
once the algorithm ends.
cubic
 the cubic to be approximated by quad segmentsprecision
 the desired precision of approximation. If drawing the resulted
quad segments, it doesn't make any sense to use less than half of the
resolution of the device used to display it (e.g. if drawing on a screen,
and the x, y< coordinates are pixels, use 0.5 as a minimum
for the precision, even if for most of the cases a value of 0.75 or even 1.0 will
be sufficient).
public static void adaptiveHalvingDegreeReduction(java.awt.geom.CubicCurve2D cubic, double precision, QuadSegmentConsumer resultHere)
public static void adaptiveDegreeReduction(java.awt.geom.CubicCurve2D cubic, double precision, QuadSegmentConsumer resultHere)
QuadSegmentConsumer
for further processing (or just storing).
cubic
 the cubic to be approximated by quad segmentsprecision
 the desired precision of approximation. If drawing the resulted
quad segments, it doesn't make any sense to use less than half of the
resolution of the device used to display it (e.g. if drawing on a screen,
and the x, y< coordinates are pixels, use 0.5 as a minimum
for the precision, even if for most of the cases a value of 0.75 or even 1.0 will
be sufficient).


PREV CLASS NEXT CLASS  FRAMES NO FRAMES  
SUMMARY: NESTED  FIELD  CONSTR  METHOD  DETAIL: FIELD  CONSTR  METHOD 