我需要按距离对点列表进行排序。
因此,例如
input : [[1,2],[5,10],[2,4]...]
output : [[1,2],[2,4],[5,10]...]
(假设几何上[1,2]和[2,4]最接近& [2,4]& [5,10]最接近。
我需要它们对它进行排序,使它们按距离排序,即在几何图形上,点a最接近点b,点b最接近c,依此类推。
有什么想法吗?
编辑:代码示例
public class Point
{
public double X {get;set;}
public double Y {get;set;}
}
List<Point> points = new List<Point>();
假设我的点列表以随机顺序(不是几何距离)填充。 所以点看起来像......
指向[[1,2],[5,10],[2,4] ......]
现在我的图表控制只需要第一个&amp;第二点,并在它们之间画一条线。这意味着它并不关心它的几何顺序。 如果我只是提供&#34;积分&#34;列出如上所示它将在每个点之间绘制线条,从图表的角度来看,它看起来不正确,因为它们将是&#34; zig-zag&#34;。
为了确保图表控件绘制一条直线(&amp;而不是zig-zag),我必须以正确的顺序传递点,这看起来像......
destination points ~ [[1,2],[2,4],[5,10]...]
所以我的问题是如何实现这一目标。
注意:此处无法更改图表控件。
由于
答案 0 :(得分:4)
代码首先在“0”索引处取最近的点(0,0),然后开始按距离最后一个点的距离对点进行排序。
C#:
List<Point> SortByDistance(List<Point> lst)
{
List<Point> output = new List<Point>();
output.Add(lst[NearestPoint(new Point(0, 0), lst)]);
lst.Remove(output[0]);
int x = 0;
for (int i = 0; i < lst.Count + x; i++)
{
output.Add(lst[NearestPoint(output[output.Count - 1], lst)]);
lst.Remove(output[output.Count - 1]);
x++;
}
return output;
}
int NearestPoint(Point srcPt, List<Point> lookIn)
{
KeyValuePair<double, int> smallestDistance = new KeyValuePair<double, int>();
for (int i = 0; i < lookIn.Count; i++)
{
double distance = Math.Sqrt(Math.Pow(srcPt.X - lookIn[i].X, 2) + Math.Pow(srcPt.Y - lookIn[i].Y, 2));
if (i == 0)
{
smallestDistance = new KeyValuePair<double, int>(distance, i);
}
else
{
if (distance < smallestDistance.Key)
{
smallestDistance = new KeyValuePair<double, int>(distance, i);
}
}
}
return smallestDistance.Value;
}
VB.Net:
Function SortByDistance(ByVal lst As List(Of Point)) As List(Of Point)
Dim out As New List(Of Point)
out.Add(lst(NearestPoint(New Point(0, 0), lst)))
lst.Remove(out(0))
Dim x As Integer = 0
For i As Integer = 0 To lst.Count - 1 + x
out.Add(lst(NearestPoint(out(out.Count - 1), lst)))
lst.Remove(out(out.Count - 1))
x += 1
Next
Return out
End Function
Function NearestPoint(ByVal srcPt As Point, ByVal lookIn As List(Of Point)) As Integer
Dim smallestDistance As KeyValuePair(Of Double, Integer)
For i As Integer = 0 To lookIn.Count - 1
Dim distance As Double = Math.Sqrt(Math.Pow(srcPt.X - lookIn(i).X, 2) + Math.Pow(srcPt.Y - lookIn(i).Y, 2))
If i = 0 Then
smallestDistance = New KeyValuePair(Of Double, Integer)(distance, i)
Else
If distance < smallestDistance.Key Then
smallestDistance = New KeyValuePair(Of Double, Integer)(distance, i)
End If
End If
Next
Return smallestDistance.Value
End Function
答案 1 :(得分:1)
我想你想要这个,Dijkstra's algorithm。有一个c#项目here。
以下内容是该链接中未经修改的代码
class Dijkstra
{
private int rank = 0;
private int[,] L;
private int[] C;
public int[] D;
private int trank = 0;
public Dijkstra(int paramRank,int [,]paramArray)
{
L = new int[paramRank, paramRank];
C = new int[paramRank];
D = new int[paramRank];
rank = paramRank;
for (int i = 0; i < rank; i++)
{
for (int j = 0; j < rank; j++) {
L[i, j] = paramArray[i, j];
}
}
for (int i = 0; i < rank; i++)
{
C[i] = i;
}
C[0] = -1;
for (int i = 1; i < rank; i++)
D[i] = L[0, i];
}
public void DijkstraSolving()
{
int minValue = Int32.MaxValue;
int minNode = 0;
for (int i = 0; i < rank; i++)
{
if (C[i] == -1)
continue;
if (D[i] > 0 && D[i] < minValue)
{
minValue = D[i];
minNode = i;
}
}
C[minNode] = -1;
for (int i = 0; i < rank; i++)
{
if (L[minNode, i] < 0)
continue;
if (D[i] < 0) {
D[i] = minValue + L[minNode, i];
continue;
}
if ((D[minNode] + L[minNode, i]) < D[i])
D[i] = minValue+ L[minNode, i];
}
}
public void Run()
{
for (trank = 1; trank >rank; trank++)
{
DijkstraSolving();
Console.WriteLine("iteration" + trank);
for (int i = 0; i < rank; i++)
Console.Write(D[i] + " ");
Console.WriteLine("");
for (int i = 0; i < rank; i++)
Console.Write(C[i] + " ");
Console.WriteLine("");
}
}
}
答案 2 :(得分:0)
在图表中,应该对任何一个坐标的值排序一组点(x1,y1), (x2,y2), (x3,y3)...(xn,yn)
,因为它不是下一个按顺序排列的最近点,而是最接近x或y的点(以哪个轴作为参考)坐标值。因此,要传递给图表的数组应为:
var orderedPoints=points.OrderBy(p=>p.X);
在上图中,线L1的长度大于L2。但是点P2而不是P3应该在P1之后P2.X<P3.X