Advertisement
WarPie90

MinAreaCircle - December 2024 version

Dec 17th, 2024 (edited)
130
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 3.09 KB | None | 0 0
  1. program new;
  2.  
  3. var
  4.   img: TImage;
  5.   TPA: TPointArray;
  6.   c: TCircle;
  7.  
  8. (*
  9.   Smallest bounding circle algorithm by Slacky
  10.   https://en.wikipedia.org/wiki/Smallest-circle_problem
  11.  
  12.   Time complexity: O(n log n)
  13.  
  14.   Where `h` is the length of the convex hull, and `n` is the data size.
  15.   Can be guaranteed O(n log n) with rotating calipers algorithm for FurthestPoints,
  16.   dont think it's worth the added complexity though.
  17.  
  18.   Edit: Refinement should be made iterative, this refinement process may be incomplete in rare cases.
  19. *)
  20. function TPointArray.MinAreaCircle2(): TCircle;
  21. var
  22.   poly: TPointArray;
  23.   p1,p2,p3,p,q,t: TPoint;
  24.  
  25.   function Circle3(const P1,P2,P3: TPoint): TCircle;
  26.   var
  27.     t,d,l: Single;
  28.     p,pcs,q,qcs: record x,y: Single; end;
  29.   begin
  30.     t   := ArcTan2(p1.y-p2.y, p1.x-p2.x) - PI/2;
  31.     p   := [(p1.x+p2.x) / 2, (p1.y+p2.y) / 2];
  32.     pcs := [Cos(t), Sin(t)];
  33.  
  34.     t   := ArcTan2(p1.y-p3.y, p1.x-p3.x) - PI/2;
  35.     q   := [(p1.x+p3.x) / 2, (p1.y+p3.y) / 2];
  36.     qcs := [Cos(t), Sin(t)];
  37.  
  38.     d := pcs.x * qcs.y - pcs.y * qcs.x;
  39.     if Abs(d) < 0.001 then Exit();
  40.     l := (qcs.x * (p.y - q.y) - qcs.y * (p.x - q.x)) / d;
  41.     Result.x := Round(p.x + l * pcs.x);
  42.     Result.y := Round(p.y + l * pcs.y);
  43.     Result.Radius := Ceil(Sqrt(Sqr((p.x + l * pcs.x)-p1.x) + Sqr((p.y + l * pcs.y)-p1.y)));
  44.   end;
  45.  
  46. begin
  47.   poly := Self.ConvexHull();  // O(n log n)
  48.   FurthestPointsPolygon(poly, p1,p2);
  49.  
  50.   p := [(p1.x+p2.x) div 2, (p1.y+p2.y) div 2];
  51.   t := poly.FurthestPoint(p);
  52.  
  53.   // Two Point Circle
  54.   if (p1 = t) or (p2 = t) then
  55.     Exit([p.x,p.y, Ceil( p1.DistanceTo(p2) / 2 )]);
  56.  
  57.   // Three Point Circle
  58.   p := Circle3(p1, p2, t).Center;
  59.   q := poly.FurthestPoint(p);
  60.  
  61.   if Sign(CrossProduct(q,  p1, p2)) = Sign(CrossProduct(t, p1, p2)) then
  62.     p3 := q
  63.   else
  64.     p3 := t;
  65.  
  66.   p := Circle3(p1,p2,p3).Center;
  67.   q := poly.FurthestPoint(p);
  68.   if (p1 <> q) and (p2 <> q) and (p3 <> q) then
  69.   begin
  70.     p := [(p3.x+q.x) div 2, (p3.y+q.y) div 2];
  71.     if p1.DistanceTo(p) < p2.DistanceTo(p) then
  72.     begin
  73.       p1 := q;
  74.       Swap(p1, p2);
  75.     end else
  76.       p2 := q;
  77.  
  78.     p := Circle3(p1, p2, p3).Center;
  79.     q := poly.FurthestPoint(p);
  80.     if (p1 <> q) and (p2 <> q) and (p3 <> q) then
  81.       p1 := q;
  82.   end;
  83.  
  84.   Result := Circle3(p1, p2, p3);
  85. end;
  86.  
  87. function TPointArray.ToString(): string;
  88. var p: TPoint;
  89. begin
  90.   Result += '[';
  91.   for p in self do
  92.     Result += '['+ToString(p.x)+','+ToString(p.y)+'],';
  93.   SetLength(Result, Length(Result)-1);
  94.   Result += ']';
  95. end;
  96.  
  97. var
  98.   i: Int32;
  99.   poly: TPointArray;
  100.   c1,c2: TCircle;
  101.   p: TPoint;
  102. begin
  103.   img := TImage.Create(900,900);
  104.   img.Show(False);
  105.   RandSeed := 12345;
  106.   Writeln(RandSeed);
  107.  
  108.   i := 0;
  109.   while True do
  110.   begin
  111.     TPA := RandomTPA(50, [250,250,550,550]);
  112.  
  113.     img.DrawColor := $FF;
  114.     img.DrawPolygon(TPA.ConvexHull());
  115.  
  116.     c2 := TPA.MinAreaCircle2();
  117.     img.DrawColor := $FFFF00;
  118.     img.DrawCircle(c2.Center, c2.Radius);
  119.  
  120.     img.DrawColor := $FF;
  121.     img.DrawPolygon(TPA.ConvexHull());
  122.  
  123.  
  124.     img.Show(False);
  125.     img.Clear();
  126.  
  127.     Inc(i);
  128.   end;
  129.  
  130.   img.Show(False);
  131. end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement