Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# C语言中不规则多边形面积的计算#_C#_Arrays_List_Polygon_Area - Fatal编程技术网

C# C语言中不规则多边形面积的计算#

C# C语言中不规则多边形面积的计算#,c#,arrays,list,polygon,area,C#,Arrays,List,Polygon,Area,我已经设法写了一篇“为假人”的文章,如何计算C#中不规则多边形的面积,但是我需要它对任何数量的垂直都是动态的 有人能帮忙吗 类别: public class Vertex { private int _vertexIdx; private double _coordX; private double _coordY; private double _coordZ; public Vertex() { } public Vertex(in

我已经设法写了一篇“为假人”的文章,如何计算C#中不规则多边形的面积,但是我需要它对任何数量的垂直都是动态的

有人能帮忙吗

类别:

public class Vertex
{
    private int _vertexIdx;
    private double _coordX;
    private double _coordY;
    private double _coordZ;

    public Vertex()
    { }

    public Vertex(int vertexIdx, double coordX, double coordY, double coordZ)
    {
        _vertexIdx = vertexIdx;
        _coordX = coordX;
        _coordY = coordY;
        _coordZ = coordZ;
    }

    public int VertexIdx
    {
        get { return _vertexIdx; }
        set { _vertexIdx = value; }
    }

    public double X
    {
        get { return _coordX; }
        set { _coordX = value; }
    }

    public double Y
    {
        get { return _coordY; }
        set { _coordY = value; }
    }

    public double Z
    {
        get { return _coordZ; }
        set { _coordZ = value; }
    }
}
表格(u)负荷:

List<Vertex> verticies = new List<Vertex>();

verticies.Add(new Vertex(1, 930.9729, 802.8789, 0));
verticies.Add(new Vertex(2, 941.5341, 805.662, 0));
verticies.Add(new Vertex(3, 946.5828, 799.271, 0));
verticies.Add(new Vertex(4, 932.6215, 797.0548, 0));
示例输出:

X1=930.9729 Y1=802.8789

X2=941.5341 Y2=805.662

X3=946.5828 Y3=799.271

X4=932.6215 Y4=797.0548

X5=930.9729 Y5=802.8789

面积=83.2566504099523

类似于a(由记事本编译):

静态双行列式(双x1、双y1、双x2、双y2)
{
返回x1*y2-x2*y1;
}
静态双GetArea(IList顶点)
{
如果(顶点数<3)
{
返回0;
}
双面积=GetDeterminate(顶点[vertices.Count-1].X,顶点[vertices.Count-1].Y,顶点[0].X,顶点[0].Y);
对于(int i=1;i
虽然你的方法没有注意Z轴。因此,我建议应用一些变换来消除它:如果多边形不是平面,则无法获得面积,而如果多边形是平面,则可以消除第三维。

公共浮动区域(列出顶点)
public float Area(List<PointF> vertices)
{
    vertices.Add(vertices[0]);
    return Math.Abs(vertices.Take(vertices.Count - 1).Select((p, i) => (p.X * vertices[i + 1].Y) - (p.Y * vertices[i + 1].X)).Sum() / 2);
}
{ 顶点。添加(顶点[0]); 返回Math.Abs(顶点.Take(顶点.Count-1).Select((p,i)=>(p.X*顶点[i+1].Y)-(p.Y*顶点[i+1].X)).Sum()/2); }
使用lambda表达式,这变得微不足道

var points = GetSomePoints();

points.Add(points[0]);
var area = Math.Abs(points.Take(points.Count - 1)
   .Select((p, i) => (points[i + 1].X - p.X) * (points[i + 1].Y + p.Y))
   .Sum() / 2);
算法解释如下:

[此方法添加]多边形边定义的梯形区域 到X轴。当程序考虑多边形的底边时, 计算给出了负面积,因此多边形之间的空间 然后减去轴,留下多边形的面积

如果多边形的方向为顺时针方向,则总计算面积为负[因此]函数仅返回绝对值

这种方法 为非简单多边形(边交叉处)提供奇怪的结果


我发现,当计算大约600000个多边形的面积时,上面所示的基本公式适用于某些多边形,但很多多边形的面积都被计算出来了。我对我的结果进行了抽查,结果显示,对于有洞的非常复杂的多边形(例如中间的湖泊),结果是正确的。为了计算复杂多边形的正确面积,我最终使用了geojson.io使用的同一个系统——客户端js库Turf.js,请参见此处

在这张图中,您可以看到我的第一次尝试,然后是我使用Turp.js的第二次尝试-那里有一列显示了第一次尝试与第二次尝试的正确率,其中1是相同的计算。你可以看到,他们大部分都很接近,但有些人的差距是10倍甚至更大

下面是一些执行计算的示例代码。我让它在屏幕上加载200,然后用JS运行计算,并将结果返回到服务器端数据库

            $(document).ready(function () {
            var items = $('.geojson');
            for (var sc = 0; sc < items.length; sc++) {
                var id = $(items[sc]).attr('data-id');
                var polyData = JSON.parse($(items[sc]).find('.geojson-data').html());
                //console.log('[' + polyData + ']');
                var polygon = turf.polygon(polyData.coordinates);

                var area = turf.area(polygon);
                console.log('id[' + id + ']sqm[' + area + ']');

                    
                $(items[sc]).closest('tr').find('.data-id').html(id);
                var answerDom = $(items[sc]).closest('tr').find('.answer');

                if (true) {
                    $.ajax({
                        url: 'calc-poly-area-from-geojson-turf-scheduled.aspx',
                        type: "get",
                        data: {id:id, area: area },
                        invokedata: { answerDom: answerDom, area: area },
                        async: true,//run all at the same time
                        cache: false,
                        success: function (data) {
                            //console.log('test email done');

                            $(this.invokedata.answerDom).html('ok:' + this.invokedata.area);
                            $(this.invokedata.answerDom).removeClass('answer');

                            if ($('.answer').length == 0) {
                                window.location.reload();
                            }
                        },
                        error: function (msg) {
                            console.log("call failed: " + msg.responseText);
                            $(el).html('error in call');

                            //prompt('copy this',url+'?'+qs)
                        }
                    });
                }
            }
        });

        window.setTimeout(function () { window.location.reload(); }, 10000);
您可以将其粘贴到geojson.io中以检查其区域(单击多边形,然后单击“属性”选项卡)


我以前见过的一种典型方法是将多边形分割成三角形,然后简单地将所有三角形的面积相加。然而,这是非平凡的,因为它需要不同的算法,这取决于多边形的复杂性(交叉边、孔、凸/凹等)。你可能会考虑这个问题,一个堆栈溢出的网站,只针对数学问题。只要确保你提出的问题是非编程问题,而不是算法方法。MathOverflow是为那些想谈论研究生数学问题的专业数学家设计的。好吧,难怪这对我来说听起来像一门外语:)所以,在2D和3D计算的面积之间有差异吗?是的,只有一点点。只能为普通对象计算面积。因此,多边形必须是平面的-其所有顶点应位于同一平面上,否则无法计算面积。问题是这个平面并不总是像您的示例中那样是Z=0平面。你应该考虑到这一点,并在计算面积之前适当地处理这些点。我发现迄今为止给出的其他答案给出了错误的答案,而这是该线程中唯一给出正确答案的答案。不知道为什么。请向我竖起大拇指。请提供一些解释,使您的答案更容易理解。链接的“解释”并不解释算法。虽然我欣赏它的简洁,但我必须部分同意@cp.engr;可能不是最易于维护(可读)的解决方案。如果我最终做了类似的事情,希望我能发布一个更简单易懂的替代方案
var points = GetSomePoints();

points.Add(points[0]);
var area = Math.Abs(points.Take(points.Count - 1)
   .Select((p, i) => (points[i + 1].X - p.X) * (points[i + 1].Y + p.Y))
   .Sum() / 2);
            $(document).ready(function () {
            var items = $('.geojson');
            for (var sc = 0; sc < items.length; sc++) {
                var id = $(items[sc]).attr('data-id');
                var polyData = JSON.parse($(items[sc]).find('.geojson-data').html());
                //console.log('[' + polyData + ']');
                var polygon = turf.polygon(polyData.coordinates);

                var area = turf.area(polygon);
                console.log('id[' + id + ']sqm[' + area + ']');

                    
                $(items[sc]).closest('tr').find('.data-id').html(id);
                var answerDom = $(items[sc]).closest('tr').find('.answer');

                if (true) {
                    $.ajax({
                        url: 'calc-poly-area-from-geojson-turf-scheduled.aspx',
                        type: "get",
                        data: {id:id, area: area },
                        invokedata: { answerDom: answerDom, area: area },
                        async: true,//run all at the same time
                        cache: false,
                        success: function (data) {
                            //console.log('test email done');

                            $(this.invokedata.answerDom).html('ok:' + this.invokedata.area);
                            $(this.invokedata.answerDom).removeClass('answer');

                            if ($('.answer').length == 0) {
                                window.location.reload();
                            }
                        },
                        error: function (msg) {
                            console.log("call failed: " + msg.responseText);
                            $(el).html('error in call');

                            //prompt('copy this',url+'?'+qs)
                        }
                    });
                }
            }
        });

        window.setTimeout(function () { window.location.reload(); }, 10000);
{"type":"Polygon", "coordinates":[[[171.519147876006,-43.809111826162],[171.519264282931,-43.8094307100015],[171.519615782201,-43.8097268361192],[171.519874096036,-43.8097860548424],[171.525264107563,-43.8176887926426],[171.525356625489,-43.8179845471556],[171.525750029905,-43.8185636705947],[171.526002901974,-43.8187934292356],[171.526154917292,-43.8189686576417],[171.526249645477,-43.8191111884506],[171.526245660987,-43.819269203656],[171.526032299227,-43.8200263808647],[171.524134038501,-43.8268225827224],[171.523301803308,-43.8297987275054],[171.523129147529,-43.8301621243769],[171.522991616155,-43.8300725313285],[171.52248605771,-43.8302181414427],[171.522128893843,-43.8304084928376],[171.521558488905,-43.8304389785399],[171.521371202269,-43.830481916342],[171.521023295734,-43.8309120441211],[171.520774217465,-43.8310054055632],[171.520589483523,-43.8311387384524],[171.515210823266,-43.8294163992962],[171.514763136723,-43.8292736695248],[171.496256757791,-43.8233680542711],[171.494338310605,-43.8227558913632],[171.493450128779,-43.8224739752289],[171.493221517911,-43.8223838125259],[171.493001278557,-43.8222877021167],[171.492654147639,-43.821801588707],[171.491048512765,-43.8200169686591],[171.488157604579,-43.8168246695455],[171.488051808197,-43.8166695752984],[171.487648717141,-43.8162207994268],[171.486147094889,-43.8145461538075],[171.482241975825,-43.8101769774879],[171.481683765874,-43.8095751045999],[171.480858016595,-43.8085443728491],[171.481124633337,-43.8086557677844],[171.481334008334,-43.8085534985925],[171.481540735171,-43.8083379086683],[171.4815994175,-43.8077828104991],[171.481763314624,-43.8074471226617],[171.481812168914,-43.8064706917151],[171.48196041271,-43.8063093336607],[171.482260412185,-43.8062322290662],[171.482916004007,-43.8059780008537],[171.494844864468,-43.8013540958407],[171.501308718774,-43.7988446798756],[171.506019390319,-43.797017657826],[171.508275460952,-43.7961421972998],[171.508430707528,-43.7960805551645],[171.509117292333,-43.7963432108869],[171.510511038963,-43.7968679021071],[171.513299102675,-43.8007637699317],[171.513465917258,-43.8010892007185],[171.513696634335,-43.8013818859084],[171.513929550742,-43.8016136793445],[171.514114411714,-43.8018826827151],[171.514305634465,-43.8021912982997],[171.51440028511,-43.8024789426394],[171.514828618996,-43.8028429251794],[171.51494106207,-43.8031623582355],[171.515852739466,-43.8044825303059],[171.516111930457,-43.8047763591375],[171.517116748697,-43.8062534995253],[171.517374596163,-43.8065473602078],[171.517549793874,-43.8068229401963],[171.5176213721,-43.8070824951625],[171.517796573697,-43.8073580748019],[171.518070610117,-43.8076087983324],[171.518880109148,-43.8088563353488],[171.519147876006,-43.809111826162]]]}