您的位置:首页 > 其它

文章标题 计算几何

2017-10-25 18:44 429 查看
#include<iostream>
#include<string>
#include<cstdio>
#include<cstring>
#include<vector>
#include<math.h>
#include<map>
#include<queue>
#include<algorithm>
using namespace std;
const double pi=acos(-1.0);
const int inf = 0x3f3f3f3f;
const int maxn=100005;
const double eps=1e-8;
//精度函数
int sgn(double x){
if (fabs(x)<eps)return 0;
if (x<0) return -1;
return 1;
}

struct point {
double x,y;
point (double a=0,double b=0){
x=a;y=b;
}
bool operator <(const point &t){
return (x<t.x)||(x==t.x&&y<t.y);
}
//相减
point operator - (const point &b)const {
return point(x-b.x,y-b.y);
}
//叉积
double operator ^ (const point &b)const{
return x*b.y-y*b.x;
}
//点积
double operator * (const point &b) const {
return x*b.x+y*b.y;
}
//绕原点旋转角度B(弧度值),后x,y的变化 ,返回点
point transXY(double B){
double tx=x,ty=y;
x = tx*cos(B) - ty*sin(B);
y = tx*sin(B) + ty*cos(B);
return point(x,y);
}
};

struct line{
point s,e;
line(){}
line (point x,point y){
s=x,e=y;
}
//两直线相交求交点
//第一个值为0表示直线重合,为1表示平行,为0表示相交,为2是相交
//只有第一个值为2时,交点才有意义
pair<int,point> operator &(const line &b)const{
point res = s;
if(sgn((s-e)^(b.s-b.e)) == 0){
if(sgn((s-b.e)^(b.s-b.e)) == 0)return make_pair(0,res);//重合
else return make_pair(1,res);//平行
}
double t = ((s-b.s)^(b.s-b.e))/((s-e)^(b.s-b.e));
res.x += (e.x-s.x)*t;
res.y += (e.y-s.y)*t;
return make_pair(2,res);
}
};

//计算多边形面积
//点的编号从0~n-1
double calArea(point P[],int len){
double ans=0;
for (int i=0;i<len;i++){
ans+=(P[i]^P[(i+1)%len])/2;
}
return fabs(ans);
}

//*判断线段相交
bool inter(line l1,line l2){
return
max(l1.s.x,l1.e.x)>=min(l2.s.x,l2.e.x)&&
max(l2.s.x,l2.e.x)>=min(l1.s.x,l1.e.x)&&
max(l1.s.y,l1.e.y)>=min(l2.s.y,l2.e.y)&&
max(l2.s.y,l2.e.y)>=min(l1.s.y,l1.e.y)&&
sgn((l2.s-l1.e)^(l1.s-l1.e))*sgn((l2.e-l1.e)^(l1.s-l1.e))<=0&&
sgn((l1.s-l2.e)^(l2.s-l2.e))*sgn((l1.e-l2.e)^(l2.s-l2.e))<=0;
}

//求凸包
/*
计算凸包,输入点数组p,个数为n,输出点数组ch,函数返回凸包定点的数
输入不能有重复点。函数执行完之后输入点的顺序被破坏
如果不希望在凸包的边上有输出点,把两个<=改成<
在精度也要求高时建议用sgn比较
*/
int convexHull(point p[],int n,point ch[]){
sort(p,p+n);
int m=0;
for (int i=0;i<n;i++){
while (m>1&&(sgn(point(ch[m-1]-ch[m-2])^point(p[i]-ch[m-2])))<=0)m--;
ch[m++]=p[i];
}
int k=m;
for (int i=n-2;i>=0;i--){
while (m>k&&(sgn(point(ch[m-1]-ch[m-2])^point(p[i]-ch[m-2])))<=0)m--;
ch[m++]=p[i];
}
if (n>1)m--;
return m;
}

//二分判断点A是否在凸包边界上和内部里面 ,ch表示凸包数组
bool check(point A,int n){
int l=1,r=n-2;
while (l<=r){
int mid=(r+l)/2;
double a1=(ch[mid]-ch[0])^(A-ch[0]);
double a2=(ch[mid+1]-p[0]^(A-ch[0]));
if (sgn(a1)>=0&&sgn(a2)<=0){
if (sgn((ch[mid+1]-ch[mid])^(A-ch[mid]))>=0)return true;
return false;
}
if (a1<0)r=mid-1;
else l=mid+1;
}
return false;
}

int main()
{

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: