[小丁笔记] 计算几何
数学基础
二维叉乘
- $ \vec{a} \times \vec{b} = (a_xb_y-a_yb_x)\vec{k} $
三维叉乘
- $ \vec{a} \times \vec{b} = (a_yb_z-a_zb_y)\vec{i}+(a_zb_x-a_xb_z)\vec{j}+(a_xb_y-a_yb_x)\vec{k}$
极角排序
-
本质上是对二维向量进行排序
-
用极坐标 \((\theta,r)\) 的 \(\theta\) 精度不够
-
直接在排序中判断向量的顺序,可以避免精度误差
-
叉乘可以判断向量的左右关系,但是超过180度后很难直接定义排列顺序
因此可以采用先用象限粗判再用叉乘判断的方式解决问题 -
例题:cf598c
-
代码片段
int quad(){ //求象限 if(y>=0) return ((x>=0)?1:2); else return ((x>=0)?4:3); } inline bool cmp(point a,point b){ int qa=a.quad(),qb=b.quad(); if(qa==qb) return mul(a,b)>0; // mul代表叉乘 else return qa<qb; }
求向量夹角
-
代码片段
#include<cmath> double rad(Vec a,Vec b){ return fabs(atan2( mul(a,b) , dot(a,b) )); // mul代表叉乘,dot代表点乘 }
-
\((atan2(y,x)=arc tan\frac{y}{x}) \)
-
\(\frac{\vec{a}\times\vec{b}} {\vec{a}\cdot\vec{b}}=\frac{\lvert\vec{a}\rvert\lvert\vec{b}\rvert sin\theta}{\lvert\vec{a}\rvert\lvert\vec{b}\rvert cos\theta}=tan\theta\)