计算几何基础

zxy巨巨
神仙
ak了winter camp回来给我们讲知识点

开始吧
计算及处理几何问题尽量减小误差
涉及到double,计算少用除法、开根(牛顿迭代法三次除法)

精度:

在这里插入图片描述
妙啊
向量表示线段(有向线段)
还可以用美丽的文玉的方法
对 于 ∀ C ∈ A B , ∃ p ∈ [ 0 , 1 ] , C = p A + ( 1 − p ) B 对于\forall C\in AB,\exists p\in [0,1],C=pA+(1-p)B CAB,p[0,1],C=pA+(1p)B

一个方法

直线方程 A x + B y + C = 0 Ax+By+C=0 Ax+By+C=0可以用

向量

struct vec{
	double x,y;
};
vec operator+(const vec a,const vec b){
	return (vec){a.x+b.x,a.y+b.y};
}
vec a,b,c;
	a.x=in,a.y=in,b.x=in,b.y=in;
	c=a+b;
	printf("%lf %lf",c.x,c.y);
	return 0;

重载运算符是个好东西
但是你要用就用你重载的东西啊!(定义了+不要有-)
重载后不影响原来对于其他数据类型的用法
函数也可以解决这个问题

点积

详见数学书,必修四欢迎您

叉乘

叉乘结果的大小是两向量构成的平行四边形的有向面积,用行列式算(详见线形代数)(证明显然)
方向利用右手定则判断(你发现你比good的时候就是正的,比bad的时候就是负的)
向量的叉乘有有序性,不满足交换律
a ⃗ × b ⃗ = − b ⃗ × a ⃗ \vec a\times \vec b=-\vec b\times \vec a a ×b =b ×a

