绘制椭圆形路径通过四个点

时间:2016-12-08 12:01:37

标签: ios math quartz-2d

我有四点要画椭圆形,通过这四点Oval path through four points

我不想使用[UIBezierPath bezierPathWithOvalInRect:frame]; 因为它无法与旋转的矩形一起使用。

1 个答案:

答案 0 :(得分:0)

我认为你的4个点不是任意的,而是围绕椭圆的矩形边缘的中间。

您可以从四条贝塞尔曲线构建路径,以近似以零为中心的单位圆。代码示例here

然后应用于控制点仿射变换,该变换将圆变换为具有半轴A和B,中心(CX,CY)和旋转角度Alpha的旋转椭圆。

对于您的情况,如果点是P0..P3,那么

     A = |P0P2| (distance)
     B = |P1P3|
     CX = (P0.X + P2.X)/2
     CY = (P0.Y + P2.Y)/2
     Alpha = ArcTan2(P0.Y - P2.Y, P0.X - P2.X)

我有这个问题的Delphi代码,希望它可以提供帮助。请注意,关闭的Bezier路径包含13个点(最后一个与第一个相同)。

procedure CalcRotatedEllipse(CX, CY, A, B: Integer; Alpha: Double; var BezPts: array of TPoint);
const
  MP = 0.55228475;
var
  CA, SA, ACA, ASA, BCA, BSA: Double;
  i, CX2, CY2: Integer;

function TransformPoint(X, Y: Double): TPoint;
begin
  Result.X := Round(CX + X * ACA + Y * BSA);
  Result.Y := Round(CY - X * ASA + Y * BCA);
end;

begin
  Assert(Length(BezPts) = 13);
  CA:= Cos(Alpha); SA := Sin(Alpha);
  ACA := A * CA; ASA := A * SA;
  BCA := B * CA; BSA := B * SA;
  CX2 := 2 * CX;  CY2 := 2 * CY;
  BezPts[0] := TransformPoint(1, 0);
  BezPts[1] := TransformPoint(1, MP);
  BezPts[2] := TransformPoint(MP, 1);
  BezPts[3] := TransformPoint(0, 1);
  BezPts[4] := TransformPoint(- MP, 1);
  BezPts[5] := TransformPoint(-1, MP);
  for i := 0 to 5 do
    BezPts[i + 6] := Point(CX2 - BezPts[i].X, CY2 - BezPts[i].Y);
  BezPts[12] := BezPts[0];
end;

procedure TForm1.Button3Click(Sender: TObject);
var
  Pts: array[0..12] of TPoint;
begin
  CalcRotatedEllipse(200, 200, 200, 70, Pi/6, Pts);
  Canvas.PolyBezier(Pts);
end;