【问题标题】:How to sort floating point coordinates with no elimination of coordinates? [closed]如何在不消除坐标的情况下对浮点坐标进行排序? [关闭]
【发布时间】:2015-01-13 19:00:07
【问题描述】:

我有一个坐标列表,应该形成我需要排序的路径的边缘。我正在尝试使用 Grahams 扫描并尝试了以下几个样本:

  1. GrhamsScan.cs
  2. ConvexHull.cs
  3. ConvexHull Algo

这些代码在我拥有的几个测试用例中都失败了,我不确定出了什么问题。

编辑:

这些坐标应该是切线的一部分。如果坐标未排序,则切线会随机出现,而不是随着风暴的进行而可能是直的或弯曲的正确路径。

我正在创建形成风暴路径的圆圈的切线。可以在这里看到一个例子:

编辑#02

如果形成切线的点是有序的,那么正确的形状(忽略末尾的半圆)应该是这样的。

测试用例:

测试用例#01

[0]: {X = 11.581625 Y = -110.983437}
[1]: {X = 11.1816254 Y = -108.983437}
[2]: {X = 11.88781 Y = -113.115852}
[3]: {X = 11.587204 Y = -111.015938}
[4]: {X = 12.1884336 Y = -115.215759}
[5]: {X = 11.88781 Y = -113.115845}
[6]: {X = 12.5794077 Y = -116.863365}
[7]: {X = 12.1794081 Y = -115.163368}
[8]: {X = 13.0785418 Y = -118.855026}
[9]: {X = 12.5785418 Y = -116.855026}
[10]: {X = 13.534234 Y = -119.732178}
[11]: {X = 13.034234 Y = -118.732178}

测试用例#02

   [0]: {X = 10.4182844 Y = -111.21611}
[1]: {X = 10.0190592 Y = -109.21595}
[2]: {X = 10.712142 Y = -113.283806}
[3]: {X = 10.4127483 Y = -111.183716}
[4]: {X = 11.0115175 Y = -115.383896}
[5]: {X = 10.712141 Y = -113.2838}
[6]: {X = 11.4204569 Y = -117.136063}
[7]: {X = 11.0213022 Y = -115.435867}
[8]: {X = 11.9213 Y = -119.144341}
[9]: {X = 11.4223957 Y = -117.144066}
[10]: {X = 12.4652023 Y = -120.266693}
[11]: {X = 11.9662571 Y = -119.266167}

测试用例#03

   [0]: {X = 10.6 Y = -109.1}
    [1]: {X = 11.0 Y = -111.1}
    [2]: {X = 11.3 Y = -113.2}
    [3]: {X = 11.6 Y = -115.3}
    [4]: {X = 12.0 Y = -117.0}
    [5]: {X = 12.5 Y = -119.0}
    [6]: {X = 13.0 Y = -120.0}

请指导我一个资源、算法或代码,我可以在其中找到可靠的浮点坐标排序算法,并且在执行此操作时不会消除点。速度不是第一要务,准确性是优先考虑的。

我将不胜感激所有投入。谢谢

【问题讨论】:

  • 你能给我们展示一下这些数据的样子吗?还有,形状是凸的吗?
  • 添加了截图和一些相关细节。
  • 每个数据集中有一个或两个轨道吗?
  • 在这种情况下,假设轨道不会自行循环,我想只要从一个点到另一个点选择最近的一个就可以了。
  • 我不明白你要解决的问题与凸包有什么关系。

标签: c# sorting floating-point coordinates grahams-scan


【解决方案1】:

很遗憾,您丢失了曾经存在于气象数据中的时间刻度,并且积分无法按顺序到达您的手中
所以你想从一组点重建一条路径。一旦完成,这个答案就是考虑构造信封应该不是问题。

如果你有 N 个点,就有 N 个!可能的顺序。

在这些排序中,您必须选择能够最大限度地表示风暴轨迹的可能性。

一个简单的标准可能是最小化路径长度。更高级的可以考虑到风暴速度不能立即改变,因此或多或少会惩罚加速度。或者加速度的导数……但这可能需要关于时间采样规律的额外假设。

在所有情况下,您都必须注入风暴轨迹应该是什么样子的模型,并将某种分数(概率)与各种假设(可能的轨迹)相关联。

