C# 从坐标列表中提取方向更改

C# 从坐标列表中提取方向更改,c#,linq,C#,Linq,给定一个坐标列表,确定方向变化的最有效方法是什么 我目前尝试的是: List<Point> path = GetRoute(); List<Point> pointsToKeep = new List<Point>(); pointsToKeep.Add(path.First()); int previousX = path.First().X; int previousY

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

我目前尝试的是:

        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;
        }
List path=GetRoute();
List POINTSTOKEP=新列表();
pointstokep.Add(path.First());
int-previousX=path.First().X;
int previousY=path.First().Y;
foreach(路径中的变量项)
{
int diffY=(item.Y-先前);
bool-up=diffY>0;
bool-down=diffY<0;
如果(向上| |向下)
{
添加点(项目);
}
previousX=项目X;
上一个Y=项目.Y;
}
理想情况下,您希望将所有以橙色突出显示的点添加到pointsToKeep列表中


当路径从左向右移动时,X坐标永远不会减小,您不仅需要跟踪上一点,还需要跟踪到达上一点的方向。如果你稍微斜视一下,你可以说这与函数f(x)的图中的原因类似

现在回到你的情况。假设你可能的方向是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);
        }
请注意,如果向列表中添加
,则跟踪新方向的第一个点,而如果向列表中添加
上一个
,则跟踪上一个方向的最后一个点。(我相信您可能希望保留以前的
,但请亲自查看。)

您可以试试这个

    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);
List path=Point.GetData();
List POINTSTOKEP=新列表();
无功电流=路径[0];
var currentDiffX=0;
var currentDiffY=0;
foreach(路径中的变量点)
{
var diffX=点X-电流X;
var diffY=点Y-电流Y;
if(diffX!=currentDiffX | | diffY!=currentDiffY)
pointstokep.Add(当前);
电流=点;
currentDiffX=diffX;
currentDiffY=diffY;
}
//添加最后一点
pointstokep.Add(路径[path.Count-1]);
foreach(pointsToKeep中的var点)
WriteLine(“Ponint({0}.{1})”,点X,点Y;
为了得到更准确的结果

-可以跟踪坡度(y2-y1)/(x2-x1),一旦坡度发生变化,然后添加点


这里有一个正在运行的

您已有的代码有什么问题?它不起作用吗?它的速度不够快吗?我认为对于这个问题没有任何特殊的算法,所以您可能仅限于一些潜在的微优化points@theodoros-chatzigiannakis它现在给了我所有的垂直点,我得到了正确添加的第一个坐标,还有第二个,然而,当它沿着一条垂直线上升时,我得到了所有的中间点。@hadi hassan是正确的,在对角线方向上的点也有问题哦,我现在明白你的意思了。在这种情况下,问题是您没有在循环中携带所需的所有信息。仅仅知道上一个点是不够的——你需要知道上一个方向,这意味着你需要跟踪差异的符号(在X轴和Y轴上),并查看它是否保持不变。仅将您更改标志的点添加到列表中。这就足够让你开始了吗?这个代码示例和提供的链接已经帮助了很多人,很多人感谢这个演示和跟踪坡度变化的指针