Created
September 14, 2012 03:45
-
-
Save zeptometer/3719669 to your computer and use it in GitHub Desktop.
幾何ライブラリ
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <complex> | |
| using namespace std; | |
| typedef complex<double> P; | |
| // 許容する誤差ε | |
| #define EPS (1e-10) | |
| // 2つのスカラーが等しいかどうか | |
| #define EQ(a,b) (abs((a)-(b)) < EPS) | |
| // 2つのベクトルが等しいかどうか | |
| #define EQV(a,b) ( EQ((a).real(), (b).real()) && EQ((a).imag(), (b).imag()) ) | |
| // ベクトルaの絶対値を求める | |
| double length = abs(a); | |
| // 2点a,b間の距離を求める | |
| double distance = abs(a-b); | |
| // ベクトルaの単位ベクトルを求める | |
| P b = a / abs(a); | |
| // ベクトルaの法線ベクトルn1,n2を求める | |
| P n1 = a * P(0, 1); | |
| P n2 = a * P(0, -1); | |
| // ベクトルaの単位法線ベクトルun1,un2を求める | |
| P un1 = (a * P(0, +1)) / abs(a); | |
| P un2 = (a * P(0, -1)) / abs(a); | |
| // 内積 (dot product) : a・b = |a||b|cosΘ | |
| double dot(P a, P b) { | |
| return (a.real() * b.real() + a.imag() * b.imag()); | |
| } | |
| // 外積 (cross product) : a×b = |a||b|sinΘ | |
| double cross(P a, P b) { | |
| return (a.real() * b.imag() - a.imag() * b.real()); | |
| } | |
| // 2直線の直交判定 : a⊥b <=> dot(a, b) = 0 | |
| int is_orthogonal(P a1, P a2, P b1, P b2) { | |
| return EQ( dot(a1-a2, b1-b2), 0.0 ); | |
| } | |
| // 2直線の平行判定 : a//b <=> cross(a, b) = 0 | |
| int is_parallel(P a1, P a2, P b1, P b2) { | |
| return EQ( cross(a1-a2, b1-b2), 0.0 ); | |
| } | |
| // 点cが直線a,b上にあるかないか | |
| int is_point_on_line(P a, P b, P c) { | |
| return EQ( cross(b-a, c-a), 0.0 ); | |
| } | |
| // 点cが線分a,b上にあるかないか(1) | |
| int is_point_on_line(P a, P b, P c) { | |
| return EQ( cross(b-a, c-a), 0.0 ) && | |
| (dot(b-a, c-a) > -EPS) && | |
| (dot(a-b, c-b) > -EPS); | |
| } | |
| // 点cが線分a,b上にあるかないか(2) | |
| int is_point_on_line(P a, P b, P c) { | |
| // |a-c| + |c-b| <= |a-b| なら線分上 | |
| return (abs(a-c) + abs(c-b) < abs(a-b) + EPS); | |
| } | |
| // 点a,bを通る直線と点cとの距離 | |
| double distance_l_p(P a, P b, P c) { | |
| return abs(cross(b-a, c-a)) / abs(b-a); | |
| } | |
| // 点a,bを端点とする線分と点cとの距離 | |
| double distance_ls_p(P a, P b, P c) { | |
| if ( dot(b-a, c-a) < EPS ) return abs(c-a); | |
| if ( dot(a-b, c-b) < EPS ) return abs(c-b); | |
| return abs(cross(b-a, c-a)) / abs(b-a); | |
| } | |
| // a1,a2を端点とする線分とb1,b2を端点とする線分の交差判定 | |
| int is_intersected_ls(P a1, P a2, P b1, P b2) { | |
| return ( cross(a2-a1, b1-a1) * cross(a2-a1, b2-a1) < EPS ) && | |
| ( cross(b2-b1, a1-b1) * cross(b2-b1, a2-b1) < EPS ); | |
| } | |
| // a1,a2を端点とする線分とb1,b2を端点とする線分の交点計算 | |
| P intersection_ls(P a1, P a2, P b1, P b2) { | |
| P b = b2-b1; | |
| double d1 = abs(cross(b, a1-b1)); | |
| double d2 = abs(cross(b, a2-b1)); | |
| double t = d1 / (d1 + d2); | |
| return a1 + (a2-a1) * t; | |
| } | |
| // a1,a2を通る直線とb1,b2を通る直線の交差判定 | |
| int is_intersected_l(P a1, P a2, P b1, P b2) { | |
| return !EQ( cross(a1-a2, b1-b2), 0.0 ); | |
| } | |
| // a1,a2を通る直線とb1,b2を通る直線の交点計算 | |
| P intersection_l(P a1, P a2, P b1, P b2) { | |
| P a = a2 - a1; P b = b2 - b1; | |
| return a1 + a * cross(b, b1-a1) / cross(b, a); | |
| } | |
| //円の交点 | |
| pair<P> intersection_circle(P p1,P p2,double r1,double r2){ | |
| double d = abs(p2-p1); | |
| double th = acos((d*d+r1*r1-r2*r2)/(2*d*r1)); | |
| returtn make_pair(p1 + polar( r1, arg(p2-p1)+th ), polar( r1, arg(p2-p1)-th ) ); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment