Question

I have some paths represented by Path2D. The Path consist of multiple CubicCurve2D or Line2D segments that are connected to each other. I would like to calculate or get the length from the start to the end of a Path. How can I calculate it or get it? Is it possible? I have checked the API documentation, but couldn't find any useful methods.

Was it helpful?

Solution

In light of a previous question on this topic, the article Computing the Arc Length of Cubic Bezier Curves may offer some insight. For convenience, you may want to look at the JScience Polynomial class. Also, this approximation, based on the same article, may help.

OTHER TIPS

Start by using getPathIterator() to get the path elements. If the path only has SEG_MOVETO and SEG_LINETO elements, the length should be easy to calculate. Just sum sqrt((X1-X2)^2 + (Y1-Y2)^2) for all of the SEG_LINETO, where point (X1, Y1) was the previous endpoint, and (X2, Y2) is the current one returned by currentSegment(double[]).

If it also contains SEG_QUADTO or SEG_CUBICTO elements, that will require a more complicated formula that I don't care to figure out right now (may require calculus).

First of all sorry for my english...

I know this is an old topic but perhaps it's useful for someone. I made this, is not for a CubicCurve but for a QuadCurve:

public double CurveLength (QuadCurve curve){
    double xini = curve.getStartX();
    double yini = curve.getStartY();
    double xpoint = curve.getControlX();
    double ypoint = curve.getControlY();
    double xfin = curve.getEndX();
    double yfin = curve.getEndY();

    double ax = xini-(2*xpoint)+xfin;
    double ay = yini-(2*ypoint)+yfin;
    double bx = (2*xpoint)-(2*xini);
    double by = (2*ypoint)-(2*yini);
    double A = 4*((ax*ax)+(ay*ay));
    double B = 4*((ax*bx)+(ay*by));
    double C = (bx*bx)+(by*by);

    double Sabc = 2*(Math.sqrt(A+B+C));
    double A2 = Math.sqrt(A);
    double A32 = 2*A*A2;
    double C2 = 2*(Math.sqrt(C));
    double BA = B/A2;

    double length = ((A32*Sabc) + (A2*B*(Sabc-C2)) + (((4*C*A)-(B*B))*Math.log(((2*A2)+BA+Sabc)/(BA+C2))))/(4*A32);
    return length;
}

You can use the function public PathIterator getPathIterator(AffineTransform at, double flatness);

This will give a 'flattenend' iterator containing only SEG_MOVETO, SEG_LINETO, and SEG_CLOSE segments.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top