首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何从起点到终点生成坐标对?

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

Stack Overflow用户
提问于 2019-09-10 13:14:54
回答 3查看 339关注 0票数 1

我想要创建坐标对来演示两点之间的路径。首先,如果它是可用的,则函数应该创建一个对角线路径,那么剩下的坐标应该是垂直的或水平的。

我计算了两个点之间的绝对X和Y值。如果X或Y大于零,则函数会减少它并得到结果。

代码语言:javascript
复制
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;
        }
    }
}

这里的问题是,如果起点比终点更远,这是行不通的。

代码语言:javascript
复制
  // 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]
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-09-10 14:30:15

在检查是否到达end点时,使用一个简单的循环:

代码:

代码语言:javascript
复制
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;
  }
}

演示:

代码语言:javascript
复制
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))));

结果:

代码语言:javascript
复制
{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}   
票数 1
EN

Stack Overflow用户

发布于 2019-09-10 13:36:27

当你计算出你需要采取多少步骤时,你会Math.Abs,这就失去了你前进的方向,你所有的路径都只能朝着一个积极的方向前进。相反,将步进保持为积极或消极:

代码语言:javascript
复制
    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);
        }
    }
票数 0
EN

Stack Overflow用户

发布于 2019-09-10 14:00:37

免责声明:未经测试!

我就是这样做的:

代码语言:javascript
复制
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,检查相等性要容易得多。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57871642

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档