二维阵列最远点搜索

时间:2018-08-21 00:39:38

标签: c# arrays search

我试图通过比较从pointsToSearchFrom列表中的每个点到pointCloudToSearchList中的每个点的距离来检索集合中最远的点。您可以从所附图像中看到示例方案。我仍然不是导航这些数据结构的专家,并且该算法超出了我目前对遍历二维数组的了解。

这是我直到知道的代码。任何帮助都会很棒。

public static void Test(List<Point3d> pointsToSearchFrom, List<Point3d> pointCloudToSearch)
{
    int rows = pointsToSearchFrom.Count;
    int columns = pointCloudToSearch.Count;
    double[,] arrayDistance = new double [rows, columns];

    for (int i = 0; i < pointsToSearchFrom.Count; i++)
    {
        for (int j = 0; j < pointCloudToSearch.Count; j++)
        {
            arrayDistance[i, j] = (pointsToSearchFrom[i] - pointCloudToSearch[j]).magnitude;
        }
    }
}

enter image description here

2 个答案:

答案 0 :(得分:0)

您可以为此使用二维数组,但不必这样做。

您需要的是可以在此处找到的MaxBy方法:

https://github.com/morelinq/MoreLINQ/blob/master/MoreLinq/MaxBy.cs

我们首先构建一对配对:

var pairs = from first in pointsToSearchFrom
            from second in pointCloudToSearch
            select new { first, second };

请注意,在C#7中,您将使用元组,而不是匿名类型。

现在我们有了所有可能对的序列。使用MaxBy查找使给定数量最大化的对:

var maxPair = pairs.MaxBy(pair => (pair.first - pair.second).magnitude);

现在您已完成:

Console.WriteLine($"{maxPair.first} --> {maxPair.second});

如果您有大量的点集(例如成千上万个),则必须使用特殊的技术,因为如果有成千上万的点,那么将有数百万个对,并且如果有数百万个,点的数量将达到数万亿。但是,如果您只有少数几个,则此技术可以正常工作。

答案 1 :(得分:0)

起初我并没有意识到这是3D。我使用了一个类和列表来存储2点及其之间的距离。这样,我不仅可以得到最长的距离,而且可以得到产生该距离的2个点。

    public class Distances
    {
        public double Distance { get; set; }
        public Point3D FromPoint { get; set; }
        public Point3D ToPoint { get; set; }

        public Distances(Point3D from, Point3D to)
        {
            FromPoint = from;
            ToPoint = to;
            Distance = (to - from).Length;
        }
    }
    private void OP2()
    {
        List<Point3D> searchFrom = new List<Point3D>()
        {
        new Point3D(20,30,50),
        new Point3D(10,50,10),
        new Point3D(30,40,20),
        new Point3D(60,30,10)
        };

        List<Point3D> searchCloud = new List<Point3D>()
        {
        new Point3D(60,70,80),
        new Point3D(110,30,30),
        new Point3D(80,110,55),
        new Point3D(90,20,90)
        };
        List<Distances> resultDistances = new List<Distances>();
        foreach (Point3D p1 in searchFrom)
        {
            foreach (Point3D p2 in searchCloud)
            {
                Distances d = new Distances(p1, p2);
                resultDistances.Add(d);
            }
        }
        //The following is just for testing purposes, skip to var longestDistance
        List<Distances> distancesInOrder = resultDistances.OrderByDescending(i => i.Distance).ToList<Distances>();
        foreach (Distances d in distancesInOrder)
        {
            Debug.Print($"From Point ({d.FromPoint.X}, {d.FromPoint.Y}, {d.FromPoint.Z}) To Point ({d.ToPoint.X}, {d.ToPoint.Y}, {d.ToPoint.Z}) Distance = {d.Distance}");
        }
        var longestDistance = resultDistances.OrderByDescending(i => i.Distance).FirstOrDefault();
        //this gives you the longest distance and the two points
        MessageBox.Show($"First Point ({longestDistance.FromPoint.X}, {longestDistance.FromPoint.Y}, {longestDistance.FromPoint.Z}) Cloud Point ({longestDistance.ToPoint.X}, {longestDistance.ToPoint.Y}, {longestDistance.FromPoint.Z}) Distance = {longestDistance.Distance}");
    }