我想创建坐标对,以演示两点之间的路径。首先,如果该功能可用,则该功能应绘制一条对角线路径,然后其余坐标应为垂直或水平。
我计算了两点之间的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]
答案 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}