2016-08-26 22 views
-1

3D頂点の集合を仮定すると、任意の形状の2Dポリゴンの表面積を計算したいと考えています。たとえば、この図の表面積は何ですか?Javascript、Math:3Dにある平坦な2Dサーフェスの面積を計算する

var polygon = new Polygon([new Point(0,0,0), new Point(5,8,2), new Point(11,15,7)]) 
polygon.areaIfPolygonIs3D() 
--> some predictable result, no matter how many vertices the polygon has... 

ポリゴンのサーフェスは1つだけです。彼らはフラットですが、三角形や台形やランダムな形をしていて、3Dの角度で浮いている可能性があります。

私がこれまでにやったことは、物事をフラットにして、現在自分のコード(式:http://www.wikihow.com/Calculate-the-Area-of-a-Polygon)で作業している2Dの不規則なポリゴンの面積を計算するための基本式を使用することです。すべての頂点をどのように回転させてポリゴンを平坦にするか(すべての "z"の値は0)、私はそのパスを断念しましたが、誰かがそこに着くことができれば試してみることができます。

ポイントとエッジ(point.to(ポイント)で作成)、エッジには「theta」(edge.theta())を使用できます。これはおそらくPoint.rotateByと 'phi'(edge.phi())があります。

いずれにしても、高校から忘れてしまったすべてのジオメトリを再学習しようと一日の努力をして、誰かがここに行って助けてくれたら、それは大いに感謝しています。あなたのポリゴン面がZ軸に平行でない場合

var locatorRho = function(x,y,z) { 
    return Math.sqrt(x*x + y*y + z*z); 
} 

var locatorTheta = function(x,y) { 
    return Math.atan2(y,x); 
}; 

var locatorPhi = function(x,y,z) { 
    return z == 0 ? Math.PI_2 : Math.acos(z/locatorRho(x, y, z)); 
} 

// rotates a point according to another point ('locator'), and their 2D angle ('theta') and 3D angle ('phi') 
Point.prototype.rotateBy = function(locator, theta, phi) { 
    phi = (phi == undefined ? 0 : phi); 
    var relativeX = this.x() - locator.x(); 
    var relativeY = this.y() - locator.y(); 
    var relativeZ = this.z() - locator.z(); 
    var distance = locatorRho(relativeX, relativeY, relativeZ); 
    var newTheta = locatorTheta(relativeX, relativeY) + theta; 
    var newPhi = locatorPhi(relativeX, relativeY, relativeZ) + phi; 
    this._x = locatorX(distance, newTheta, newPhi) + locator.x(); 
    this._y = locatorY(distance, newTheta, newPhi) + locator.y(); 
    this._z = locatorZ(distance, newPhi) + locator.z(); 
} 

Polygon.prototype.signedArea = function() { 
    var vertices = this.vertices(); 
    var area = 0; 
    for(var i=0, j=1, length=vertices.length; i<length; ++i, j=(i+1)%length) { 
    area += vertices[i].x()*vertices[j].y() - vertices[j].x()*vertices[i].y(); 
    } 
    return 0.5*area 
} 

Polygon.prototype.areaIfPolygonIs2D = function() { 
    return Math.abs(rotatedFlatCopy.signedArea()) 
} 

Polygon.prototype.areaIfPolygonIs3D = function() { 
    ... help here I am so stuck ... 
} 

var vertices = [some number of Points, e.g., new Point(x,y,z)] 
var polygon = new Polygon(vertices) 
var polygon.areaIfPolygonIs3D() 
--> result 
+0

3dのすべての点が飛行機に乗っていると言っていますが、この飛行機の点で囲まれた領域に興味がありますか?または、投影面積に興味がありますか? –

答えて

1

は、Xを用いた公知の手法を用いて面積投影を計算することができ、Yは座標のみ、その平面

にZ軸と法線Nとの間の角度のコサインによって結果を割り
Area = Sum[x1*y2-x2*y1 +...] ////shoelace formula 
True_Area = Area/Cos(Angle between N and Z axis)) = 
       Area/DotProduct((N.x,N.y,N.z), (0,0,1)) = 
       Area/N.z 
       //// if N is normalized (unit) 
+0

OZはZ軸の方向ベクトルです。コサインは、NとOZの間の角度です。コサインはドットプロダクトによって表現されるかもしれません - それは単純化につながります。 – MBo

+0

あなたはZ軸の方向を取得する必要はありません - それは単に存在します:)。正規化された(単位)ベクトルの長さは1です。平面の向きについてはどう思いますか? – MBo

+0

ベクトル**(頂点[1] - 頂点[0])**と**(頂点[2] - 頂点[0])**のベクトル積として法線ベクトルNを計算してから、正規化ベクトルN長さで成分を分割する。法線ベクトルは面方位を特徴づけ、私が書いたように、真の領域を見つけるためにz成分が使われるかもしれません。 – MBo

0

は、2D頂点(X, Y)(Y, Z)(Z, X)に、座標法を3回使用します。所望の領域は、√Axy²+Ayz²+Azx²で与えられます(ポリゴンがフラットである場合)。

関連する問題