ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

平面计算几何全家桶

2022-08-05 13:36:15  阅读:169  来源: 互联网

标签:return point double bm 全家 times vec 几何 平面


平面计算几何全家桶

点与向量

向量的线性运算

struct vec{
	double x,y;
	vec(){}
	vec(double _x,double _y){x=_x;y=_y;}
	friend vec operator + (vec p,vec q){return vec(p.x+q.x,p.y+q.y);}
	friend vec operator - (vec p,vec q){return vec(p.x-q.x,p.y-q.y);} 
	friend vec operator * (vec p,double k){return vec(p.x*k,p.y*k);}
	friend vec operator / (vec p,double k){return p*(1.0/k);}
};

本质上点和向量用的是同一个类型,但还是定义两个名字清晰一些

typedef vec point;

点+向量=点

向量旋转

点积

\[\bm{a} \cdot \bm{b}= |\bm{a}||\bm{b}|\cos <\bm{a},\bm{b}>=x_1x_2+y_1y_2 \]

double dot(vec p,vec q){return p.x*q.x+p.y*q.y;}
double dist(point P,point Q){return sqrt(dot(P-Q,P-Q));}
double dist2(point P,point Q){return dot(P-Q,P-Q);}//距离的平方

\(|\bm{a}|^2=\bm{a} \cdot \bm{a}\),因此用点积表示向量长度与两点距离

用点积可求向量投影

叉积

\[\bm{a} \times \bm{b}= |\bm{a}||\bm{b}|\sin <\bm{a},\bm{b}>=x_1y_2-x_2y_1 \]

注意叉积不满足交换律\(\bm{a} \times \bm{b} = - (\bm{b} \times \bm{a})\)

二维向量叉积的结果是一个实数,其几何意义是\(\bm{a} ,\bm{b}\)围成的平行四边形的面积(有符号)。符号的判定可用右手定则:若 P × Q > 0, 则P在Q的顺时针方向(拇指向上)。 若 P × Q < 0, 则P在Q的逆时针方向。

double cross(vec p,vec q){return p.x*q.y-p.y*q.x;}

直线

直线方程

在高中我们学习了五种直线方程的表示方法,现在介绍计算几何中常用的方法:

\(Q=P+ t \bm{v}\)

其中\(P\)为直线上一点,\(\bm{v}\)为直线的方向向量,\(Q\)为直线上任意一点,\(t\)为参数。 给出\(P,\bm{v}\),则直线唯一确定

其实直线的参数方程\(\begin{cases} x=x_0+t\cos \theta \\ y=y_0+t\sin \theta \end{cases}\)就是这种表示法的特殊情况

struct line{
	point P;vec v;//P+tv
	line(){}
	line(point _P,vec _v){P=_P;v=_v;}
};

直线的交点

如何用点向式方程求直线的交点?

设两直线分别为 \((P,\bm{v}),(Q,\bm{m})\) ,交点\(A = P + t \bm{v}\).

又因为\(A\) 在另一条直线上, 故\(\vec{QA}\times \bm{m}=0\)

\((P + t \bm{v} - Q) \times \bm{m}=0\)

叉积关于向量加法运算具有分配律,展开后得

\(t (\bm{v} \times \bm{m}) = (Q-P)\times \bm{m}\)

解的\(t = \frac{(Q-P)\times \bm{m}}{\bm{v} \times \bm{m}}\)

故 $$A=P+\frac{(Q-P)\times \bm{m}}{\bm{v} \times \bm{m}}\bm{v}$$

point getInterSec(line l,line m){
	return l.P+l.v*(cross(m.P-l.P,m.v)/cross(l.v,m.v)); //((P-Q)+tv)m=0,解出t,交点为P+tv 
}

多边形

凸包

用Graham算法(本质是单调栈)

void convexHull(point *a,int n){
	static point s[MAXN+5];
    for(int i=1;i<=n;i++) if(a[i].x<a[1].x||(a[i].x==a[1].x&&a[i].y<a[1].y)) swap(a[i],a[1]);
    sort(a+2,a+1+n,[=](point p,point q)->bool{//极角排序 
        double ang=cross(p-a[1],q-a[1]);
        if(fabs(ang)<eps) return dist2(p,a[1])<dist2(q,a[1]);
        else return ang>eps;
    });
	int top=0;
    for(int i=1;i<=n;i++){//单调栈 
   		while(top>1&&cross(s[top]-s[top-1],a[i]-s[top-1])<=eps) top--;
   		s[++top]=a[i]; 
    }
}

标签:return,point,double,bm,全家,times,vec,几何,平面
来源: https://www.cnblogs.com/birchtree/p/16553802.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有