public class BezierUtils extends Object
| Modifier and Type | Class and Description |
|---|---|
static class |
BezierUtils.CubicArrayListConsumer
|
static class |
BezierUtils.QuadArrayListConsumer
|
| Modifier and Type | Field and Description |
|---|---|
static double |
minPrecision |
| Constructor and Description |
|---|
BezierUtils() |
| Modifier and Type | Method and Description |
|---|---|
static QuadCurve2D[] |
adaptiveDegreeReduction(CubicCurve2D cubic,
double precision)
The adaptive
degree reduction algorithm, implemented to return the resulted "daisy-chain" of the approximating
quadratic segments as an array.
|
static void |
adaptiveDegreeReduction(CubicCurve2D cubic,
double precision,
QuadSegmentConsumer resultHere)
The adaptive
degree reduction algorithm, implemented to return the resulted "daisy-chain" of the approximating
quadratic segments as an array.
|
static CubicCurve2D[] |
adaptiveHalving(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(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 QuadCurve2D[] |
adaptiveHalving(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(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(CubicCurve2D cubic,
double precision,
QuadSegmentConsumer resultHere) |
static int |
computeInflexion(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(CubicCurve2D cubic,
CubicCurve2D first,
CubicCurve2D second)
Subdivides a cubic Bézier at a value for the curve's parameter
of
1/2. |
static boolean |
halfSplitCurve(QuadCurve2D quad,
QuadCurve2D first,
QuadCurve2D second)
Subdivides a quadratic Bézier at a value for the curve's parameter
of
1/2. |
static void |
midPointAndTangentOnCurve(CubicCurve2D curve,
Point2D point,
Line2D tangent) |
static void |
minPointAndTangentOnCurve(QuadCurve2D curve,
Point2D point,
Line2D tangent) |
static void |
pointAndTangentOnCurve(double t,
CubicCurve2D curve,
Point2D point,
Line2D tangent) |
static void |
pointAndTangentOnCurve(double t,
QuadCurve2D curve,
Point2D point,
Line2D tangent) |
static Point2D |
pointOnCurve(double t,
CubicCurve2D curve,
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 Point2D |
pointOnCurve(double t,
QuadCurve2D curve,
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 CubicCurve2D[] |
splitCurve(CubicCurve2D curve,
double[] params,
CubicCurve2D[] resultsHere)
Subdivides a cubic Bézier in more than one subdivision points.
|
static boolean |
splitCurve(CubicCurve2D cubic,
double tSplit,
CubicCurve2D first,
CubicCurve2D second)
Subdivides a cubic Bézier at a given value for the curve's parameter.
|
static QuadCurve2D[] |
splitCurve(QuadCurve2D curve,
double[] params,
QuadCurve2D[] resultsHere)
Subdivides a quadratic Bézier in more than one subdivision points.
|
static boolean |
splitCurve(QuadCurve2D quad,
double tSplit,
QuadCurve2D first,
QuadCurve2D second)
Subdivides a quadratic Bézier at a given value for the curve's parameter.
|
public static boolean halfSplitCurve(CubicCurve2D cubic, CubicCurve2D first, 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(QuadCurve2D quad, QuadCurve2D first, 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(CubicCurve2D cubic, double tSplit, CubicCurve2D first, 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(QuadCurve2D quad, double tSplit, QuadCurve2D first, 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 CubicCurve2D[] splitCurve(CubicCurve2D curve, double[] params, 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 theresultHere 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 re-allocated (old content is copied into the newly allocated
one), filled in and returned.public static QuadCurve2D[] splitCurve(QuadCurve2D curve, double[] params, 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 theresultHere 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 re-allocated (old content is copied into the newly allocated
one), filled in and returned.public static Point2D pointOnCurve(double t, CubicCurve2D curve, 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 Point2D pointOnCurve(double t, QuadCurve2D curve, 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,
CubicCurve2D curve,
Point2D point,
Line2D tangent)
public static void pointAndTangentOnCurve(double t,
QuadCurve2D curve,
Point2D point,
Line2D tangent)
public static void midPointAndTangentOnCurve(CubicCurve2D curve, Point2D point, Line2D tangent)
public static void minPointAndTangentOnCurve(QuadCurve2D curve, Point2D point, Line2D tangent)
public static int computeInflexion(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/cubic-inflexion.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(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 "daisy-chain" 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 sub-division (may just accumulate
them perform a processing on them - like transforming them into lie segments).public static void adaptiveHalving(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 "daisy-chain" 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 sub-division (may just accumulate
them perform a processing on them - like transforming them into lie segments).public static CubicCurve2D[] adaptiveHalving(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 "daisy-chain" 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 criterionpublic static QuadCurve2D[] adaptiveHalving(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 "daisy-chain" 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 criterionpublic static QuadCurve2D[] adaptiveDegreeReduction(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(CubicCurve2D cubic, double precision, QuadSegmentConsumer resultHere)
public static void adaptiveDegreeReduction(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).Copyright © 2016. All rights reserved.