[数据结构] 最小覆盖圆
这个数据结构是根据 最小覆盖圆 算法进行改造得到,主要是描述一个圆的半径、圆心坐标、圆覆盖的点的圆,以及维护一个加入点的操作(push_point方法)。
成员变量如下:
- Center 圆心坐标,是一个struct point类型
- Radius 圆的半径,是一个double类型
- allPoint 点的数组,是一个vector< struct point >类型,表示这个圆覆盖的所有点
成员方法如下:
- bool inside_circle (const point&):判断输入的point是否在圆内,在圆内则返回ture,否则返回false
- void push_point (const point&):加入一个点,具体操作如下:
- 将该点加入allPoint数组
- 判断这个点的是否在圆内部,如果在圆内部直接返回
- 如果这个点在圆外部,则进行最小圆覆盖算法处理:从allPoint数组中进行枚举出一个或者两个点与push_point输入的点来形成新的圆(最小覆盖圆算法)
- 枚举一个点的原因是会存在钝角三角形的外接圆情况,此时这个钝角三角的外接圆一定可以缩小为其中两个点为直径的圆。
cpp代码:
1 struct point { 2 double x,y; 3 4 point():x(0.0),y(0.0) {} 5 point(double x, double y): x(x),y(y) {} 6 7 point operator + (const point &p) const { // (x1+x2), (y1+y2) 8 return {this->x + p.x, this->y + p.y}; 9 } 10 point operator - (const point &p) const { // (x1-x2), (y1-y2) 11 return {this->x - p.x, this->y - p.y}; 12 } 13 point operator / (const double &number) const { // (x / n), (y / n) 14 return {this->x / number, this->y / number}; 15 } 16 double distance (const point &p) const { // sq_distance = ((x1 - x2)^2 + (y1 - y2)^2) = distance^2 17 return (this->x - p.x) * (this->x - p.x) + (this->y - p.y) * (this->y - p.y); 18 } 19 point circumcenter (const point &p1, const point &p2) const { // The center of the circumscribed circle of three points 20 double x1 = this->x, x2 = p1.x, x3 = p2.x; 21 double y1 = this->y, y2 = p1.y, y3 = p2.y; 22 if ( (y2 - y1) * (x3 - x1) == (x2 - x1) * (y3 - y1)) { 23 double d1 = this->distance(p1); // this and p1 24 double d2 = this->distance(p2); // this and p2 25 double d3 = p1.distance(p2); // p1 and p3 26 if (d1 > d2 && d1 > d3) { 27 return (*this + p1) / 2.0; 28 } else if (d2 > d3) { 29 return (*this + p2) / 2.0; 30 } else { 31 return (p1 + p2) / 2.0; 32 } 33 } 34 double new_x = ((y2-y1)*(y3*y3-y1*y1+x3*x3-x1*x1)-(y3-y1)*(y2*y2-y1*y1+x2*x2-x1*x1)) / (2.0*((x3-x1)*(y2-y1)-(x2-x1)*(y3-y1))); 35 double new_y = ((x2-x1)*(x3*x3-x1*x1+y3*y3-y1*y1)-(x3-x1)*(x2*x2-x1*x1+y2*y2-y1*y1)) / (2.0*((y3-y1)*(x2-x1)-(y2-y1)*(x3-x1))); 36 return {new_x, new_y}; 37 } 38 }; 39 struct circle { 40 point center; 41 double radius; 42 std::vector< point > all_points; 43 44 circle (): center(point()), radius(0.0) {} 45 46 bool inside_point (const point &p) const { // if distance <= radius, return true; 47 return p.distance(this->center) <= this->radius; 48 } 49 50 void push_point (const point &p) { 51 this->all_points.push_back(p); 52 53 if(this->inside_point(p)) return; 54 55 this->center = p; 56 this->radius = 0.0; 57 58 for (auto i = 0; i < this->all_points.size() - 1; i++) { 59 if( this->inside_point(this->all_points[i]) ) continue; 60 61 this->center = (p + this->all_points[i]) / 2.0; 62 this->radius = p.distance(this->center); 63 64 for (int j = 0; j < i; j++) { 65 if(this->inside_point(this->all_points[j])) continue; 66 67 this->center = p.circumcenter(this->all_points[i], this->all_points[j]); 68 this->radius = p.distance(this->center); 69 } 70 } 71 } 72 };

浙公网安备 33010602011771号