Search code examples
javabeziercurve

Calculate the perimeter of a Bezier Curve in Java


It does not seem that there is any method in Java to calculate the perimeter of a quadratic Bezier Curve... or at least I do not recognize it.

I have search in stackoverflow and all I found was methods in other programming languages. I would be very grateful if anyone could help me find any library (or just some mathematical explanation so I could port it to Java) that could solve this problem.

Sorry if it is an obvious question, but I'm just an amateur programmer and I know little of geometry.

And sorry (again) for my crappy English

Thank you for your time! :)

P.D.: Perimeter = new tag? WAT

EDIT: Ooook, Googled better (thanks to stackoverflow's lack of "perimeter" tag... and this... is... ironyyyy) and found this: http://segfaultlabs.com/docs/quadratic-bezier-curve-length

It's a heavy and precise way to calculate the length. The webpage even includes an example of an implementation in C


Solution

  • Here's a faithful translation of the C code at the link you provided in Java. Please note that it is completely untested. I would recommend some further refactoring to improve class and parameter names.

    public class Bezier {
    
      public static class v {
    
        public double x;
        public double y;
    
        public v(double x, double y) {
          this.x = x;
          this.y = y;
        }
      }
    
      public static double length(v p0, v p1, v p2) {
        v a = new v(p0.x - (2 * p1.x) + p2.x, p0.y - (2 * p1.y) + p2.y);
        v b = new v((2 * p1.x) - (2 * p0.x), (2 * p1.y) - (2 * p0.y));
        double A = 4 * (a.x * a.x + a.y * a.y);
        double B = 4 * (a.x * b.x + a.y * b.y);
        double C = b.x * b.x + b.y * b.y;
        double Sabc = 2 * Math.sqrt(A + B + C);
        double A_2 = Math.sqrt(A);
        double A_32 = 2 * A * A_2;
        double C_2 = 2 * Math.sqrt(C);
        double BA = B / A_2;
        return (A_32 * Sabc + A_2 * B * (Sabc - C_2) + (4 * C * A - B * B) * Math.log((2 * A_2 + BA + Sabc) / (BA + C_2))) / (4 * A_32);
      }
    }