Skip to content

Commit f49bb23

Browse files
committed
naive algorithm for the circumscribed circle
1 parent f859394 commit f49bb23

File tree

1 file changed

+121
-0
lines changed

1 file changed

+121
-0
lines changed

smallest-circle.cpp

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
#include <iostream>
2+
#include <vector>
3+
#include <math.h>
4+
5+
using namespace std;
6+
7+
struct Point {
8+
double x, y;
9+
Point(double a = 0.0, double b = 0.0)
10+
{
11+
x = a;
12+
y = b;
13+
}
14+
};
15+
16+
double LenghtLine(Point A, Point B)
17+
{
18+
return sqrt(abs((B.x - A.x)*(B.x - A.x)) + abs((B.y - A.y)*(B.y - A.y)));
19+
}
20+
21+
double TriangleArea(Point A, Point B, Point C)
22+
{
23+
double a = LenghtLine(A, B);
24+
double b = LenghtLine(B, C);
25+
double c = LenghtLine(C, A);
26+
double p = (a + b + c) / 2;
27+
return sqrt(p*(p - a)*(p - b)*(p - c));
28+
}
29+
30+
bool PointInCircle(vector<Point> &P, Point Center, double R)
31+
{
32+
for (size_t i = 0; i < P.size(); i++)
33+
{
34+
if (LenghtLine(P[i], Center) > R)
35+
return false;
36+
}
37+
return true;
38+
}
39+
40+
double circle(vector<Point> P)
41+
{
42+
double minR = INT8_MAX;
43+
double R;
44+
Point C;
45+
Point minC;
46+
for (size_t i = 0; i < P.size() - 2; i++)
47+
for (size_t j = i+1; j < P.size(); j++)
48+
for (size_t k = j+1; k < P.size(); k++)
49+
{
50+
C.x = -0.5 * ((P[i].y*(P[j].x*P[j].x + P[j].y*P[j].y - P[k].x*P[k].x - P[k].y*P[k].y) + P[j].y*(P[k].x*P[k].x + P[k].y*P[k].y - P[i].x*P[i].x - P[i].y*P[i].y) + P[k].y*(P[i].x*P[i].x + P[i].y*P[i].y - P[j].x*P[j].x - P[j].y*P[j].y)) / (P[i].x*(P[j].y - P[k].y) + P[j].x*(P[k].y - P[i].y) + P[k].x*(P[i].y - P[j].y) ));
51+
C.y = 0.5 * ((P[i].x*(P[j].x*P[j].x + P[j].y*P[j].y - P[k].x*P[k].x - P[k].y*P[k].y) + P[j].x*(P[k].x*P[k].x + P[k].y*P[k].y - P[i].x*P[i].x - P[i].y*P[i].y) + P[k].x*(P[i].x*P[i].x + P[i].y*P[i].y - P[j].x*P[j].x - P[j].y*P[j].y)) / (P[i].x*(P[j].y - P[k].y) + P[j].x*(P[k].y - P[i].y) + P[k].x*(P[i].y - P[j].y) ));
52+
R = (LenghtLine(P[i], P[j]) * LenghtLine(P[j], P[k]) * LenghtLine(P[k], P[i])) / (4 * TriangleArea(P[i], P[j], P[k]));
53+
if (!PointInCircle(P, C, R))
54+
{
55+
continue;
56+
}
57+
if (R <= minR)
58+
{
59+
minR = R;
60+
minC = C;
61+
}
62+
63+
}
64+
for (size_t i = 0; i < P.size() - 1; i++)
65+
for (size_t j = i + 1; j < P.size(); j++)
66+
{
67+
C.x = (P[i].x + P[j].x) / 2;
68+
C.y = (P[i].y + P[j].y) / 2;
69+
R = LenghtLine(C, P[i]);
70+
if (!PointInCircle(P, C, R))
71+
{
72+
continue;
73+
}
74+
if (R <= minR)
75+
{
76+
minR = R;
77+
minC = C;
78+
}
79+
}
80+
cout << minC.x << " " << minC.y << endl;
81+
return minR;
82+
}
83+
84+
void test()
85+
{
86+
vector<Point> Pv(5);
87+
Pv.push_back(Point(0,0));
88+
Pv.push_back(Point(1,3));
89+
Pv.push_back(Point(4,1));
90+
Pv.push_back(Point(5,4));
91+
Pv.push_back(Point(3,-2));
92+
cout << circle(Pv) << endl;
93+
}
94+
95+
void test2()
96+
{
97+
vector<Point> Pv(4);
98+
Pv.push_back(Point(0,0));
99+
Pv.push_back(Point(0,2));
100+
Pv.push_back(Point(2,2));
101+
Pv.push_back(Point(2,0));
102+
cout << circle(Pv) << endl;
103+
}
104+
105+
void test3()
106+
{
107+
vector<Point> Pv(3);
108+
Pv.push_back(Point(0.5,1));
109+
Pv.push_back(Point(3.5,3));
110+
Pv.push_back(Point(2.5,0));
111+
cout << circle(Pv) << endl;
112+
}
113+
int main()
114+
{
115+
test();
116+
cout << endl;
117+
test2();
118+
cout << endl;
119+
test3();
120+
return 0;
121+
}

0 commit comments

Comments
 (0)