質問: 2 次元の平面座標系では、任意の多角形について、各頂点の座標がわかり、多角形の面積が計算されます。
「座標」や「面積」という言葉を見て真っ先に思いついたのは、前回書いたブログの内容であるベクトルの外積です。次に、ベクトルの外積から始めて、面積を計算する問題に答えられるかどうかを確認します。
ベクトル外積の定義:
2 つのベクトルの場合
次に=
計算と導出を容易にするために、次のように外積の定義式をさらに進化させます。
=
=
=
二次元平面への次元削減
= =で、それぞれ x 軸、y 軸、z 軸の単位ベクトルを表します。
3 番目の列では、最初の行を除いて、他のすべての行が 0 であるため、行列式の 3 番目の列に従って展開し、取得します。
= = = 、代数補因子を表します。
したがって、2 次元平面で 2 つのベクトルの外積を計算する場合、2 つのベクトルの座標の順序付けられた配列の行列式を計算することで評価できます。前回のブログで、2 つのベクトルの外積の絶対値が、原点と3 点で囲まれた三角形の面積の 2 倍に等しいことを検証しました。
この基礎が整ったら、質問に戻りましょう。
この問題は多角形を表しています. 下の図に示すように、最も単純な多角形である三角形から始めましょう:
上図の三角形の面積は
ベクトル外積を使用して、上記の式の各三角形の面積を取得します。
=
注: ベクトルをクロス乗算すると、結果は正または負になり、正と負は方向を表し、右手の法則を満たします。
三角形を計算したら、四角形に進みます。
四角形には、いわゆる凸面と凹面があるため、もう少し複雑になります. 2 つのシナリオが同じ計算のアイデア、つまりバンプの感覚を持たないかどうかを見てみましょう. まず、2 つのグラフィックスを別々に計算します。
凸边形:
=
=
凹边形:
=
=
上下の結果の式が統一されていること、つまり、四角形の凸面と凹面が一致していることがわかります.面積計算にベクトル外積を使用すると、計算式が一致し、凹凸感がなくなります. .
これで、三角形から四角形への問題解決方法が検証されました。
各頂点と多角形の原点からなるベクトルを反時計回り (または時計回りも使用できます) の順序で構成し、前後の 2 つのベクトルを交差乗算して外積を求め、テールとヘッドのベクトルを求めます。もクロス乗算されます (つまり、グラフの各エッジで接続された 2 つのエンドポイントは、 head-to-tail でクロス乗算する必要があります)。次に、加算によって得られた合計の半分の絶対値すべての外積は多角形の面積です。たった今
=
この計算方法はすべてのポリゴンに適用できますか? 数学的帰納法で証明してみましょう。
辺がn個あるとき=が成り立つと仮定すると、このときこれを基準に点を足すとn+1辺となる
上の図に示すように、2 つのエッジ (図の黄色の部分) を追加し、このエッジ (図の赤い点線)を削除する必要があります。
= +
= +
(注: これは、2 つの辺を追加して 1 つの辺を削除することに相当します)
=
最終結果は、上で要約した計算規則を満たしています。ここまでで、ポリゴン領域の解が理論的に得られました。
そして次は、この計算方法をコンピュータに移植して計算を任せる必要があるので、計算式をコンピュータが計算しやすい形に進化させていく必要があります。
=
=
=
=
その中で、当時、すなわち
最後に、有名な靴紐の定理 靴紐の定理である上記の式を取得しました。
その特徴は何ですか?次のように、インターネットから写真を借りましょう。
この式が靴ひものように作用することから、靴ひもの定理と呼ばれます。
靴紐の定理を使えば、簡単にコードに移植できます。
struct Point2d
{
double x;
double y;
Point2d(double xx, double yy): x(xx), y(yy){}
};
//计算任意多边形的面积,顶点按照顺时针或者逆时针方向排列
double ComputePolygonArea(const vector<Point2d> &points)
{
int point_num = points.size();
if(point_num < 3)return 0.0;
double s = 0;
for(int i = 0; i < point_num; ++i)
s += points[i].x * points[(i+1)%point_num].y - points[i].y * points[(i+1)%point_num].x;
return fabs(s/2.0);
}