除非您的点集非常小,否则您不会迭代整个组合。相反,您将从一个任意点开始重建轨迹。然后,您将尝试通过迭代添加一个点来在一侧或另一侧扩展轨迹。您将先验地选择一组最有可能的候选者(例如距离重建轨迹的最后一个点最近的点,或者最接近已重建轨迹的外推法,具有恒定速度或恒定加速度假设......)。

一个简单的算法将在每一步本地选择最可能的候选者。

更严谨的算法会并行重构几个可能的轨迹,并根据一些概率选择规则消除最不可能的轨迹。

我看到这类问题与使用 RADAR 跟踪目标密切相关,因此您可能会查看此类文献,尤其是对贝叶斯集成概率感兴趣。我希望你喜欢数学。

【讨论】:

    【解决方案2】:

    这是我写的,它最终适用于所有情况。让我承认它可以提高性能,这可能是一种快速而肮脏的方式,但这是我目前正在使用的。

    P.S:我也承认“Convex Hull”或“Graham Scan”从来都不是我所需要的,与所需要的无关。所以从技术上讲,这是我这边的一个错误。我需要按照@Chris 的建议,首先对最近的点进行排序。

    public class ConvexHull6
    {
    
        public class PointDistance
        {
            public double X { get; set; }
            public double Y { get; set; }
            public double distance { get; set; }
            public int index { get; set; }
        }
        public class StormPointsDistance
        {
            public StormPoints stormPoints { get; set; }
            public Double distance { get; set; }
        }
        public static List<PointD> ReOrderPointsByClosestPointFirst(List<PointD> points, bool islower = false)
        {
            var minX = points.Min(p => p.X);
            var maxX = points.Max(p => p.X);
            var minP = points.First(p => p.X == minX);
            var maxP = points.First(p => p.X == maxX);
    
            minP = points.First(p => p.X == minX);
            maxP = points.First(p => p.X == maxX);
    
            var pB = points.ToList();
            var len = pB.Count();
            //Temporary lists to hold data structures and points when performing the points sorting..
            var pDist = new List<PointDistance>();
            var distances = new List<Double>();
            int index = 0;
            //Sorted list to hold final points...
            var sorted = new List<PointD>();
            for (int i = 0; i < len; i++)
            {
                if (i > 0)
                {
                    //Minimum point or "Point of Reference for comparison" is now the last point in the sorted list.
                    minP = sorted[sorted.Count() - 1];
                    //Clear the temporary lists used...
                    pDist.Clear(); distances.Clear();
                }
                for (int j = 0; j < len - i; j++)
                {
                    var distance = Math.Sqrt(Math.Pow(pB[j].X - minP.X, 2) + Math.Pow(pB[j].Y - minP.Y, 2));
                    pDist.Add(new PointDistance() { X = pB[j].X, Y = pB[j].Y, distance = distance, index = index });
                    distances.Add(distance);
                }
                //Order the data structure
                pDist = pDist.OrderBy(m => m.distance).ToList();
                //Convert to points list for use
                pB = pDist.Select(m => new PointD(m.X, m.Y)).ToList();
                //Get the first point and put it in the sorted list
                sorted.Add(pB[0]);
                //Remove the point from the pb list so that it is not considered again
                pB.RemoveAt(0);
    
                index++;
            }
            pDist = pDist.OrderBy(m => m.distance).ToList();
            distances = pDist.Select(m => m.distance).ToList();
    
            //The new code...
            points = sorted.ToList();
    
            //Get the minimum Point again as minP has been overwritten during the loop
            minX = points.Min(p => p.X);
            maxX = points.Max(p => p.X);
            minP = points.First(p => p.X == minX);
            maxP = points.First(p => p.X == maxX);
            //Check if minp does nott match the first point
            if ((minP != points[0] && maxP == points[0]) || (maxP != points[len - 1] && minP == points[len - 1]))
            {
                //Reverse only if the first point of array is not the minimum point
                points.Reverse();
            }
            return points;
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 2012-07-22
      • 1970-01-01
      • 2021-08-30
      • 1970-01-01
      • 2019-02-26
      • 1970-01-01
      • 2016-01-01
      • 1970-01-01
      • 2011-11-05
      相关资源
      最近更新 更多