从坐标列表中提取方向变化

时间:2016-03-16 22:17:16

标签: c# linq

给定一个坐标列表,确定方向变化的最有效方法是什么?

Path of coordinates

我目前的尝试:

        List<Point> path = GetRoute();

        List<Point> pointsToKeep = new List<Point>();

        pointsToKeep.Add(path.First());

        int previousX = path.First().X;
        int previousY = path.First().Y;

        foreach (var item in path)
        {
            int diffY = (item.Y - previousY);
            bool up = diffY > 0;
            bool down = diffY < 0;

            if (up || down)
            {
                pointsToKeep.Add(item);
            }

            previousX = item.X;
            previousY = item.Y;
        }

理想情况下,希望将橙色中突出显示的所有点添加到pointsToKeep列表中

当路径从左到右时,X坐标永远不会减少

2 个答案:

答案 0 :(得分:1)

您需要不仅跟踪前一个点,而且还要跟踪您前一个点到达的方向。如果你稍微眯一下,你可以说这类似于函数 f(x)中的you need derivatives to find the relative minimum and relative maximum原因。

现在回到你的案子。假设您可能的方向是0度,45度或90度,那么只记录两个标志应该足以代表所有可能的斜率。 (如果我的假设不适合你的情况,你需要跟踪比标志更详细的东西。)

所有这些,你可能需要这样的东西:

        var previous = path.First();
        var direction = new Point(0, 0);

        foreach (var item in path)
        {
            var signX = Math.Sign(item.X - previous.X);
            var signY = Math.Sign(item.Y - previous.Y);

            if (signX != direction.X || signY != direction.Y)
            {
                pointsToKeep.Add(previous);
            }

            previous = item;
            direction = new Point(signX, signY);
        }

请注意,如果您将item添加到列表中,则会跟踪方向的第一个点,而如果您添加previous在列表中,您将跟踪上一个方向的最后一点。 (我相信你可能希望保留previous,但请亲自看看。)

答案 1 :(得分:1)

你可以试试这个

    List<Point> path = Point.GetData();
    List<Point> pointsToKeep = new List<Point>();
    var current = path[0];
    var currentDiffX = 0;
    var currentDiffY = 0;
    foreach (var point in path)
    {
        var diffX = point.X - current.X;
        var diffY = point.Y - current.Y;
        if (diffX != currentDiffX || diffY != currentDiffY)
            pointsToKeep.Add(current);
        current = point;
        currentDiffX = diffX;
        currentDiffY = diffY;
    }
    // add the last point
    pointsToKeep.Add(path[path.Count-1]);
    foreach(var point in pointsToKeep)
        Console.WriteLine("Ponint({0}.{1})",point.X,point.Y);

获得更准确的结果

- 你可以跟踪斜率(y2-y1)/(x2-x1),一旦斜率改变,然后加点

这是一个有效的demo