假设我有我的第一个 Point 结构:
Point start = new Point(1, 9);
我的第二个:
Point end = new Point(4, 9);
我想得到开始和结束之间的所有点。因此,例如,我想要一个数组中的 2,9 和 3,9。.NET 是否为此内置了一些东西?
这就是我最终做的。正如@Cody Gray 在他的评论中提到的,一条线上有无限的点。因此,您需要指定要检索的点数。
我的线类:
public class Line {
public Point p1, p2;
public Line(Point p1, Point p2) {
this.p1 = p1;
this.p2 = p2;
}
public Point[] getPoints(int quantity) {
var points = new Point[quantity];
int ydiff = p2.Y - p1.Y, xdiff = p2.X - p1.X;
double slope = (double)(p2.Y - p1.Y) / (p2.X - p1.X);
double x, y;
--quantity;
for (double i = 0; i < quantity; i++) {
y = slope == 0 ? 0 : ydiff * (i / quantity);
x = slope == 0 ? xdiff * (i / quantity) : y / slope;
points[(int)i] = new Point((int)Math.Round(x) + p1.X, (int)Math.Round(y) + p1.Y);
}
points[quantity] = p2;
return points;
}
}
用法:
var line = new Line(new Point(10, 15), new Point(297, 316));
var points = line.getPoints(20);
这将返回一个由 20 个 Points 组成的 Point 数组,它们在两个端点(包括)之间均匀分布。希望有帮助!
没有内置函数,因为点之间没有点。数学上,两点之间有一条线。在计算机图形方面,可以对线条进行抗锯齿处理,因此不会四舍五入到完整的整数。
如果您正在寻找一种在两者之间创建所有整数的快速方法,我想 Bresenhams-Line-Algorithm 将是您的选择。但这不是构建到 .NET 中的,您必须自己编写代码(或采用 Matthew Watson 的实现):
http://en.wikipedia.org/wiki/Bresenham's_line_algorithm
甚至还有更快的算法可以做到这一点,但我会选择 Bresenham。
我知道自从您第一次提出这个问题以来已经有很长时间了,但我最近在寻找类似的东西并找到了这个包含伪代码的 wiki ( https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm )。
所以我用伪代码实现了一个函数来执行这个计算并将点添加到一个列表中。
public List<Point> GetPoints(Point p1, Point p2)
{
List<Point> points = new List<Point>();
// no slope (vertical line)
if (p1.X == p2.X)
{
for (double y = p1.Y; y <= p2.Y; y++)
{
Point p = new Point(p1.X, y);
points.Add(p);
}
}
else
{
// swap p1 and p2 if p2.X < p1.X
if (p2.X < p1.X)
{
Point temp = p1;
p1 = p2;
p2 = temp;
}
double deltaX = p2.X - p1.X;
double deltaY = p2.Y - p1.Y;
double error = -1.0f;
double deltaErr = Math.Abs(deltaY / deltaX);
double y = p1.Y;
for (double x = p1.X; x <= p2.X; x++)
{
Point p = new Point(x, y);
points.Add(p);
Debug.WriteLine("Added Point: " + p.X.ToString() + "," + p.Y.ToString());
error += deltaErr;
Debug.WriteLine("Error is now: " + error.ToString());
while (error >= 0.0f)
{
Debug.WriteLine(" Moving Y to " + y.ToString());
y++;
points.Add(new Point(x, y));
error -= 1.0f;
}
}
if (points.Last() != p2)
{
int index = points.IndexOf(p2);
points.RemoveRange(index + 1, points.Count - index - 1);
}
}
return points;
}
您可以使用以下代码在点之间获取。用户只需要定义两点之间要获得多少点。这里我定义为 10 分。
PointF pStart = new PointF(10, 10);
PointF pEnd = new PointF(100, 100);
PointF[] betPoints = new PointF[10];
for (int i = 1; i <= 10; i++)
{
betPoints[i].X = (Math.Abs(pStart.X - pEnd.X) / 10) * i + pEnd.X;
betPoints[i].Y = (Math.Abs(pStart.Y - pEnd.Y) / 10) * i + pEnd.Y;
}