円と直線の交点
目次
# 解説
円の中心座標を、半径を、直線が通る2点を左から, とおく.
円と直線の交点を、とおく.
交点を求めるには以下3つの情報があれば良い.
- 円Cから直線への垂線と直線との交点.
- 直線上の単位ベクトル.
- 線分の長さ.
1〜3の情報から、交点からのプラスマイナスの方向へ長さだけ進んだ点2つが解となる.
# 1. 交点を求める
射影の公式を使って求める.
Vector2 project(Vector2 p1, Vector2 p2, Vector2 c) {
Vector2 v = p2 - p1;
return p1 + v * (v.dot(c - p1) / v.norm());
}
# 2. 単位ベクトルを求める
単位ベクトルはベクトルをその長さで割ると求められる.
Vector2 unitVec(Vector2 v) {
return v / v.length();
}
# 3. 線分の長さを求める
から直線へ垂線を引きとの交点をとおく.
この時、点は線分を2等分する点である.
また、は直角三角形である.
線分との長さは三平方の定理より、
# 4. 交点を求める
# コード全体
double R;
Vector2 C, p1, p2;
Vector2 project(Vector2 p1, Vector2 p2, Vector2 c) {
Vector2 v = p2 - p1;
return p1 + v * (v.dot(c - p1) / v.norm());
}
Vector2 unitVec(Vector2 v) {
return v / v.length();
}
pair<Vector2, Vector2> crossPoints() {
Vector2 p = project(p1, p2, C);
Vector2 e = unitVec(p2 - p1);
double len = sqrt(R*R - (p - C).norm());
Vector2 a = p + e * (-len);
Vector2 b = p + e * len;
if (fabs(a.x) < EPS) a.x = 0.0;
if (fabs(a.y) < EPS) a.y = 0.0;
if (fabs(b.x) < EPS) b.x = 0.0;
if (fabs(b.y) < EPS) b.y = 0.0;
if (a < b) return make_pair(a, b);
return make_pair(b, a);
}