在给模型加支撑的项目中我用了凸包的算法,这是几何中的一个经典算法,单独拿出来作为以后使用的模板。
double dis_2d(Point2d a, Point2d b)
{
Point2d c = a - b;
return sqrt(c.x*c.x + c.y*c.y);
}
//叉乘
double X_2d(Point2d a, Point2d b)
{
return a.x*b.y - a.y*b.x;
}
Point2d temp_2d;//point_2d[0]左下角的点
bool bottom_cmp(const Point2d& a, const Point2d& b)
{
double x = X_2d(a - temp_2d, b - temp_2d);
if (x>0) return 1;
if (x == 0 && dis_2d(a, temp_2d)<dis_2d(b, temp_2d)) return 1;
return 0;
}
double multi(Point2d p1, Point2d p2, Point2d p3)
{
return X_2d(p2 - p1, p3 - p1);
}
void support_point::bottom_base()
{
vector<Point2d>bottom_point;
point_2d.clear();
for (int i = 0; i<point.size(); i++)
{
point_2d.push_back(Point2d(point[i].x, point[i].y));
}
int k = 1;
for (int i = 1; i<point_2d.size(); i++)
if (point_2d[i].y<point_2d[k].y || (point_2d[i].y == point_2d[k].y&&point_2d[i].x<point_2d[k].x))k = i;
swap(point_2d[0], point_2d[k]);
temp_2d = point_2d[0];
sort(point_2d.begin() + 1, point_2d.end(), bottom_cmp);
bottom_point.push_back(point_2d[0]);
bottom_point.push_back(point_2d[1]);
for (int i = 2; i<point_2d.size(); i++)
{
//while(t>=2&&multi(s[t-1],s[t],p[i])<=0) t--;
while (1)
{
int t = bottom_point.size() - 1;
if (t >= 2 && multi(bottom_point[t - 1], bottom_point[t], point_2d[i]) <= 0)
bottom_point.pop_back();
else
break;
}
bottom_point.push_back(point_2d[i]);
}
}