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