计算几何常用的函数/方法
(一)求多边形的面积(用叉积计算)
代码如下:
//叉积,可以用来判断方向和求面积
double cross(Point a,Point b,Point c){return (c.x-a.x)*(b.y-a.y) - (b.x-a.x)*(c.y-a.y);
}//求多边形的面积
double S(Point p[],int n){double ans = 0;p[n] = p[0];for(int i=1;i<n;i++)ans += cross(p[0],p[i],p[i+1]);if(ans < 0) ans = -ans;return ans / 2.0;
}
(二)求多边形的重心
代码如下:
//求多边形的重心
Point grabity(Point p[],int n){Point G;double sum_area=0;for(int i=2;i<n;i++){double area = cross(p[0],p[i-1],p[i]);sum_area+=area;G.x+=(p[0].x+p[i-1].x+p[i].x)*area;G.y+=(p[0].y+p[i-1].y+p[i].y)*area;}G.x=G.x/3/sum_area,G.y=G.y/3/sum_area;return G;
}
(三)andrew算法求凸包
代码如下:
/**
求二维凸包Andrew算法,将所有的点按x小到大(x相等,y小到大)排序
删去重复的点,得到一个序列p1,p2...,然后把p1,p2放入凸包中,从p3
开始当新点再前进方向左边时(可以用叉积判断方向)继续,否则,依次
删除最近加入凸包的点,直到新点再左边。
**/int ConvexHull(Point *p,int n,Point *stack){sort(p,p+n);n=unique(p,p+n)-p;int m=0;for(int i=0;i<n;i++){//如果不希望凸包的边上有输入的点则把两个等号去掉while(m>1&&cross(stack[m-2],p[i],stack[m-1])<=0) m--;stack[m++]=p[i];}int k=m;for(int i=n-2;i>=0;i--){while(m>k&&cross(stack[m-2],p[i],stack[m-1])<=0)m--;stack[m++]=p[i];}if(n>1) m--;return m;
}
(四)比较函数提高精度:
//判断符号,提高精度
int dcmp(double x){if(fabs(x)<eps) return 0;else return x < 0 ? -1 : 1;
}
(五)向量/以及常见运算重载
struct Point{double x,y;Point():x(0),y(0){}Point(double _x,double _y):x(_x),y(_y){}bool operator <(const struct Point &tmp) const{if(x==tmp.x) return y<tmp.y;return x<tmp.x;}
};typedef Point Vector;
Vector operator + (Vector A, Vector B){return Vector(A.x+B.x, A.y+B.y);
}
Vector operator - (Point A, Point B){return Vector(A.x-B.x, A.y-B.y);
}
Vector operator * (Vector A, double p){return Vector(A.x*p, A.y*p);
}
Vector operator / (Vector A, double p){return Vector(A.x/p, A.y/p);
}
bool operator == (Vector A,Vector B){return dcmp(A.x-B.x)==0&&dcmp(A.y-B.y)==0;
}
double Dot(Vector A, Vector B){//向量相乘return A.x*B.x + A.y*B.y; //a*b*cos(a,b)
}
double Length(Vector A){return sqrt(Dot(A, A)); //向量的长度
}
double Angle(Vector A, Vector B){return acos(Dot(A, B) / Length(A) / Length(B)); //向量的角度
}
double Cross(Vector A, Vector B){//叉积return A.x*B.y - A.y*B.x;
}
/**
向量(x,y) 绕起点逆时针旋转a度。
x' = x*cosa - y*sina
y' = x*sina + y*cosa
**/
Vector Rotate(Vector A,double a){return Vector (A.x*cos(a)-A.y*cos(a),A.x*sin(a)+A.y*cos(a));
}double trans(double ang){return ang/180*acos(-1.0);
}
(六)旋转卡壳求凸包的直径,平面最远的点对
代码如下:
//旋转卡壳求凸包的直径,平面距离最远的点对的距离
double rotatint_calipers(Point *p,int n){int k=1;int ans = 0;p[n]=p[0];for(int i=0;i<n;i++){while(fabs(Cross(p[i+1],p[k],p[i]))<fabs(Cross(p[i+1],p[k+1],p[i])))k=(k+1)%n;ans = max(ans,max(dis(p[i],p[k]),dis(p[i+1],p[k])));}return ans;
}
(七)旋转卡壳求凸包的宽度,即找一组距离最近的平行线似的凸包的点在两根线的内侧
代码如下:
double rotating_calipers(Point *p,int n){int k = 1;double ans = 0x7FFFFFFF;p[n] = p[0];for(int i=0;i<n;i++){while(fabs(cross(p[i],p[i+1],p[k])) < fabs(cross(p[i],p[i+1],p[k+1])))k = (k+1) % n;double tmp = fabs(cross(p[i],p[i+1],p[k]));double d = dist(p[i],p[i+1]);ans = min(ans,tmp/d);}return ans;
}
(八)求线段的中垂线
//求线段的中垂线
inline Line getMidLine(const Point &a, const Point &b) { Point mid = (a + b); mid.x/=2.0; mid.y/=2.0; Point tp = b-a; return Line(mid, mid+Point(-tp.y, tp.x));
}
(九)直线相关
struct Line
{ Point s,e; Line(){} Line(Point _s,Point _e) { s = _s; e = _e; } bool operator ==(Line v) { return (s == v.s)&&(e == v.e); } void input() { s.input(); e.input(); } //两线段相交判断 //2 规范相交 //1 非规范相交 //0 不相交 int segcrossseg(Line v) { int d1 = sgn((e-s)^(v.s-s)); int d2 = sgn((e-s)^(v.e-s)); int d3 = sgn((v.e-v.s)^(s-v.s)); int d4 = sgn((v.e-v.s)^(e-v.s)); if( (d1^d2)==-2 && (d3^d4)==-2 )return 2; return (d1==0 && sgn((v.s-s)*(v.s-e))<=0) || (d2==0 && sgn((v.e-s)*(v.e-e))<=0) || (d3==0 && sgn((s-v.s)*(s-v.e))<=0) || (d4==0 && sgn((e-v.s)*(e-v.e))<=0); } //直线和线段相交判断 //-*this line -v seg //2 规范相交 //1 非规范相交 //0 不相交 int linecrossseg(Line v) { int d1 = sgn((e-s)^(v.s-s)); int d2 = sgn((e-s)^(v.e-s)); if((d1^d2)==-2) return 2; return (d1==0||d2==0); }
};
计算几何常用的函数/方法相关推荐
- jQuery中常用的函数方法总结
jQuery中为我们提供了很多有用的方法和属性,自己总结的一些常用的函数,方法.个人认为在www.21kaiyun.com的紫微斗数星座在线排盘开发中会比较常用的,仅供大家学习和参考. 事件处理 re ...
- java easing_jQuery中常用的函数方法总结
jQuery中为我们提供了很多有用的方法和属性,自己总结的一些常用的函数,方法.个人认为在www.2JavaScript jQuery中为我们提供了很多有用的方法和属性,自己总结的一些常用的函数,方法 ...
- JavaScript 常用数组函数方法专题
1. 由字符串生成数组 split() 分割字符串,并将分割的部分作为一个元素保存在一个新建的数组中. var str1 = "this is an emample to using the ...
- 函数 java_java函数方法
1.方法重载 (1)源代码 // MethodOverload.java // Using overloaded methods public class MethodOverload { publi ...
- js中当等于最小值是让代码不执行_网页中JS函数自动执行常用三种方法
本文为大家分享了在网页中JS函数自动执行常用方法,供大家参考,具体内容如下 一.JS方法 1.最简单的调用方式,直接写到html的body标签里面: 2.在JS语句调用: function myfun ...
- 【JavaScript】JS的变量、数组、计算器案例、函数、类、常用对象的方法
目录 01-js-js的声明和引入 <!DOCTYPE html> <html><head><meta charset="UTF-8"&g ...
- python创建文件对象的函数_Python 文件对象常用内建方法
学习python教程文件操作时,除了 文件对象读取内容 file.read(size):size为读字节的长度,默认为-1. file.readline(size):逐行读取,如果定义了size参数, ...
- 【JS教程】100+常用JS函数(方法)
为什么80%的码农都做不了架构师?>>> 100+常用JS函数(方法) 1. document.write("");为 输出语句 2. JS中的注释为// ...
- 归一化mysql函数_数据归一化和两种常用的归一化方法
数据归一化和两种常用的归一化方法 一.总结 一句话总结: min-max标准化:x* =(x-min)/(max-min):新数据加入,需重新计算max和min Z-score标准化:x* =(x-μ ...
- 视频教程-Excel常用公式函数 if函数 vlookup函数的使用方法视频教程-Office/WPS
Excel常用公式函数 if函数 vlookup函数的使用方法视频教程 本人张光欢,在2018年4月1日注册公司邢台水滴计算机科技有限公司,从事于计算机软硬件开发,信息技术咨询服务 张光欢 ¥12.0 ...
最新文章
- 深度丨如果机器人三定律被打破,我们可以做些什么?
- REDIS 高可用性部署架构图
- python链接安卓 跳一跳
- oracle11g注册在哪里,oracle 如何新建账号密码在suse11,oracle11g和tomcat开机自启动...
- Leetcode 95. 不同的二叉搜索树 II 解题思路及C++实现
- 知识图谱领域有哪些最新研究进展?不妨从EMNLP 2021录用论文寻找答案
- 钢厂冒的白烟到底有没有污染?东北大学教授的试验结果让你大吃一惊
- JavaScript Math 对象
- python协程与多线程比较_python-协程、多线程、多进程性能比较
- 标准c语言与c51的区别,单片机学习笔记5-C51语言与标准C语言的比较
- NOIP 2000 进制转换
- Cordova框架基本原理
- java中的内存回收机制所采用的算法_JavaGC垃圾回收机制和常见算法
- 最简单的 UE 4 C++ 教程 —— 扫描多线轨迹【十六】
- 实现用户登录注册代码(高级代码)
- Clojure入门教程
- Speedoffice(PPT)如何设置文字顶部对齐
- 总结numpy中的ndarray,非常齐全
- 【产品】如何了解行业需求、痛点和发展机会
- kkt条件里面的松弛互补条件推导