惯例贴详解
graham扫描法这个图片不错 https://blog.csdn.net/neau2014/article/details/48225965
然后就是代码如何实现 https://www.cnblogs.com/wpbing/p/9456240.html
struct Point{
double x, y;
}p[1100], st[1100];
叉积(叉乘):
double X(double x1, double y1, double x2, double y2){
return x1*y2 - y1*x2;
}
线段长:
double dis(Point a, Point b){
double sum1 = abs(b.x-a.x);
double sum2 = abs(b.y-a.y);
return sqrt(sum1*sum1 + sum2*sum2);
}
极角排序:
bool cmp(Point a, Point b){
double x = X(a.x - p[1].x, a.y-p[1].y, b.x - p[1].x, b.y-p[1].y);
if(x > 0) return 1;
if(!x && dis(a, p[1]) > dis(b, p[1])) return 1;
return 0;
}
判断ac是否在ab的顺时针方向,凸包上的连续三个点a.b.c应该ac在ab顺时针方向:
bool judge(Point a, Point b, Point c){
if(X(b.x-a.x, b.y-a.y, c.x-a.x, c.y-a.y) > 0) return 1;
return 0;
}
求凸包集合s:
void solve(){
s[1] = p[1];
s[2] = p[2]; //前两个点初始点
int pos = 2; //表示凸包集合栈顶
for(int i = 3; i <= n; i++){
while(t > 2 && !judge(s[pos-1], s[pos], p[i])) pos--;
s[++pos] = p[i];
}
}
求凸包周长:
double L(){
double sum = 0;
for(int i=1;i<t;i++){
sum+=dis(s[i],s[i+1]);
}
}
求任意多边形面积(点集已经按照顺时针或者逆时针排好序了):
提示: s = (ab*sin0)/2 即a向量和b向量叉乘的一半
double S(){
if(n < 3) return 0;
double sum = 0;
p[n + 1] = p[1]; //画个图就知道了
for(int i = 1; i <= n; i++)
sum += p[i].x * p[i + 1].y - p[i].y * p[i + 1].x;
//可以理解为不管这个多边形在哪,都以原点为分割点,
//就算原点在外面也可以算出,因为有正负可以抵消掉多余的
return fabs(sum / 2.0);
}
有段话我左看右看就不知道哪里触动赵家人了,相册都给我屏蔽:
清华郭于华:我未必能唤醒周围的人,我只是挣扎着不让自己沉睡;我没能力推翻一堵墙,但我不会给这堵墙增加哪怕一块砖;我注定改变不了权势,我只是抗争着不让权势改变我;我可能一辈子看不到未来,但我永远铭记着自己的信仰和方向。每个人灵魂深处都有颗种子,有人选择弃置,有人会给他创造成长的土壤。