# 計算幾何 ## Template ### point ``` c++= typedef double Double; struct Point { Double x,y; bool operator < (const Point &b)const{ // 比較 //return tie(x,y) < tie(b.x,b.y); //return atan2(y,x) < atan2(b.y,b.x); } Point operator + (const Point &b)const{ // 向量加法 return {x+b.x,y+b.y}; } Point operator - (const Point &b)const{ // 向量減法 return {x-b.x,y-b.y}; } Point operator * (const Double &d)const{ // 向量伸縮 return {d*x, d*y}; } Double operator * (const Point &b)const{ // 向量內積 return x*b.x + y*b.y; } Double operator % (const Point &b)const{ // 向量外積 return x*b.y - y*b.x; } Double abs(){ return sqrt(x*x + y*y); } Double abs2(){ return (x*x + y*y); } }; ``` --- ## 問題 ### 1. 點到直線距離 $\frac{|\vec u \times \vec v|}{|\vec v|}$ ```c++= double dist_point_to_line(point &u, point &v){ return abs((u%v)/abs(v)); } ``` ### 2. 兩直線交點 ![link text](https://i.imgur.com/KbQuPeE.png) $I=p+t\vec V$ $t=-\frac{|\vec W\times \vec {PQ}|}{|\vec V \times \vec W|}$ ```c++= Point GetLineIntersection(Point P,Vector v,Point Q,Vector w){ Point u = P-Q; double t = Cross(w,u) / Cross(v,w); return P + v*t; } ``` ### 3. 凸包 ```c++= vector<Point> convexhull(vector<Point> &p){ // 輸入點,回傳凸包 sort(p.begin(), p.end()); int n = p.size(); int m = 0; vector<Point> res; for(int i = 0; i < n; i++){ while(m >= 2 && (p[i]-res[m-2]) % (res[m-1]-res[m-2]) < 0){ res.pop_back(); m--; } res.push_back(p[i]); m++; } for(int i = n-2; i >= 0; i--){ while(m >= 2 && (p[i]-res[m-2]) % (res[m-1]-res[m-2]) < 0){ res.pop_back(); m--; } res.push_back(p[i]); m++; } return res; } ``` ### 4. 簡單多邊形面積 ```c++= double _2d_area(vector<Point> &poly){ // 輸入簡單多邊形(起點和終點須重複, 已排序好) 回傳間單多邊形的面積 int n = poly.size(); double res = 0.0; for(int i = 0; i < n-1; i++){ res += (poly[i] % poly[i+1]); } return abs(res/2); } ```