【问题标题】:Is there any algorithm for calculating area of a shape given co-ordinates that define the shape?在给定定义形状的坐标的情况下,是否有任何算法可以计算形状的面积?
【发布时间】:2011-01-26 19:23:11
【问题描述】:

所以我有一些函数可以接收 N 个随机 2D 点。

是否有任何算法可以计算输入点定义的形状面积?

【问题讨论】:

  • 你的问题到底是什么?你说的是什么方格?
  • 不太清楚您要的是什么,可能是最小边界正方形/矩形?
  • “计算形状的平方”是什么意思?你是说那个地区吗?如果是,你用什么方法来确定“形状”是什么?
  • N 的大小可能是多少?是否有任何性能限制?
  • :) @Mark Byers:我们离性能调整还很远,因为我们离问题还很远?

标签: c# algorithm geometry


【解决方案1】:

我找到了另一个function written in Java,所以我把它翻译成C#

public static double area(List<Double> lats,List<Double> lons)
{       
double sum=0;
double prevcolat=0;
double prevaz=0;
double colat0=0;
double az0=0;
for (int i=0;i<lats.Count;i++)
{
    double colat=2*Math.Atan2(Math.Sqrt(Math.Pow(Math.Sin(lats[i]*Math.PI/180/2), 2)+ Math.Cos(lats[i]*Math.PI/180)*Math.Pow(Math.Sin(lons[i]*Math.PI/180/2), 2)),
        Math.Sqrt(1-  Math.Pow(Math.Sin(lats[i]*Math.PI/180/2), 2)- Math.Cos(lats[i]*Math.PI/180)*Math.Pow(Math.Sin(lons[i]*Math.PI/180/2), 2)));
    double az=0;
    if (lats[i]>=90)
    {
        az=0;
    }
    else if (lats[i]<=-90)
    {
        az=Math.PI;
    }
    else
    {
        az=Math.Atan2(Math.Cos(lats[i]*Math.PI/180) * Math.Sin(lons[i]*Math.PI/180),Math.Sin(lats[i]*Math.PI/180))% (2*Math.PI);
    }
    if(i==0)
    {
         colat0=colat;
         az0=az;
    }           
    if(i>0 && i<lats.Count)
    {
        sum=sum+(1-Math.Cos(prevcolat  + (colat-prevcolat)/2))*Math.PI*((Math.Abs(az-prevaz)/Math.PI)-2*Math.Ceiling(((Math.Abs(az-prevaz)/Math.PI)-1)/2))* Math.Sign(az-prevaz);
    }
    prevcolat=colat;
    prevaz=az;
}
sum=sum+(1-Math.Cos(prevcolat  + (colat0-prevcolat)/2))*(az0-prevaz);
return 5.10072E14* Math.Min(Math.Abs(sum)/4/Math.PI,1-Math.Abs(sum)/4/Math.PI);
}

【讨论】:

    【解决方案2】:

    你想calculate the area of a polygon

    (取自链接,转换为 C#)

    class Point { double x, y; } 
    
    double PolygonArea(Point[] polygon)
    {
       int i,j;
       double area = 0; 
    
       for (i=0; i < polygon.Length; i++) {
          j = (i + 1) % polygon.Length;
    
          area += polygon[i].x * polygon[j].y;
          area -= polygon[i].y * polygon[j].x;
       }
    
       area /= 2;
       return (area < 0 ? -area : area);
    }
    

    【讨论】:

    • 我梦见天体;)
    • 嗯,很好,但这是否可以解决凹度问题(扭曲多边形:)?
    • 正如我在回答中提到的,没有现成的多边形:您需要创建一个。
    • 我知道这可能不是要问的地方,但是...我如何将这个概念应用于由大地顶点(纬度)构成的多边形。我需要对笛卡尔坐标系进行投影还是有更简单的方法?
    【解决方案3】:

    您的问题并不直接暗示有现成的多边形(由this answer 假设)。我会推荐一个三角测量,比如Delaunay Triangulation,然后简单地计算每个三角形的面积。 OpenCV(我用过大量的二维点,非常有效)和CGAL为确定三角测量提供了出色的实现。

    【讨论】:

      【解决方案4】:

      您可以使用 Timothy Chan 的算法在 nlogh 中找到凸包,其中 n 是点数,h 是凸包顶点数。如果您想要一个简单的算法,请使用 Graham 扫描。

      此外,如果您知道您的数据像一个简单的链一样有序,其中点不相互交叉,您可以使用 Melkman 算法计算 O(N) 中的凸包。

      此外,凸包的另一个有趣特性是,它具有最小周长。

      【讨论】:

        【解决方案5】:

        定义点集合的“区域”可能很困难,例如如果您想获得包含您的集合的直线边界的最小区域,那么我不确定如何继续。您可能想要做的是计算您的一组点的凸包面积;这是一个标准问题,Steven Skiena 在Stony Brook Algorithms repository 给出了解决方案实现链接的问题描述。从那里计算面积的一种方法(在我看来是显而易见的方法)是对该区域进行三角测量并计算每个三角形的面积。

        【讨论】:

        • “具有直线边界的最小区域”的面积为 0,并包含一个最小生成树。
        • 是的,足够公平的评论。我想可以对这个问题施加合理的约束,以提供除凸包之外的解决方案(例如,通过允许任意边缘来允许“大”孔,并限制边缘数量为 O(n^{1 /2})),但任何此类问题都可能非常难以解决。
        • 在这里挑选nits,但直线边界最短的区域实际上是Steiner树,通常比MST短。
        • 凸包面积的唯一保证是它是一个上限
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-08-19
        • 2013-08-12
        • 2018-10-06
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多