(更新中。。。。。。。)
点 结构
struct point
{
double x; // 或为double
double y;
}
{
double x; // 或为double
double y;
}
浮点处理:
1
int dbcmp(
double x)
2 {
3 if(fabs(x) < eps) return 0;
4
5 if(x < 0 ) return - 1;
6 else return 1;
7 }
2 {
3 if(fabs(x) < eps) return 0;
4
5 if(x < 0 ) return - 1;
6 else return 1;
7 }
点乘:
int betweencmp(point c,point a,point b)
//
c 是否在a ,b 间
{
return dbcmp(dot(c,a,b)) ;
}
double dotdet( double x1, double y1, double x2, double y2)
{
return x1*x2+y1*y2 ;
}
double dot(point a,point b,point c)
{
return dotdet(b.x - a.x,b.y - a.y,c.x - a.x,c.y - a.y);
}
{
return dbcmp(dot(c,a,b)) ;
}
double dotdet( double x1, double y1, double x2, double y2)
{
return x1*x2+y1*y2 ;
}
double dot(point a,point b,point c)
{
return dotdet(b.x - a.x,b.y - a.y,c.x - a.x,c.y - a.y);
}
叉积:
1
double det(
double x1,
double y1,
double x2,
double y2)
2 {
3 return x1*y2 - x2*y1;
4 }
5 double cross(point a,point b,point c)
6 {
7 return det(b.x - a.x,b.y - a.y,c.x - a.x,c.y - a.y);
8 }
2 {
3 return x1*y2 - x2*y1;
4 }
5 double cross(point a,point b,point c)
6 {
7 return det(b.x - a.x,b.y - a.y,c.x - a.x,c.y - a.y);
8 }
多边形的面积:
1
double area(point p[])
2 {
注意 p[]中的点按 顺时针或逆时针 排 ,一般按 逆时针
2 {
注意 p[]中的点按 顺时针或逆时针 排 ,一般按 逆时针
double s = 0;
4 p[n].x = p[0].x;//以 (0,0) 为 跟点 ,也可以多边形边点为 跟点(利用 有向面积 的和)
5 p[n].y = p[0].y ;
6 for(int i = 0; i<n;i++)
7 {
8 s+=det(p[i].x,p[i].y,p[i+1].x,p[i+1].y);
9
10 }
11
12 return fabs(s*0.5);
13 }
线段和线段的交点
point
get (point a,point b,point c,point d)
{
point q;
double s1, s2,s3,s4;
int d1,d2,d3,d4;
d1 = dbcmp(s1 = cross(a,b,c));
d2 = dbcmp(s2 = cross(a,b,d));
d3 = dbcmp(s3 = cross(c,d,a));
d4 = dbcmp(s4 = cross(c,d,b));
if((d1^d2) == - 2 &&(d3^d4) == - 2)//规范相交
{
q.x = (c.x*s2 - d.x*s1)/(s2 - s1) ; // 求 交点 的 x 坐标
q.y = (c.y*s2 - d.y*s1)/(s2 - s1) ; // 求 交点 的 y 坐标
return q ;
}
if(d1 == 0 && betweencmp(c,a,b) <= 0 || //非规范相交
d2 == 0 && betweencmp(d,a,b) <= 0 ||
d3 == 0 && betweencmp(a,c,d) <= 0 ||
d4 == 0 && betweencmp(b,c,d) <= 0
)
{
q.x = (c.x*s2 - d.x*s1)/(s2 - s1) ; // 求 交点 的 x 坐标
q.y = (c.y*s2 - d.y*s1)/(s2 - s1) ; // 求 交点 的 y 坐标
return q ;
}
}
{
point q;
double s1, s2,s3,s4;
int d1,d2,d3,d4;
d1 = dbcmp(s1 = cross(a,b,c));
d2 = dbcmp(s2 = cross(a,b,d));
d3 = dbcmp(s3 = cross(c,d,a));
d4 = dbcmp(s4 = cross(c,d,b));
if((d1^d2) == - 2 &&(d3^d4) == - 2)//规范相交
{
q.x = (c.x*s2 - d.x*s1)/(s2 - s1) ; // 求 交点 的 x 坐标
q.y = (c.y*s2 - d.y*s1)/(s2 - s1) ; // 求 交点 的 y 坐标
return q ;
}
if(d1 == 0 && betweencmp(c,a,b) <= 0 || //非规范相交
d2 == 0 && betweencmp(d,a,b) <= 0 ||
d3 == 0 && betweencmp(a,c,d) <= 0 ||
d4 == 0 && betweencmp(b,c,d) <= 0
)
{
q.x = (c.x*s2 - d.x*s1)/(s2 - s1) ; // 求 交点 的 x 坐标
q.y = (c.y*s2 - d.y*s1)/(s2 - s1) ; // 求 交点 的 y 坐标
return q ;
}
}
直线和线段的交点
1
double getxy(point a,point b,point c,point d)
//
a,b 代表直线 ,c,d 代表 线段
2 {
2 {
// 判断是否相交 用 叉积 就可以了
double s1 = cross(a,b,c);
4 double s2 = cross(a,b,d);
5
6 x = (c.x*s2 - d.x*s1)/(s2 - s1) ;// 求 交点 的 x 坐标
7 y = (c.y*s2 - d.y*s1)/(s2 - s1) ;// 求 交点 的 y 坐标
8 }
凸包 graham法:
int cmp(point a,point b)
{
if(a.y != b.y) return a.y < b.y;
else return a.x < b.x;
}
{
if(a.y != b.y) return a.y < b.y;
else return a.x < b.x;
}
void graham()
{
int i,len;
top = 0;
sort(p,p+n,cmp);
if(n == 0) return ;
if(n == 1) return ;
stack[top++] = p[ 0];//stack[] 为 point 栈
stack[top++] = p[ 1];
for(i = 2 ;i<n;i++) // 求右链
{
while(top > 1&& cross(stack[top - 1],stack[top - 2],p[i]) >= 0) top--; // >= 0 这 改为 > 0 可以 不去除 共线点 //注意 top 要 > 1
stack[top++] = p[i];
}
// dblcmp(cross(p[stack[top - 1]],p[stack[top - 2]],p[i])) 可以直接是 cross
len = top ;
for(i = n - 2;i >= 0;i--) // 求左链
{
while(top > len && cross(stack[top - 1],stack[top - 2],p[i]) >= 0)top--;
stack[top++] = p[i];
}
top--; // 第一个点入栈两次 所以 减 1
}
{
int i,len;
top = 0;
sort(p,p+n,cmp);
if(n == 0) return ;
if(n == 1) return ;
stack[top++] = p[ 0];//stack[] 为 point 栈
stack[top++] = p[ 1];
for(i = 2 ;i<n;i++) // 求右链
{
while(top > 1&& cross(stack[top - 1],stack[top - 2],p[i]) >= 0) top--; // >= 0 这 改为 > 0 可以 不去除 共线点 //注意 top 要 > 1
stack[top++] = p[i];
}
// dblcmp(cross(p[stack[top - 1]],p[stack[top - 2]],p[i])) 可以直接是 cross
len = top ;
for(i = n - 2;i >= 0;i--) // 求左链
{
while(top > len && cross(stack[top - 1],stack[top - 2],p[i]) >= 0)top--;
stack[top++] = p[i];
}
top--; // 第一个点入栈两次 所以 减 1
}