I want to know how to get the bounds of an QuadCurve2D. I found a method to get the bounds from a CubicCurve2D.
Using this methods is possible to change it to use QuadCurve2D?
private static void ProcessMonotonicCubic(double[] coords, double[] bbox ) {
if (bbox[0] > coords[0]) bbox[0] = coords[0];
if (bbox[1] > coords[1]) bbox[1] = coords[1];
if (bbox[2] < coords[0]) bbox[2] = coords[0];
if (bbox[3] < coords[1]) bbox[3] = coords[1];
if (bbox[0] > coords[6]) bbox[0] = coords[6];
if (bbox[1] > coords[7]) bbox[1] = coords[7];
if (bbox[2] < coords[6]) bbox[2] = coords[6];
if (bbox[3] < coords[7]) bbox[3] = coords[7];
}
/*
* Bite the piece of the cubic curve from start point till the point
* corresponding to the specified parameter then call ProcessCubic for the
* bitten part.
* Note: coords array will be changed
*/
private static void ProcessFirstMonotonicPartOfCubic(double[] coords,
double[] bbox,
double t)
{
double[] coords1 = new double[8];
double tx, ty;
coords1[0] = coords[0];
coords1[1] = coords[1];
tx = coords[2] + t*(coords[4] - coords[2]);
ty = coords[3] + t*(coords[5] - coords[3]);
coords1[2] = coords[0] + t*(coords[2] - coords[0]);
coords1[3] = coords[1] + t*(coords[3] - coords[1]);
coords1[4] = coords1[2] + t*(tx - coords1[2]);
coords1[5] = coords1[3] + t*(ty - coords1[3]);
coords[4] = coords[4] + t*(coords[6] - coords[4]);
coords[5] = coords[5] + t*(coords[7] - coords[5]);
coords[2] = tx + t*(coords[4] - tx);
coords[3] = ty + t*(coords[5] - ty);
coords[0]=coords1[6]=coords1[4] + t*(coords[2] - coords1[4]);
coords[1]=coords1[7]=coords1[5] + t*(coords[3] - coords1[5]);
ProcessMonotonicCubic(coords1, bbox);
}
/*
* Split cubic curve into monotonic in X and Y parts. Calling
* ProcessMonotonicCubic for each monotonic piece of the curve.
*
* Note: coords array could be changed
*/
private static void ProcessCubic(double[] coords, double[] bbox) {
/* Temporary array for holding parameters corresponding to the extreme
* in X and Y points
*/
double params[] = new double[4];
double eqn[] = new double[3];
double res[] = new double[2];
int cnt = 0;
/* Simple check for monotonicity in X before searching for the extreme
* points of the X(t) function. We first check if the curve is
* monotonic in X by seeing if all of the X coordinates are strongly
* ordered.
*/
if ((coords[0] > coords[2] || coords[2] > coords[4] ||
coords[4] > coords[6]) &&
(coords[0] < coords[2] || coords[2] < coords[4] ||
coords[4] < coords[6]))
{
/* Searching for extreme points of the X(t) function by solving
* dX(t)
* ---- = 0 equation
* dt
*/
eqn[2] = -coords[0] + 3*coords[2] - 3*coords[4] + coords[6];
eqn[1] = 2*(coords[0] - 2*coords[2] + coords[4]);
eqn[0] = -coords[0] + coords[2];
int nr = QuadCurve2D.solveQuadratic(eqn, res);
开发者_Go百科 /* Following code also correctly works in degenerate case of
* the quadratic equation (nr = -1) because we do not need
* splitting in this case.
*/
for (int i = 0; i < nr; i++) {
if (res[i] > 0 && res[i] < 1) {
params[cnt++] = res[i];
}
}
}
/* Simple check for monotonicity in Y before searching for the extreme
* points of the Y(t) function. We first check if the curve is
* monotonic in Y by seeing if all of the Y coordinates are strongly
* ordered.
*/
if ((coords[1] > coords[3] || coords[3] > coords[5] ||
coords[5] > coords[7]) &&
(coords[1] < coords[3] || coords[3] < coords[5] ||
coords[5] < coords[7]))
{
/* Searching for extreme points of the Y(t) function by solving
* dY(t)
* ----- = 0 equation
* dt
*/
eqn[2] = -coords[1] + 3*coords[3] - 3*coords[5] + coords[7];
eqn[1] = 2*(coords[1] - 2*coords[3] + coords[5]);
eqn[0] = -coords[1] + coords[3];
int nr = QuadCurve2D.solveQuadratic(eqn, res);
/* Following code also correctly works in degenerate case of
* the quadratic equation (nr = -1) because we do not need
* splitting in this case.
*/
for (int i = 0; i < nr; i++) {
if (res[i] > 0 && res[i] < 1) {
params[cnt++] = res[i];
}
}
}
if (cnt > 0) {
/* Sorting parameter values corresponding to the extreme points
* of the curve
*/
Arrays.sort(params, 0, cnt);
/* Processing obtained monotonic parts */
ProcessFirstMonotonicPartOfCubic(coords, bbox,
(float)params[0]);
for (int i = 1; i < cnt; i++) {
double param = params[i] - params[i-1];
if (param > 0) {
ProcessFirstMonotonicPartOfCubic(coords, bbox,
/* Scale parameter to match with rest of the curve */
(float)(param/(1.0 - params[i - 1])));
}
}
}
ProcessMonotonicCubic(coords, bbox);
}
private Rectangle2D.Double getCurveBounds(CubicCurve2D curve) {
double minX = Double.MAX_VALUE, minY = Double.MAX_VALUE;
double maxX = Double.MIN_VALUE, maxY = Double.MIN_VALUE;
double [] bbox = new double[] {Double.MAX_VALUE, Double.MAX_VALUE, Double.MIN_VALUE, Double.MIN_VALUE};
ProcessCubic(new double[] {curve.getP1().getX(), curve.getP1().getY(),
curve.getCtrlP1().getX(), curve.getCtrlP1().getY(), curve.getCtrlP2().getX(),
curve.getCtrlP2().getY(), curve.getP2().getX(), curve.getP2().getY()}, bbox);
return new Rectangle2D.Double(bbox[0], bbox[1], bbox[2] - bbox[0], bbox[3] - bbox[1]);
}
"How does your use of the term "bounds" differ from the result of getBounds()?" Get bounds 2D grab the control points, i want an rectangle that doesn't wrap the control points.
well testing a little i found another method in the same site that can be changed to use QuadCurve2D. Here is the code:
private Rectangle2D.Double getCurveBounds(QuadCurve2D.Double curve) {
double flatness = 0.01;
PathIterator pit = curve.getPathIterator(null, flatness);
double[] coords = new double[2];
double minX = Double.MAX_VALUE, minY = Double.MAX_VALUE;
double maxX = Double.MIN_VALUE, maxY = Double.MIN_VALUE;
while(!pit.isDone()) {
int type = pit.currentSegment(coords);
switch(type) {
case PathIterator.SEG_MOVETO:
// fall through
case PathIterator.SEG_LINETO:
if(coords[0] < minX) minX = coords[0];
if(coords[0] > maxX) maxX = coords[0];
if(coords[1] < minY) minY = coords[1];
if(coords[1] > maxY) maxY = coords[1];
break;
}
pit.next();
}
return new Rectangle2D.Double(minX, minY, maxX-minX, maxY-minY);
}
hope it helps someone. :D
精彩评论