From 7b1e723bef24191d4cac6772129c60f441ebe04b Mon Sep 17 00:00:00 2001 From: Bruno Freitas Tissei <bft15@inf.ufpr.br> Date: Thu, 29 Aug 2019 13:56:45 -0300 Subject: [PATCH] Add circle Signed-off-by: Bruno Freitas Tissei <bft15@inf.ufpr.br> --- algorithms/geometry/circle.cpp | 47 +++++++++++++++++++++ algorithms/geometry/geometry_primitives.cpp | 5 +++ 2 files changed, 52 insertions(+) create mode 100644 algorithms/geometry/circle.cpp diff --git a/algorithms/geometry/circle.cpp b/algorithms/geometry/circle.cpp new file mode 100644 index 0000000..91f3555 --- /dev/null +++ b/algorithms/geometry/circle.cpp @@ -0,0 +1,47 @@ +/// Circle + +struct Circle { + Point<double> c; + double r; + + Circle(Point<double> c, double r) : c(c), r(r) {} + + // Circumcircle + Circle(Point<double> a, Point<double> b, Point<double> c) { + Point<double> u((b - a).y, -(b - a).x); + Point<double> v((c - a).y, -(c - a).x); + Point<double> n = (c - b)*0.5; + + double t = u.cross(n) / v.cross(u); + + this->c = (a + c)*0.5 + v*t; + this->r = dist(this->c, a); + } + + bool contains(Point<double> p) { + return (dist(c, p) <= r + EPS); + } +}; + +// Minumum enclosing circle +Circle min_enclosing(vector<Point<double>> p) { + random_shuffle(all(p)); + Circle C(p[0], 0.0); + + for (int i = 0; i < p.size(); ++i) { + if (C.contains(p[i])) continue; + C = Circle(p[i], 0.0); + + for (int j = 0; j < i; ++j) { + if (C.contains(p[j])) continue; + C = Circle((p[j] + p[i])*0.5, 0.5*dist(p[j], p[i])); + + for (int k = 0; k < j; ++k) { + if (C.contains(p[k])) continue; + C = Circle(p[j], p[i], p[k]); + } + } + } + + return C; +} diff --git a/algorithms/geometry/geometry_primitives.cpp b/algorithms/geometry/geometry_primitives.cpp index 590ee0a..041afc2 100644 --- a/algorithms/geometry/geometry_primitives.cpp +++ b/algorithms/geometry/geometry_primitives.cpp @@ -12,6 +12,7 @@ struct Point { Point operator+(Point p) { return Point(x+p.x, y+p.y); } Point operator-(Point p) { return Point(x-p.x, y-p.y); } + Point operator*(T s) { return Point(x*s, y*s); } T dot(Point p) { return (x*p.x) + (y*p.y); } T cross(Point p) { return (x*p.y) - (y*p.x); } @@ -51,6 +52,10 @@ struct Point { } }; +double dist(Point<double> a, Point<double> b) { + return hypot(a.x - b.x, a.y - b.y); +} + template <typename T> struct Segment { Point<T> a, b; -- GitLab