Javascript,Math:计算位于3D中的平面2D表面的面积

时间:2016-08-26 18:30:54

标签: javascript math geometry polygon area

我希望能够在给定一组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... 

请记住,多边形只有一个表面。它们是扁平的,但可以是三角形或梯形或随机形状,并且可以以3D角度浮动......想象它们是在3D空间中以任何方式转动的纸张。

我到目前为止尝试做的是将物体旋转,然后使用基本公式计算当前在我的代码中工作的2D不规则多边形的区域(公式:http://www.wikihow.com/Calculate-the-Area-of-a-Polygon )。我有一个很难搞清楚如何旋转所有顶点以使多边形平坦(所有" z"值为0)我放弃了这条路径,尽管如果有人我可以尝试可以到达那里。 (也许Point.rotateBy()中有一个错误。)

我可以使用Points和Edges(使用point.to(point)创建),而Edges有' theta' (edge.theta())和' phi' (edge.phi())。

在任何情况下,如果有人可以填写这里的内容,并在试图重新学习我从高中忘记的所有几何学习一整天后帮助我,那将非常感激!

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  

2 个答案:

答案 0 :(得分:1)

如果多边形平面与Z轴不平行,则可以使用已知方法仅使用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)

答案 1 :(得分:0)

在2D顶点(X, Y)(Y, Z)(Z, X)上使用鞋带配方三次。所需区域由√Axy²+Ayz²+Azx²给出(假设多边形是平坦的)。