// Two boundary points known Circle *makeCircleTwoPoints(vector<Point> &points, int fromIdx, int toIdx, Point p, Point q) { Circle *temp = makeDiameter(p, q); bool ContainsAll=1; for(int i = fromIdx; i < toIdx; ++i) if(!temp->contains(points[i])){ ContainsAll = 0; break; } if (ContainsAll) return temp; Circle *left = NULL; Circle *right = NULL; for (int i = fromIdx; i < toIdx; ++i) { Point r = points[i]; Point pq = q.subtract(p); double cross = pq.cross(r.subtract(p)); Circle *c = makeCircumcircle(p, q, r); if (c == NULL) continue; else if (cross > 0 && (left == NULL || pq.cross(c->c.subtract(p)) > pq.cross(left->c.subtract(p)))) left = c; else if (cross < 0 && (right == NULL || pq.cross(c->c.subtract(p)) < pq.cross(right->c.subtract(p)))) right = c; } return right == NULL || (left != NULL && left->r) <= right->r ? left : right; }
/* * Returns the smallest circle that encloses all the given points. Runs in expected O(n) time, randomized. * Note: If 0 points are given, null is returned. If 1 point is given, a circle of radius 0 is returned. */ Circle *makeCircle(vector<Point> points) { random_shuffle(points.begin(),points.end()); Circle *c = NULL; for (int i = 0; i < points.size(); i++) { Point p = points[i]; if (c == NULL || !c->contains(p)) c = makeCircleOnePoint(points,0,i, p); } return c; }
Circle *makeCircleOnePoint(vector<Point> &points, int fromIdx, int toIdx, Point p) { Circle *c = new Circle(p, 0); for (int i = fromIdx; i < toIdx; i++) { Point q = points[i]; if (!c->contains(q)) { if (c->r == 0) c = makeDiameter(p, q); else c = makeCircleTwoPoints(points,0,i, p, q); } } return c; }
bool H2Geodesic::contains(const H2Point & p) const { if (isCircleInDiskModel()) { Circle C; getCircleInDiskModel(C); return C.contains(p.getDiskCoordinate()); } else { PlanarLine L; getLineInDiskModel(L); return L.contains(p.getDiskCoordinate()); } }