0

I have a four points that I want to draw oval that path through these four pointsOval path through four points

I do not want to use [UIBezierPath bezierPathWithOvalInRect:frame]; Because it can not work with rotated rectangle.

khaled
  • 865
  • 9
  • 24
  • I am wondering if you have routines to do the following (and if it works, because I found an answer on math stack exchange claiming it takes five points to determine an ellipse). 1. The equation could be made to look like x^2+by^2+cxy+dx+ey+f=0. So plug in each of your four coordinate pairs to this equation to get four linear equations about b,c,d,e, and f. 2. I think you do need five pairs. Because with five equations you would solve the system (not bad if you have a library that does matrices) or solves systems. 3) plug back in and graph the relation (again needs a routine). – Jeremy Kahan Dec 08 '16 at 12:46
  • See http://math.stackexchange.com/questions/880258/minimal-number-of-points-to-define-a-rotated-ellipse/880292#comment4207125_880292 which claims you need five points. Maybe some clever reader can draw a second ellipse through your four. – Jeremy Kahan Dec 08 '16 at 12:50
  • Or are you giving us endpoints of the axes as pictured? – Jeremy Kahan Dec 08 '16 at 12:52
  • @JeremyKahan Yes, Actually I can have the four points as shown in the image on the two axis of the oval – khaled Dec 08 '16 at 13:30
  • @JeremyKahan But I am curious about how can I transform the equation into drawing on iOS – khaled Dec 08 '16 at 13:34
  • Ah, then take the midpoint of two axes endpoints to get the center (h,k) and then use three points and A(x-h)^2+Bxy+C(y-k)^2=1 to get three equations, which can then be solved to find A, B, and C. Then there must be something out there which plots an arbitrary relationship by letting x equal each pixel value (loop), finding y's, and plotting (x,y). In a pinch, you could write it? – Jeremy Kahan Dec 08 '16 at 13:47

1 Answers1

0

I suppose that your 4 points are not arbitrary ones, but middles of edges of rectangle around the ellipse.

You can build path from four Bezier curves to approximate zero-centered unit circle. Example of code here

Then apply to control points affine transformation that transform circle to rotated ellipse with semi-axes A and B, center (CX, CY) and rotation angle Alpha.

For your case, if points are P0..P3, then

     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)

I have Delphi code for this problem, hope it could help. Note that closed Bezier path contains 13 points (the last is the same as the first).

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;
Community
  • 1
  • 1
MBo
  • 77,366
  • 5
  • 53
  • 86