【问题标题】:Javascript, Math: calculate the area of a flat, 2D surface that is situated in 3DJavascript,数学:计算位于 3D 中的平面 2D 表面的面积
【发布时间】:2016-08-26 18:30:53
【问题描述】:

在给定一组 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() 中存在错误。)

我可以使用点和边(使用 point.to(point) 创建),边有“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  

【问题讨论】:

  • 所以你是说 3d 中的所有点都在一个平面上,你对这个平面上这些点所包围的区域感兴趣,对吧?或者您对投影面积感兴趣。

标签: javascript math geometry polygon area


【解决方案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)

【讨论】:

  • OZ 为 Z 轴方向向量。余弦是角度 - N 和 OZ 之间的角度。余弦可以通过点积表示 - 它导致简化。
  • 您不需要获取 Z 轴的方向 - 它只是存在 :)。归一化(单位)向量的长度为 1。您对平面方向了解多少?
  • 您可以将法线向量 N 计算为向量 (vertices[1] - vertices[0])(vertices[2] - vertices[0 ]),然后找到它的长度,然后对向量 N 除以长度的分量进行归一化。正如我所写,法线向量表征平面方向,它的 z 分量可用于找到真实区域。
  • 如果法线 N 垂直于 Z 怎么办?
  • @Mohamed Amine Ouali 只需投影到另一个平面上
【解决方案2】:

在二维顶点(X, Y)(Y, Z)(Z, X) 上使用鞋带公式三次。所需区域由√Axy²+Ayz²+Azx² 给出(假设多边形是平面的)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-04-18
    • 1970-01-01
    • 1970-01-01
    • 2011-01-22
    • 2012-03-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多