算法学习:计算几何基础
Posted rentu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法学习:计算几何基础相关的知识,希望对你有一定的参考价值。
【定义】
【极角】极坐标系中的phi,对于直线来说可以直接看成斜率,因为斜率也可以表示为角度
计算几何是运用计算机中的值和代码去模拟真实的几何运算过程,所以需要先创建相对应的元素,而最基本的元素就是点,而点能够表示二维空间内的位置
同在二维空间,点和向量的储存方式类似(但是实际意义大不相同)
struct V
double x, y;
double ang;
double angle()
//求取极角
return atan2(y, x);
V(double X = 0, double Y = 0)
//初始化
x = X, y = Y;
ang = atan2(y, x);
bool operator ==(const V &b)
return cmp(x - b.x) && cmp(y - b.y);
;
通过重命名令点和向量在某些用法上有所重合
typedef V P;
定义运算(点和向量的个别运算又有所重合)
V operator +(V a, V b) return V(a.x + b.x, a.y + b.y);
V operator -(V a, V b) return V(a.x - b.x, a.y - b.y);
V operator *(V a, double b) return V(a.x *b, a.y*b);
V operator /(V a, double b) return V(a.x / b, a.y / b);
//叉积
double cross(V a, V b)
return a.x*b.y - a.y*b.x;
//点积
double dot(V a, V b)
return a.x*b.x + a.y*b.y;
而根据高中几何知识,我们知道两个点能够表示一条线段
所以有线段的定义
struct L
P s, t;
double ang;
L(P X = V(), P Y = V())
s = X, t = Y, ang = (Y - X).angle();
;
其相应运算都能够通过各种求交点,平行,叉积,点积求取完成
(证明都比较简单)
//通过斜率比较线段大小
bool operator <(const L &a, const L &b)
double r = a.ang - b.ang;
if (cmp(r) != 0) return cmp(r) == -1;
//极角相同,默认偏下的更大
return cmp(cross(a.t - a.s, b.t - a.s)) == -1;
//判断线段平行
bool is_parallel(L a, L b)
return cmp(cross(a.t - a.s, b.t - b.s)) == 0;
//查找交点
P intersection(L a, L b)
return a.s + (a.t - a.s)*(cross(b.t - b.s, a.s - b.s)) / cross(a.t - a.s, b.t - b.s);
而面的确定可以有多个点或者多个线段确定
【求多边形面积】
叉积能够表示的是:两个线段围成的平行四边形面积
然后通过逐个求取边和原点围成的多边形面积
因为叉积有正有负,所以
通过这个原理就能够求得多边形面积
double area(P *p, int n)
double res = 0;
p[n + 1] = p[1];
for (int i = 1; i <= n; i++)
res += cross(p[i], p[i + 1]);
return fabs(res / 2);
这些元素之间还有各种判断和操作
点是否在直线一侧
bool is_right(L a, P b)
//判断点b是否在直线的右边(和起点连成的向量方向和直线向量方向相反)
return cmp(cross(a.t - a.s, b - a.s)) < 0;
求点是否在多边形内
通过计算点两边的边的个数是否相等,如果相等则说明点在多边形内
同时,计算点是否在直线上,查找点在直线上的情况
点是否在多边形内
求两向量是否相交
两线段是否相交
通过以上两个知识点:
能够求两个多边形是否相交
两多边形是否相交
以上是关于算法学习:计算几何基础的主要内容,如果未能解决你的问题,请参考以下文章