Рисование овального пути через четыре точки

У меня есть четыре точки, по которым я хочу нарисовать овал, проходящий через эти четыре точки  Овальный путь через четыре точки

Я не хочу использовать [UIBezierPath bezierPathWithOvalInRect:frame];, потому что он не может работать с повернутым прямоугольником.


person khaled    schedule 08.12.2016    source источник
comment
Мне интересно, есть ли у вас процедуры для выполнения следующих действий (и если это работает, потому что я нашел ответ на обмен математическим стеком, утверждающий, что для определения эллипса требуется пять баллов). 1. Уравнение можно представить в виде x ^ 2 + следующим образом: ^ 2 + cxy + dx + ey + f = 0. Итак, подключите каждую из ваших четырех пар координат к этому уравнению, чтобы получить четыре линейных уравнения о b, c, d, e и f. 2. Думаю, вам нужно пять пар. Потому что с помощью пяти уравнений вы решите систему (неплохо, если у вас есть библиотека, которая делает матрицы) или решает системы. 3) снова подключитесь и нанесите график зависимости (снова нужна процедура).   -  person Jeremy Kahan    schedule 08.12.2016
comment
См. math.stackexchange.com/questions/880258/, который утверждает, что вам нужно пять баллов. Может быть, какой-нибудь умный читатель сможет нарисовать через вашу четверку второй эллипс.   -  person Jeremy Kahan    schedule 08.12.2016
comment
Или вы даете нам конечные точки осей, как показано на картинке?   -  person Jeremy Kahan    schedule 08.12.2016
comment
@JeremyKahan Да, на самом деле я могу иметь четыре точки, как показано на изображении, по двум осям овала   -  person khaled    schedule 08.12.2016
comment
@JeremyKahan Но мне любопытно, как я могу преобразовать уравнение в рисунок на iOS   -  person khaled    schedule 08.12.2016
comment
Ах, затем возьмите середину двух конечных точек осей, чтобы получить центр (h, k), а затем используйте три точки и A (xh) ^ 2 + Bxy + C (yk) ^ 2 = 1, чтобы получить три уравнения, которые затем могут быть решенным, чтобы найти A, B и C. Тогда должно быть что-то, что строит произвольные отношения, позволяя x равняться каждому значению пикселя (цикл), находить y и строить график (x, y). В крайнем случае, вы могли бы это написать?   -  person Jeremy Kahan    schedule 08.12.2016


Ответы (1)


Я предполагаю, что ваши 4 точки не произвольные, а середины граней прямоугольника вокруг эллипса.

Вы можете построить путь из четырех кривых Безье, чтобы аппроксимировать единичную окружность с нулевым центром. Пример кода здесь

Затем примените к контрольным точкам аффинное преобразование, которое преобразует круг в повернутый эллипс с полуосями 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 для решения этой проблемы, надеюсь, это поможет. Обратите внимание, что замкнутый путь Безье содержит 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;
person MBo    schedule 08.12.2016