xamlmathsvggeometrygeometric-arc

Get points of svg/xaml arc


Format of svg arc (arc in xaml have same args):

(rx ry x-axis-rotation large-arc-flag sweep-flag x y)

Description:

Draws an elliptical arc from the current point to (x, y). The size and orientation of the ellipse are defined by two radii (rx, ry) and an x-axis-rotation, which indicates how the ellipse as a whole is rotated relative to the current coordinate system. The center (cx, cy) of the ellipse is calculated automatically to satisfy the constraints imposed by the other parameters. large-arc-flag and sweep-flag contribute to the automatic calculations and help determine how the arc is drawn.

I need to calc all point of it arc (with some step, of course). How I can do it? I would like to code on C# or on Java.


Solution

  • Bresenham algorithm is invented for point-by-point drawing.

    Some code found for rotated ellipse (wayback machine)

    Added: How to transform zero-centered ellipse to needed implicit form (A,B,C,D,E,F)

    A := (Cos(fi)/rx)^2 + (Sin(fi)/ry)^2;
    
    C := (Sin(fi)/rx)^2 + (Cos(fi)/ry)^2;
    
    B := Sin(2*fi)*(1/(ry*ry) - 1/(rx*rx));
    
    D=E=0;
    
    F:=-1
    

    Checked for rx=100, ry=60, fi=Pi/6: enter image description here

    One more step: Delphi function to obtain implicit form for an arbitrary ellipse. I hope that code is understandable (Sqr(x) = x*x)

    //calc implicit ellipse equation
    //semiaxes rx, ry; rotated at fi radians; centered at (cx,cy)
    //x = rx * Cos(t) * Cos(fi) - ry * Sin(t) * Sin(fi) + cx
    //y = rx * Cos(t) * Sin(fi) + ry * Sin(t) * Cos(fi) + cy
    //To obtain implicit equation, exclude t
    //note: implicit form Ax^2+Bxy+Cy^2+Dx+Ey+F=0 (not 2B,2D,2E)
    
    procedure CalcImplicitEllipseEquation(rx, ry, fi, cx, cy: Double;
                                          var A, B, C, D, E, F:  Double);
    begin
      B := Sin(2 * Fi) * (ry * ry - rx * rx);
      A := Sqr(ry * Cos(fi)) + Sqr(rx * Sin(fi));
      C := Sqr(rx * Cos(fi)) + Sqr(ry * Sin(fi));
      D := -B * cy - 2 * A * cx;
      E := -2 * C * cy - B * cx;
      F := C * cy * cy + A * cx * cx + B * cx * cy - rx * rx * ry * ry;
    end;