将一个点阵列拆分为多个彼此相距特定距离的阵列

  • 本文关键字:阵列 距离 一个 拆分 c#
  • 更新时间 :
  • 英文 :


我有一个点数组,看起来像这样(x,y(:

6,12
6,13.25
6,14.5
6,15.75
6,17
6,18.25
18,12
18,13.25
18,14.5
18,15.75
18,17
18,18.25

这个数组代表两个独立的点序列,它们彼此相距1.25"。有两个序列,但也可以有[n]个序列,我需要根据特定的偏移量将它们划分为适当数量的数组,如下所示:

6,12
6,13.25
6,14.5
6,15.75
6,17
6,18.25
18,12
18,13.25
18,14.5
18,15.75
18,17
18,18.25

偏移可以在X或Y方向上,但不能同时在这两个方向上。我已经做了一段时间了,现在有点卡住了。

编辑

到目前为止,我尝试的是在数组中获取一个点,并搜索指定间隔上的所有点(getDist计算从一个点到另一个点的距离(:

foreach(Point firstPoint in points){
foreach(Point nextPoint in points){
if(isSame(firstPoint, nextPoint)
continue;
if(getDist(firstPoint, nextPoint) % 1.25 == 0){
// add to new array
}
}
}
double getDist(Point p1, Point p2) => Math.Sqrt(Math.Pow(p2.X - p1.X, 2) + Math.Pow(p2.Y - p1.Y, 2));
bool isSame(Point p1, Point p2) => p1.X == p2.X && p1.Y == p2.Y;

我遇到的问题是,这会查看所有的点,然后再次查看每个点,从而创建一组庞大的数组。

使用linq:

decimal[,] data = {{6,12}, {6,13.25M}, {6, 14.5M}, {6,15.75M}, {6,17}, {6,18.25M},
{18,12},{18,13.25M}, {18,14.5M},{18,15.75M},{18,17},{18,18.25M}};
var groups = data.Cast<decimal>()
.Select((x, i) => new { num = x, index = i })
.GroupBy(x => x.index / 2)
.Select(x => new decimal[] { x.FirstOrDefault().num, x.LastOrDefault().num })
.GroupBy(x => x.FirstOrDefault())
.Select(x => x.ToArray()).ToArray();

我尝试过这样做,但我没有将结果存储在数组中,而是使用了列表(尽管代码可能需要改进(:

List<List<PointF>> splitted_list = new List<List<PointF>>();
float x = 0;
float y = 0;
float offsetX = 0;
float offsetY = 0;
foreach(PointF p in points)
{
if (splitted_list.Count() > 0)
{
if (splitted_list.Last().Count() >= 2 && (p.X - x != offsetX || p.Y - y != offsetY))
{
List<PointF> list_points = new List<PointF>();
list_points.Add(p);
splitted_list.Add(list_points);
}
else
{
splitted_list.Last().Add(p);
offsetX = p.X - x;
offsetY = p.Y - y;
}
}
else
{
List<PointF> list_points = new List<PointF>();
list_points.Add(p);
splitted_list.Add(list_points);
}
x = p.X;
y = p.Y;
}

每次偏移量发生变化时,我都会创建一个新的列表,并将其添加到我的"列表列表"中(无论偏移量的值如何,它都有效(。

结果是一系列点的列表。如果必须将这些序列用作点的数组,则可以简单地使用ToArray((方法将列表转换为数组。

这里有另一个实现:

static void Main(string[] args)
{
List<PointF> points = new List<PointF>()
{
new PointF(6, 12),
new PointF(6, 13.25f),
new PointF(6, 14.5f),
new PointF(6, 15.75f),
new PointF(6, 17),
new PointF(6, 18.25f),
new PointF(18, 12),
new PointF(18, 13.25f),
new PointF(18, 14.5f),
new PointF(18, 15.75f),
new PointF(18, 17),
new PointF(18, 18.25f)
};
var result = new List<List<PointF>>();
int i, j = 0;
for (i = 1; i < points.Count; i++)
{
if (!IsInRange(points[i], points[i - 1]))
{
result.Add(points.GetRange(j, i - j));
j = i;
}
}
result.Add(points.GetRange(j, i - j));
}
static bool IsInRange(PointF a, PointF b) => Math.Abs(a.X + a.Y - b.X - b.Y) <= 1.25f;

所以,感谢你们的回复,有了他们,我才得以做到这一点。我用了类似的东西。我无法共享确切的代码,因为我的公司有代码无法共享。我在一个与数组非常相似的集合中获得点,我必须在这种类型的集合中使用它们。

while(points.Length > 0){
Point currentPoint = points[0];
List<Point> selectedPoints = new List<Point>();
selectedPoints.Add(currentPoint)
for(int i = 1; i <= points.Length; i++){
Point nextPoint = points[i];
double dist = getDist(currentPoint, nextPoint);
if(Math.Abs(dist % 1.25 - 0) < 1.19e-4){
selectedPoints.Add(nextPoint);
}
}
// remove selected points from all points
// add them to my list of points that I needed
}

谢谢你的帮助!

最新更新