TheAlgorithms/C++ 1.0.0
All the algorithms implemented in C++
Loading...
Searching...
No Matches
smallest_circle.cpp
Go to the documentation of this file.
1
10#include <cmath>
11#include <iostream>
12#include <vector>
13
15struct Point {
16 double x,
17 y;
23 explicit Point(double a = 0.f, double b = 0.f) {
24 x = a;
25 y = b;
26 }
27};
28
37double LenghtLine(const Point &A, const Point &B) {
38 double dx = B.x - A.x;
39 double dy = B.y - A.y;
40 return std::sqrt((dx * dx) + (dy * dy));
41}
42
54double TriangleArea(const Point &A, const Point &B, const Point &C) {
55 double a = LenghtLine(A, B);
56 double b = LenghtLine(B, C);
57 double c = LenghtLine(C, A);
58 double p = (a + b + c) / 2;
59 return std::sqrt(p * (p - a) * (p - b) * (p - c));
60}
61
72bool PointInCircle(const std::vector<Point> &P, const Point &Center, double R) {
73 for (size_t i = 0; i < P.size(); i++) {
74 if (LenghtLine(P[i], Center) > R)
75 return false;
76 }
77 return true;
78}
79
87double circle(const std::vector<Point> &P) {
88 double minR = INFINITY;
89 double R;
90 Point C;
91 Point minC;
92
93 /* This code is invalid and does not give correct result for TEST 3 */
94 // for each point in the list
95 for (size_t i = 0; i < P.size() - 2; i++)
96 // for every subsequent point in the list
97 for (size_t j = i + 1; j < P.size(); j++)
98 // for every subsequent point in the list
99 for (size_t k = j + 1; k < P.size(); k++) {
100 // here, we now have picked three points from the given set of
101 // points that we can use
102 // viz., P[i], P[j] and P[k]
103 C.x = -0.5 * ((P[i].y * (P[j].x * P[j].x + P[j].y * P[j].y -
104 P[k].x * P[k].x - P[k].y * P[k].y) +
105 P[j].y * (P[k].x * P[k].x + P[k].y * P[k].y -
106 P[i].x * P[i].x - P[i].y * P[i].y) +
107 P[k].y * (P[i].x * P[i].x + P[i].y * P[i].y -
108 P[j].x * P[j].x - P[j].y * P[j].y)) /
109 (P[i].x * (P[j].y - P[k].y) +
110 P[j].x * (P[k].y - P[i].y) +
111 P[k].x * (P[i].y - P[j].y)));
112 C.y = 0.5 * ((P[i].x * (P[j].x * P[j].x + P[j].y * P[j].y -
113 P[k].x * P[k].x - P[k].y * P[k].y) +
114 P[j].x * (P[k].x * P[k].x + P[k].y * P[k].y -
115 P[i].x * P[i].x - P[i].y * P[i].y) +
116 P[k].x * (P[i].x * P[i].x + P[i].y * P[i].y -
117 P[j].x * P[j].x - P[j].y * P[j].y)) /
118 (P[i].x * (P[j].y - P[k].y) +
119 P[j].x * (P[k].y - P[i].y) +
120 P[k].x * (P[i].y - P[j].y)));
121 R = (LenghtLine(P[i], P[j]) * LenghtLine(P[j], P[k]) *
122 LenghtLine(P[k], P[i])) /
123 (4 * TriangleArea(P[i], P[j], P[k]));
124 if (!PointInCircle(P, C, R)) {
125 continue;
126 }
127 if (R <= minR) {
128 minR = R;
129 minC = C;
130 }
131 }
132
133 // for each point in the list
134 for (size_t i = 0; i < P.size() - 1; i++)
135 // for every subsequent point in the list
136 for (size_t j = i + 1; j < P.size(); j++) {
137 // check for diameterically opposite points
138 C.x = (P[i].x + P[j].x) / 2;
139 C.y = (P[i].y + P[j].y) / 2;
140 R = LenghtLine(C, P[i]);
141 if (!PointInCircle(P, C, R)) {
142 continue;
143 }
144 if (R <= minR) {
145 minR = R;
146 minC = C;
147 }
148 }
149 std::cout << minC.x << " " << minC.y << std::endl;
150 return minR;
151}
152
158void test() {
159 std::vector<Point> Pv;
160 Pv.push_back(Point(0, 0));
161 Pv.push_back(Point(5, 4));
162 Pv.push_back(Point(1, 3));
163 Pv.push_back(Point(4, 1));
164 Pv.push_back(Point(3, -2));
165 std::cout << circle(Pv) << std::endl;
166}
167
173void test2() {
174 std::vector<Point> Pv;
175 Pv.push_back(Point(0, 0));
176 Pv.push_back(Point(0, 2));
177 Pv.push_back(Point(2, 2));
178 Pv.push_back(Point(2, 0));
179 std::cout << circle(Pv) << std::endl;
180}
181
188void test3() {
189 std::vector<Point> Pv;
190 Pv.push_back(Point(0.5, 1));
191 Pv.push_back(Point(3.5, 3));
192 Pv.push_back(Point(2.5, 0));
193 Pv.push_back(Point(2, 1.5));
194 std::cout << circle(Pv) << std::endl;
195}
196
198int main() {
199 test();
200 std::cout << std::endl;
201 test2();
202 std::cout << std::endl;
203 test3();
204 return 0;
205}
void test2()
double circle(const std::vector< Point > &P)
double LenghtLine(const Point &A, const Point &B)
void test3()
double TriangleArea(const Point &A, const Point &B, const Point &C)
void test()
int main()
bool PointInCircle(const std::vector< Point > &P, const Point &Center, double R)
int y
Point respect to x coordinate.
Point(double a=0.f, double b=0.f)