我想要创建坐标对来演示两点之间的路径。首先,如果它是可用的,则函数应该创建一个对角线路径,那么剩下的坐标应该是垂直的或水平的。
我计算了两个点之间的绝对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]发布于 2019-09-10 14:30:15
在检查是否到达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} 发布于 2019-09-10 13:36:27
当你计算出你需要采取多少步骤时,你会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);
}
}发布于 2019-09-10 14:00:37
免责声明:未经测试!
我就是这样做的:
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,检查相等性要容易得多。
https://stackoverflow.com/questions/57871642
复制相似问题