二維坐標系中的點積、叉積、多邊形面積


二維坐標系中的點積、叉積、多邊形面積

點積定義

設有向量 \(\vec{a}\)\(\vec{b}\) ,定義點積 \(\vec{a}\cdot \vec{b}\)實數 ,其值為 向量 \(\vec{a}\) 在向量 \(\vec{b}\) 上投影的長度乘以向量 \(\vec{b}\) 的模

點積性質

滿足交換律,結合律

點積計算

直接計算

\[|\vec{a}\cdot \vec{b}| = |\vec{a}| \times |\vec{b}|\times cos<\vec{a},\ \vec{b}> \]

坐標系中計算

放在坐標系中,設 \(\vec{a} = (x_{1},\ y_{1}),\ \vec{b} = (x_{2},\ y_{2})\)

那么 \(\vec{a}\cdot \vec{b} = x_{1}x_{2} + y_{1}y_{2}\)

叉積定義

設有向量 \(\vec{a}\)\(\vec{b}\) ,定義叉積 \(\vec{a}\times \vec{b}\) 為新的 向量
其模長為 \(\vec{a}\)\(\vec{b}\) 所圍成的平行四邊形面積。
方向與 \(\vec{a}\)\(\vec{b}\) 均垂直。
\(\vec{b}\)\(\vec{a}\) 逆時針方向,即呈現左手系,那么 \(\vec{a}\times \vec{b}\) 為正;反之為負。

叉積性質

叉積模即為平行四邊形面積,所以在直角坐標系中求一個三角形的面積可以用叉積來計算,即

\[S_{OAB} = \frac{1}{2}|\vec{a} \times \vec{b}| \]

叉積不滿足交換律,因為方向會發生變化,即

\[\vec{a} \times \vec{b} = - \vec{b} \times \vec{a} \]

二維叉積模的計算

直接計算

\[|\vec{a}\times \vec{b}| = |\vec{a}| \times |\vec{b}|\times sin<\vec{a},\ \vec{b}> \]

坐標系中計算

放在坐標系中,設 \(\vec{a} = (x_{1},\ y_{1}),\ \vec{b} = (x_{2},\ y_{2})\)

經過推導得到 \(|\vec{a} \times \vec{b}| = |x_{1}y_{2} - x_{2}y_{1}|\)

去掉絕對值便得到 有向面積

若值為正,說明 \(\vec{b}\)\(\vec{a}\) 逆時針方向;若值為負,說明說明 \(\vec{b}\)\(\vec{a}\) 順時針方向。

多邊形面積計算

基本思想是把多邊形划分成多個三角形,然后叉積計算面積。這個思想對於凹凸多邊形都成立。

記多邊形頂點逆時針排列為 \(P_{0},\ P_{1},\ ..,\ P_{n - 1}\)

為了方便計算,選取坐標原點 \(O(0,\ 0)\) 作為源點,逐一計算 \(\vec{OP_{i}}\times \vec{OP_{i + 1}}\) ,累計求和即可。

公式為

\[\sum_{i = 0}^{n - 1}(x_{i}y_{i + 1} - x_{i + 1}y_{i}) \]

\(i = n - 1\) 時,下一個坐標要回到 \((x_{0}, y_{0})\) ,這里可以特判,也可以取模運算。

復雜度 \(O_{n}\)

由於叉積面積的有向性,多余的面積會被抵消掉,所以這個算法是正確的,此處省略嚴格證明。

\(code\)

int n;
struct Cor
{
    int x, y;
}cor[105];

inline int read()
{
    char c = getchar();
    int ans = 0, f = 1;
    while(!isdigit(c)) {if(c == '-') f = -1; c = getchar();}
    while(isdigit(c)) {ans = ans * 10 + c - '0'; c = getchar();}
    return ans * f;
}

int main()
{
    while(scanf("%d", &n) && n) {
        for(int i = 0; i < n; ++i)
            cor[i].x = read(), cor[i].y = read();
        double ans = 0.0;
        for(int i = 0; i < n; ++i){
            ans += 0.5 * (cor[i % n].x * cor[(i + 1) % n].y - cor[i % n].y * cor[(i + 1) % n].x);
        }
        printf("%.1f\n", ans);
    }
    return 0;
}


免責聲明!

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



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