---
# System prepended metadata

title: 計算幾何

---

# 計算幾何
## 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);
}
```