多角形の重心を計算する PHP 関数を作成しようとしています。
他の同様の質問を見てきましたが、これに対する解決策が見つからないようです。
私の問題は、正多角形と不規則多角形の両方、さらには自己交差多角形の重心を計算できる必要があることです。
それは可能ですか?
私もそれを読みました: http://paulbourke.net/geometry/polyarea/ しかし、これは非自己交差ポリゴンに制限されています。
これどうやってするの?正しい方向に私を向けることができますか?
多角形の重心を計算する PHP 関数を作成しようとしています。
他の同様の質問を見てきましたが、これに対する解決策が見つからないようです。
私の問題は、正多角形と不規則多角形の両方、さらには自己交差多角形の重心を計算できる必要があることです。
それは可能ですか?
私もそれを読みました: http://paulbourke.net/geometry/polyarea/ しかし、これは非自己交差ポリゴンに制限されています。
これどうやってするの?正しい方向に私を向けることができますか?
重心 (「重心」または「重心」とも呼ばれる) は、次の式で計算できます。
X = SUM[(Xi + Xi+1) * (Xi * Yi+1 - Xi+1 * Yi)] / 6 / A
Y = SUM[(Yi + Yi+1) * (Xi * Yi+1 - Xi+1 * Yi)] / 6 / A
ウィキペディアから抽出: n 個の頂点 (x0,y0), (x1,y1), ..., (xn−1,yn−1) で定義される非自己交差閉多角形の重心は点 (Cx, Cy)、ここ


で、A は多角形の符号付き面積です。

VBasic を使用した例:
' Find the polygon's centroid.
Public Sub FindCentroid(ByRef X As Single, ByRef Y As _
Single)
Dim pt As Integer
Dim second_factor As Single
Dim polygon_area As Single
' Add the first point at the end of the array.
ReDim Preserve m_Points(1 To m_NumPoints + 1)
m_Points(m_NumPoints + 1) = m_Points(1)
' Find the centroid.
X = 0
Y = 0
For pt = 1 To m_NumPoints
second_factor = _
m_Points(pt).X * m_Points(pt + 1).Y - _
m_Points(pt + 1).X * m_Points(pt).Y
X = X + (m_Points(pt).X + m_Points(pt + 1).X) * _
second_factor
Y = Y + (m_Points(pt).Y + m_Points(pt + 1).Y) * _
second_factor
Next pt
' Divide by 6 times the polygon's area.
polygon_area = PolygonArea
X = X / 6 / polygon_area
Y = Y / 6 / polygon_area
' If the values are negative, the polygon is
' oriented counterclockwise. Reverse the signs.
If X < 0 Then
X = -X
Y = -Y
End If
End Sub
詳細については、このWeb サイトまたはウィキペディアを確認してください。
それが役に立てば幸い。
よろしく!
コールド c++ で、x および y プロパティを持つ Vec2 構造体があると仮定します。
const Vec2 findCentroid(Vec2* pts, size_t nPts){
Vec2 off = pts[0];
float twicearea = 0;
float x = 0;
float y = 0;
Vec2 p1, p2;
float f;
for (int i = 0, j = nPts - 1; i < nPts; j = i++) {
p1 = pts[i];
p2 = pts[j];
f = (p1.x - off.x) * (p2.y - off.y) - (p2.x - off.x) * (p1.y - off.y);
twicearea += f;
x += (p1.x + p2.x - 2 * off.x) * f;
y += (p1.y + p2.y - 2 * off.y) * f;
}
f = twicearea * 3;
return Vec2(x / f + off.x, y / f + off.y);
}
そしてJavaScriptで:
function findCentroid(pts, nPts) {
var off = pts[0];
var twicearea = 0;
var x = 0;
var y = 0;
var p1,p2;
var f;
for (var i = 0, j = nPts - 1; i < nPts; j = i++) {
p1 = pts[i];
p2 = pts[j];
f = (p1.lat - off.lat) * (p2.lng - off.lng) - (p2.lat - off.lat) * (p1.lng - off.lng);
twicearea += f;
x += (p1.lat + p2.lat - 2 * off.lat) * f;
y += (p1.lng + p2.lng - 2 * off.lng) * f;
}
f = twicearea * 3;
return {
X: x / f + off.lat,
Y: y / f + off.lng
};
}
または古き良きcで、 x および y プロパティを持つ Point 構造体があると仮定しながら:
const Point centroidForPoly(const int numVerts, const Point* verts)
{
float sum = 0.0f;
Point vsum = 0;
for (int i = 0; i<numVerts; i++){
Point v1 = verts[i];
Point v2 = verts[(i + 1) % numVerts];
float cross = v1.x*v2.y - v1.y*v2.x;
sum += cross;
vsum = Point(((v1.x + v2.x) * cross) + vsum.x, ((v1.y + v2.y) * cross) + vsum.y);
}
float z = 1.0f / (3.0f * sum);
return Point(vsum.x * z, vsum.y * z);
}
PHPで:
// Find the polygon's centroid.
function getCenter($polygon)
{
$NumPoints = count($polygon);
if($polygon[$NumPoints-1] == $polygon[0]){
$NumPoints--;
}else{
//Add the first point at the end of the array.
$polygon[$NumPoints] = $polygon[0];
}
// Find the centroid.
$X = 0;
$Y = 0;
For ($pt = 0 ;$pt<= $NumPoints-1;$pt++){
$factor = $polygon[$pt][0] * $polygon[$pt + 1][1] - $polygon[$pt + 1][0] * $polygon[$pt][1];
$X += ($polygon[$pt][0] + $polygon[$pt + 1][0]) * $factor;
$Y += ($polygon[$pt][1] + $polygon[$pt + 1][1]) * $factor;
}
// Divide by 6 times the polygon's area.
$polygon_area = ComputeArea($polygon);
$X = $X / 6 / $polygon_area;
$Y = $Y / 6 / $polygon_area;
return array($X, $Y);
}
function ComputeArea($polygon)
{
$NumPoints = count($polygon);
if($polygon[$NumPoints-1] == $polygon[0]){
$NumPoints--;
}else{
//Add the first point at the end of the array.
$polygon[$NumPoints] = $polygon[0];
}
$area = 0;
for ($i = 0; $i < $NumPoints; $i++) {
$i1 = ($i + 1) % $NumPoints;
$area += ($polygon[$i][1] + $polygon[$i1][1]) * ($polygon[$i1][0] - $polygon[$i][0]);
}
$area /= 2;
return $area;
}
続きを読む: