如何从起点到终点产生坐标对?

时间:2019-09-10 13:14:54

标签: c# algorithm coordinates

我想创建坐标对,以演示两点之间的路径。首先,如果该功能可用,则该功能应绘制一条对角线路径,然后其余坐标应为垂直或水平。

我计算了两点之间的X和Y绝对值。然后,如果X或Y大于零,则函数将其减小并产生结果。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            var start = new Point(10, 10);
            var end = new Point(5, 3);
            var coordinates = new List<Point>(Coordinates(start, end));
            foreach (var coord in coordinates)
            {
                Console.WriteLine("[" + coord.X + ", " + coord.Y + "]");
            }
            Console.ReadKey();
        }

        public static IEnumerable<Point> Coordinates(Point start, Point end)
        {
            var difX = Math.Abs(end.X - start.X + 1);
            var difY = Math.Abs(end.Y - start.Y + 1);
            var iterations = (difX > difY) ? difX : difY;
            for (var i = 0; i < iterations; i++)
            {
                if (difX > 0)
                {
                    difX--;
                }

                if (difY > 0)
                {
                    difY--;
                }
                yield return new Point(end.X - difX, end.Y - difY);
            }
        }
    }

    internal struct Point
    {
        public double X { get; set; }
        public double Y { get; set; }

        public Point(double x, double y)
        {
            X = x;
            Y = y;
        }
    }
}

这里的问题是,如果起点比起点比终点更远,则不起作用。

  // Start point (10, 10), end point (5, 3)
  // Actual results: 
  [2, -2]
  [3, -1]
  [4, 0]
  [5, 1]
  [5, 2]
  [5, 3]

  // Desired: 
  [10, 10]
  [9, 9]
  [8, 8]
  [7, 7]
  [6, 6]
  [5, 5]
  [5, 4]
  [5, 3]

  // If I reverse start and end points the result is as expected:
  [5, 3]
  [6, 4]
  [7, 5]
  [8, 6]
  [9, 7]
  [10, 8]
  [10, 9]
  [10, 10]

3 个答案:

答案 0 :(得分:0)

您的Math.Abs​​在确定您需要踩多少步时会失去步的方向,因此所有路径只能朝正方向前进。而是保持步进为正或负:

    public static IEnumerable<Point> Coordinates(Point start, Point end)
    {
        int difX = end.X - start.X;
        int difY = end.Y - start.Y;
        var iterations = (difX > difY) ? difX : difY;

        //reduce the stepping to either +1 or -1 for each 
        difX = difX/Math.Abs(difX);
        difY = difY/Math.Abs(difY);

        //start off one behind, because we'll increment in the loop
        int newX = start.X - difX; 
        int newY = start.Y - difY;

        //now when you loop, only apply the stepping if you didnt already reach the end
        for (var i = 0; i < iterations; i++)
        {
            //only move if we didn't reach the end
            if(newX != end.X) 
              newX += difX;
            if(newY != end.Y)
              newY += difY;

            yield return new Point(newX, newY);
        }
    }

答案 1 :(得分:0)

免责声明:未经测试!

这就是我的处理方式:

public static IEnumerable<Point> Coordinates(Point start, Point end)
{
    double dirX = start.X < end.X ? +1 : -1;
    double dirY = start.Y < end.Y ? +1 : -1;

    double x = start.X;
    double y = start.Y;

    do
    {
        if (!coordsEqual(x, end.X)) x = x+dirX;
        if (!coordsEqual(y, end.Y)) x = y+dirY;
        yield return new Point(x,y);
    }while( !shouldStop(x,y,end) );
}

static bool shouldStop( double x, double y, Point target )
{
    // Basically x == end.X && y == end.Y , just considering floating point issues.
    return coordsEqual( x, target.X ) && coordsEqual( y, target.Y );
}

static bool coordsEqual( double d1, double d2 )
{
    // TODO
}

请记住,我还要做一些工作。检查双打是否相等有很多陷阱,所以我留给您学习它们。

顺便说一句:您似乎只使用整数值。如果使用int而不是double,则检查相等性要容易得多。

答案 2 :(得分:0)

检查我们是否达到end点时的一个简单循环:

代码:

public static IEnumerable<Point> Coordinates(Point start, Point end) {
  int dx = Math.Sign(end.X - start.X);
  int dy = Math.Sign(end.Y - start.Y);
  int steps = Math.Max(Math.Abs(end.X - start.X), Math.Abs(end.Y - start.Y)) + 1; 

  int x = start.X;
  int y = start.Y;

  for (int i = 1; i <= steps; ++i) {
    yield return new Point(x, y);

    x = x == end.X ? end.X : x + dx;
    y = y == end.Y ? end.Y : y + dy;
  }
}

演示:

Console.WriteLine(string.Join(Environment.NewLine, 
  Coordinates(new Point(10, 10), new Point(5, 3))));

Console.WriteLine();

Console.WriteLine(string.Join(Environment.NewLine, 
  Coordinates(new Point(5, 3), new Point(10, 10))));

结果:

{X=10,Y=10} 
{X=9,Y=9}
{X=8,Y=8}
{X=7,Y=7}
{X=6,Y=6}
{X=5,Y=5}
{X=5,Y=4}
{X=5,Y=3}

{X=5,Y=3} 
{X=6,Y=4}
{X=7,Y=5}
{X=8,Y=6}
{X=9,Y=7}
{X=10,Y=8}
{X=10,Y=9}
{X=10,Y=10}