(期末考前玩着玩着搞出来了向量叉乘坐标运算的一个严格的证明,我是不是有点不务正业T_T)
向量叉乘坐标运算:
仿照数学书上点乘的坐标运算,我们需要知道向量的叉乘是否遵循分配率
( a ⃗ + b ⃗ ) × c ⃗ = ? = a ⃗ × c ⃗ + b ⃗ × c ⃗ (\vec{a}+\vec{b})\times\vec{c}=?=\vec{a}\times\vec{c}+\vec{b}\times \vec{c} (a +b )×c =?=a ×c +b ×c
做出几何图形如下,易证
在这里插入图片描述
( a ⃗ + b ⃗ ) × c ⃗ = S A C C ′ D (\vec{a}+\vec{b})\times\vec{c}=S_{ACC'D} (a +b )×c =SACCD
a ⃗ × c ⃗ = S A B B ′ D \vec{a}\times\vec{c}=S_{ABB'D} a ×c =SABBD
b ⃗ × c ⃗ = S B C C ′ B ′ \vec{b}\times\vec{c}=S_{BCC'B'} b ×c =SBCCB
由初中几何知识易知: ( a ⃗ + b ⃗ ) × c ⃗ = a ⃗ × c ⃗ + b ⃗ × c ⃗ (\vec{a}+\vec{b})\times\vec{c}=\vec{a}\times\vec{c}+\vec{b}\times \vec{c} (a +b )×c =a ×c +b ×c

接着,我们就可以放心大胆地使用分配率了(下面有点不严谨: i 和 j i和j ij上面应该打向量的箭头,但是咕了)
a ⃗ = ( x 1 , y 1 ) = x 1 i + y 1 j ,   b ⃗ = ( x 2 , y 2 ) = x 2 i + y 2 j \vec{a}=(x_1,y_1)=x_1i+y_1j,\ \vec{b}=(x_2,y_2)=x_2i+y_2j a =(x1,y1)=x1i+y1j, b =(x2,y2)=x2i+y2j
a ⃗ × b ⃗ = x 1 x 2 ( i × i ) + y 1 y 2 ( j × j ) + x 1 y 2 ( i × j ) + y 1 x 2 ( j × i ) \vec{a}\times\vec{b}=x_1x_2(i\times i)+y_1y_2(j\times j)+x_1y_2(i\times j)+y_1x_2(j\times i) a ×b =x1x2(i×i)+y1y2(j×j)+x1y2(i×j)+y1x2(j×i)
= x 1 y 2 − x 2 y 1 =x_1y_2-x_2y_1 =x1y2x2y1(ixi=0,jxj=0,ixj=1,jxi=-1)

妙不妙?

向量的旋转

a ⃗ = ( x , y ) = x i ⃗ + y j ⃗ \vec a=(x,y)=x\vec i+y\vec j a =(x,y)=xi +yj
旋转角 θ \theta θ
各位应该很明显的看到直接把 x i ⃗ x\vec i xi y j ⃗ y\vec j yj 转了不就行了?

叉乘

我是不是又打了一个一样的标题?
那是因为我懒得想这个标题究竟应该写什么

· 点乘和叉乘用

void dottimes(vec a,vec b,int &c){
	c=a.x*b.x+a.y*b.y;
}
void crosstimes(vec a,vec b,int &c){
	c=a.x*b.y-b.x*a.y;
}

给一点叉乘的小结论
· 求有向面积:废话,用叉乘 S Δ O A B = O A ⃗ × O B ⃗ S_{\Delta OAB}=\vec {OA}\times \vec {OB} SΔOAB=OA ×OB

· 又看数学书:三点共线的时候是不是围成三角形的面积为0?是的,可以根据叉乘 x 1 y 2 − x 2 y 1 = 0 x_1y_2-x_2y_1=0 x1y2x2y1=0

· 还可以依据三角形的有向面积判断角的大小(优劣角)——
α \alpha α为以 a ⃗ \vec a a 为始边、以 b ⃗ \vec b b 为终边的角
可以发现:
a ⃗ × b ⃗ > 0 ⇒ α ∈ ( 0 , π ) \vec a\times \vec b\gt0\Rightarrow\alpha\in(0,\pi) a ×b >0α(0,π)
a ⃗ × b ⃗ < 0 ⇒ α ∈ ( π , 2 π ) \vec a\times \vec b\lt0\Rightarrow\alpha\in(\pi,2\pi) a ×b <0α(π,2π)
一会儿会用到它来做凸包

· 另:点乘的正负由 c o s < a ⃗ , b ⃗ > cos<\vec a,\vec b> cos<a ,b >提供,因此可以判断夹角为钝角或锐角

· 求距离:三角形面积与高,他不容易吗? d = S Δ P A B ∣ A B ⃗ ∣ = O A ⃗ × O B ⃗ 2 ∣ A B ⃗ ∣ d=\frac{S_{\Delta PAB}}{|\vec {AB}|}=\frac{\vec {OA}\times \vec {OB}}{2|\vec {AB}|} d=AB SΔPAB=2AB OA ×OB
提醒!叉乘算的是平行四边形的面积!

· 判断是否相交:
端点分布在两侧,利用面积,叉乘的结果同号(注意边的顺序)
还可以用来求交点——知道面积知道面积比知道边上比例

· 点与多边形的关系:在内或在外
做一条直线,记穿边的个数,奇内偶外
如果交了顶点,算远不算近(不要问我,对于顶点肯定不能说交了1个点对吧,那么交0个或者交2个对奇偶性是没有影响的,算不算无所谓)

· 求多边形面积就很妙了
在这里插入图片描述
叉乘自动给你改变正负
这就是向量的魅力,所以我第一眼看到向量的时候就爱上他了

· 还有一种判断点是否在多边形的方法
把多边形放在极坐标系里,以一个点作为原点,易知每条对角线的极角是单增的,知道点的极角,二分它所在的区域,再用叉乘判断点在不在里面就行了
在这里插入图片描述

【模板】二维凸包 / [USACO5.1]圈奶牛Fencing the Cows

求凸包:
step1 取极点,选左下角的那个
step2 排序,根据极角单增与距离单增(叉乘实现)
step3 挨个连,用栈维护,弹优角
现在栈里面就是凸包的边界了

码的时候遇到了一点问题:
运算符之类的符号是不能对结构体运行
在结构体里面要么重载运算符,要么return true(不改变顺序)| return false(改变顺序)

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值