初學計算幾何(一)——點與向量·叉積與點積


前言

計算幾何應該是一個比較復雜的東西吧,它的應用十分廣泛。為此,我花了很長的時間來學習計算幾何。

點與向量

應該還算比較簡單吧!對於平面上的一個坐標為\((x,y)\)的點,我們可以用\(P(x,y)\)來表示它。

  • 向量

向量表示的是一個有大小和方向的量,在平面坐標系下它與點一樣也用兩個數來表示。這兩個數的實際含義是將這個向量的起點移至原點后終點的坐標。通常,我們用\(\vec v\)來表示一個向量,用\(|\vec v|\)來表示向量\(\vec v\)的長度。

  • 點與向量的基本定義與運算

雖然點與向量十分相像,但是它們在概念上還是有許多不同的。

下面是它們的基本定義與運算。

struct Point//一個結構體用來存儲一個點
{
	double x,y;//分別存儲點的兩個坐標
	Point(double nx=0,double ny=0):x(nx),y(ny){}//構造函數
};
typedef Point Vector;//向量在代碼中其實與點差不多,因此可以直接typedef一下
inline Vector operator + (Vector A,Vector B) {return Vector(A.x+B.x,A.y+B.y);}//向量+向量=向量
inline Vector operator - (Point  A,Point  B) {return Vector(A.x-B.x,A.y-B.y);}//點-點=向量
inline Vector operator * (Vector A,double x) {return Vector(A.x*x,A.y*x);}//向量*一個數=向量
inline Vector operator / (Vector A,double x) {return Vector(A.x/x,A.y/x);}//向量/一個數=向量

點積

下面,先來介紹一下向量的點積

  • 點積的計算公式及其擴展

\[\vec v(X_1,Y_1)·\vec u(X_2,Y_2)=X_1X_2+Y_1Y_2 \]

對於兩個向量\(\vec v\)\(\vec u\),如果它們的夾角為\(\theta\),則它們的點積就等同於\(|\vec v||\vec u|cos \theta\)

既然這樣,我們就可以推導出以下公式:

向量的長度\(\sqrt {\vec v·\vec v}\)(因為對於兩個相同的向量,\(cos\theta=0\),因此\(\vec v·\vec v=|\vec v||\vec v|=|\vec v|^2\)

向量的夾角\(acos(\vec v·\vec u/|\vec v|/|\vec u|)\)(因為\(\vec v·\vec u/|\vec v|/|\vec u|=cos\theta\),所以\(\theta=acos(\vec v·\vec u/|\vec v|/|\vec u|)\)

以下是代碼實現:

inline double Dot(Vector A,Vector B) {return A.x*B.x+A.y*B.y;}//點積
inline double Len(Vector A) {return sqrt(Dot(A,A));}//向量的長度等於sqrt(x^2+y^2)
inline double Ang(Vector A,Vector B) {return acos(Dot(A,B)/Len(A)/Len(B));}//向量的夾角等於acos(A·B/|A|/|B|)
  • 點積的正負

該如何判斷兩個向量的點積的正負呢?

點積的正負是由兩個向量的夾角\(\theta\)所決定的。

\[\begin{cases}當\theta<90^。時,點積為正\\當\theta>90^。時,點積為負\\當\theta=90^。,即兩個向量垂直時,點積等於0\end{cases} \]

  • 其他

點積還有一個很重要的性質,就是點積滿足交換律

叉積

叉積點積是十分類似的。

  • 叉積的計算公式及其擴展

\[\vec v(X_1,Y_1)×\vec u(X_2,Y_2)=X_1Y_2-Y_1X_2 \]

叉積有一個十分神奇的性質,就是\(\vec v×\vec u\)恰好等於這兩個向量組成的三角形的有向面積\(2\)倍。

這樣,我們就能輕松求出兩個向量組成的三角形的面積了:

兩個向量組成的三角形的面積\(\frac {\vec v×\vec u} 2\)

以下是代碼實現:

inline double Cro(Vector A,Vector B) {return A.x*B.y-A.y*B.x;}//叉積
inline double Area(Vector A,Vector B) {return Cro(A,B)/2;}//求兩個向量組成三角形的有向面積
  • 叉積的正負

叉積的正負是由兩個向量的位置關系決定的。

\[\begin{cases}當\vec u在\vec v左邊時,\vec v×\vec u為正\\當\vec u在\vec v右邊時,\vec v×\vec u為負\\如果\vec u與\vec v方向相同,則\vec v×\vec u為0\end{cases} \]

  • 其他

叉積是不滿足交換律的,\(\vec v×\vec u=-\vec u×\vec v\)

后記:其他常見運算

點與向量還有一些比較基本的運算,下面就直接貼代碼了。

  • 旋轉
inline Vector Rotate(Vector A,double rad) {return Vector(A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+A.y*cos(rad));}//將向量A旋轉rad度
  • 求法線
inline Vector Normal(Vector A) {double len=Len(A);return Vector(-A.y/len,A.x/len);}//求向量A的單位法線


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM