網上找了乙個三維計算幾何模版,完善了一下,使它能使用了...
#include #include #include using namespace std;
/***********基礎*************/
const double eps=0.000001;
typedef struct point_3d
bool operator == (const point_3d& a) const
}vector_3d;
point_3d read_point_3d()
vector_3d operator + (const vector_3d & a, const vector_3d & b)
vector_3d operator - (const point_3d & a, const point_3d & b)
vector_3d operator * (const vector_3d & a, double p)
vector_3d operator / (const vector_3d & a, double p)
double dot(const vector_3d & a, const vector_3d & b)
double length(const vector_3d & a)
double angle(const vector_3d & a, const vector_3d & b)
vector_3d cross(const vector_3d & a, const vector_3d & b)
double area2(const point_3d & a, const point_3d & b, const point_3d & c)
double volume6(const point_3d & a, const point_3d & b, const point_3d & c, const point_3d & d)
// 四面體的重心
point_3d centroid(const point_3d & a, const point_3d & b, const point_3d & c, const point_3d & d)
/************點線面*************/
// 點p到平面p0-n的距離。n必須為單位向量
double distancetoplane(const point_3d & p, const point_3d & p0, const vector_3d & n)
// 點p在平面p0-n上的投影。n必須為單位向量
point_3d getplaneprojection(const point_3d & p, const point_3d & p0, const vector_3d & n)
//直線p1-p2 與平面p0-n的交點
point_3d lineplaneintersection(point_3d p1, point_3d p2, point_3d p0, vector_3d n)
// 點p到直線ab的距離
double distancetoline(const point_3d & p, const point_3d & a, const point_3d & b)
//點到線段的距離
double distancetoseg(point_3d p, point_3d a, point_3d b)
vector_3d v1 = b - a, v2 = p - a, v3 = p - b;
if(dot(v1, v2) + eps < 0)
else
else
}}//求異面直線 p1+s*u與p2+t*v的公垂線對應的s 如果平行|重合,返回false
bool linedistance3d(point_3d p1, vector_3d u, point_3d p2, vector_3d v, double & s)
double a = dot(u, v) * dot(v, p1 - p2) - dot(v, v) * dot(u, p1 - p2);
s = a / b;
return true;
}bool sameside(const point_3d & p1, const point_3d & p2, const point_3d & a, const point_3d & b)
// 點p在三角形p0, p1, p2中
bool pointintri(const point_3d & p, const point_3d & p0, const point_3d & p1, const point_3d & p2)
// 三角形p0p1p2是否和線段ab相交
bool trisegintersection(const point_3d & p0, const point_3d & p1, const point_3d & p2, const point_3d & a, const point_3d & b, point_3d & p)
else // 平面a和直線p1-p2有惟一交點
p = a + (b - a) * t; // 交點
return pointintri(p, p0, p1, p2);
}}//空間兩三角形是否相交
bool tritriintersection(point_3d * t1, point_3d * t2)
if(trisegintersection(t2[0], t2[1], t2[2], t1[i], t1[(i + 1) % 3], p))
}return false;
}//空間兩直線上最近點對 返回最近距離 點對儲存在ans1 ans2中
double segsegdistance(point_3d a1, point_3d b1, point_3d a2, point_3d b2, point_3d& ans1, point_3d& ans2)
// 判斷p是否在三角形a, b, c中,並且到三條邊的距離都至少為mindist。保證p, a, b, c共面
bool insidewithmindistance(const point_3d & p, const point_3d & a, const point_3d & b, const point_3d & c, double mindist)
if(distancetoline(p, a, b) < mindist)
if(distancetoline(p, b, c) < mindist)
if(distancetoline(p, c, a) < mindist)
return true;
}// 判斷p是否在凸四邊形abcd(順時針或逆時針)中,並且到四條邊的距離都至少為mindist。保證p, a, b, c, d共面
bool insidewithmindistance(const point_3d & p, const point_3d & a, const point_3d & b, const point_3d & c, const point_3d & d, double mindist)
if(!pointintri(p, c, d, a))
if(distancetoline(p, a, b) < mindist)
if(distancetoline(p, b, c) < mindist)
if(distancetoline(p, c, d) < mindist)
if(distancetoline(p, d, a) < mindist)
return true;
}/*************凸包相關問題*******************/
//加干擾
double rand01()
double randeps()
point_3d add_noise(const point_3d & p)
struct face
vector_3d normal(const vector& p) const
// f是否能看見p[i]
int cansee(const vector& p, int i) const
};// 增量法求三維凸包
// 注意:沒有考慮各種特殊情況(如四點共面)。實踐中,請在呼叫前對輸入點進行微小擾動
vectorch3d(const vector& p)
vectorcur;
cur.push_back(face(0, 1, 2)); // 由於已經進行擾動,前三個點不共線
cur.push_back(face(2, 1, 0));
for(int i = 3; i < n; i++)
for(int k = 0; k < 3; k++)
}for(int j = 0; j < cur.size(); j++)
for(int k = 0; k < 3; k++)
}cur = next;
}return cur;
}struct convexpolyhedron
p.resize(n);
p2.resize(n);
for(int i = 0; i < n; i++)
faces = ch3d(p2);
return true;
}//三維凸包重心
point_3d centroid()
return tot / totv;
}//凸包重心到表面最近距離
double mindist(point_3d c)
return ans;
}};int main()
ACM計算幾何 三維幾何模板
三維幾何函式庫 include define eps 1e 8 define zero x x 0?x x eps vlen xmult subt p,s.b subt p,s.c eps vlen xmult subt p,s.c subt p,s.a eps int dot inplane ex...
三維幾何 基礎
數學上,三維幾何是3維歐式空間幾何的傳統名稱。因為實際上這大致就是我們生活的空間。我們在前面介紹過向量運算,其中很多內容也適合三維幾何,如點 向量 點,向量 向量 向量,點 點沒有定義。首先是輔助巨集的定義 const double eps 1e 10 const double pi acos 1 ...
三維幾何 平面
平面的表示。通常用點法式 p0,n 來描述乙個平面。其中點p0是平面的乙個點,向量n是平面的法向量。每個平面把空間分成了兩個部分,我們可以用點法式表示其中乙個半空間。具體是哪乙個呢?是這個法向量所背離的那乙個 即法向量指向遠離半空間的方向 既然是法向量,n就垂直於平面上的所有直線。換句話說,平面上的...