How to calculate the length of a Path2D in Java?
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 chec开发者_StackOverflow社区ked the API documentation, but couldn't find any useful methods.
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).
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.
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.
精彩评论