从矢量计算相交坐标
Calculate intersecting coordinates from vector
给定一个向量(或两个点),我怎样才能得到这个向量在给定区间内相交的离散坐标?
我使用它是为了给定一条光线(矢量)我可以计算图像中这条光线相交的像素并将它们用作我的图像的索引。在 3D 的情况下,光线始终位于图像的平面中。
此外,向量来自另一个坐标系,而不是用于图像索引的坐标系,但这只是坐标系之间的缩放。
我正在寻找 3D 的解决方案,但可以接受 2D。
编辑:间隔是 2d space,所以解是这个 2d 间隔中的一组点。这将是 运行 在具有 CUDAfy.NET
的 GPU 上
你的向量 P1,P2 就是这些点:
vector := P1 + a * (P2-P1) with a in [0;1]
你的P3,P4间隔就是这些点:
interval := P3 + b * (P4 - P3) with b in [0,1]
它们相交于同一点:
vector == interval
P1 + a * (P2-P1) == P3 + b * (P4-P3)
在 2d 中,这是两个具有两个未知数的方程式 -> 可解
这是我的假设:
- 你图片的左下角是原点(坐标为
(0, 0)
的点)
- 你有一张宽度为
w
高度为 h
的图像
- 您可以将向量以线性方程的形式表示(即
y=mx+b
,其中 m
是斜率,b
是 y 轴截距)
根据这些假设,执行以下操作以找到直线与图像边缘相交的离散坐标:
/// <summary>
/// Find discreet coordinates where the line y=mx+b intersects the edges of a w-by-h image.
/// </summary>
/// <param name="m">slope of the line</param>
/// <param name="b">y-intercept of the line</param>
/// <param name="w">width of the image</param>
/// <param name="h">height of the image</param>
/// <returns>the points of intersection</returns>
List<Point> GetIntersectionsForImage(double m, double b, double w, double h)
{
var intersections = new List<Point>();
// Check for intersection with left side (y-axis).
if (b >= 0 && b <= h)
{
intersections.Add(new Point(0.0, b));
}
// Check for intersection with right side (x=w).
var yValRightSide = m * w + b;
if (yValRightSide >= 0 && yValRightSide <= h)
{
intersections.Add(new Point(w, yValRightSide));
}
// If the slope is zero, intersections with top or bottom will be taken care of above.
if (m != 0.0)
{
// Check for intersection with top (y=h).
var xValTop = (h - b) / m;
if (xValTop >= 0 && xValTop <= w)
{
intersections.Add(new Point(xValTop, h));
}
// Check for intersection with bottom (y=0).
var xValBottom = (0.0 - b) / m;
if (xValBottom >= 0 && xValBottom <= w)
{
intersections.Add(new Point(xValBottom, 0));
}
}
return intersections;
}
以下是确保其有效的测试:
[TestMethod]
public void IntersectingPoints_AreCorrect()
{
// The line y=x intersects a 1x1 image at points (0, 0) and (1, 1).
var results = GetIntersectionsForImage(1.0, 0.0, 1.0, 1.0);
foreach (var p in new List<Point> { new Point(0.0, 0.0), new Point(1.0, 1.0) })
{
Assert.IsTrue(results.Contains(p));
}
// The line y=1 intersects a 2x2 image at points (0, 1), and (2, 1).
results = GetIntersectionsForImage(0.0, 1.0, 2.0, 2.0);
foreach (var p in new List<Point> { new Point(0.0, 1.0), new Point(2.0, 1.0) })
{
Assert.IsTrue(results.Contains(p));
}
}
经过一番搜索,我发现 Bresenham 的线算法或多或少正是我所需要的。
如果对我使用的算法感兴趣,请参考this answer
给定一个向量(或两个点),我怎样才能得到这个向量在给定区间内相交的离散坐标?
我使用它是为了给定一条光线(矢量)我可以计算图像中这条光线相交的像素并将它们用作我的图像的索引。在 3D 的情况下,光线始终位于图像的平面中。
此外,向量来自另一个坐标系,而不是用于图像索引的坐标系,但这只是坐标系之间的缩放。
我正在寻找 3D 的解决方案,但可以接受 2D。
编辑:间隔是 2d space,所以解是这个 2d 间隔中的一组点。这将是 运行 在具有 CUDAfy.NET
的 GPU 上你的向量 P1,P2 就是这些点:
vector := P1 + a * (P2-P1) with a in [0;1]
你的P3,P4间隔就是这些点:
interval := P3 + b * (P4 - P3) with b in [0,1]
它们相交于同一点:
vector == interval
P1 + a * (P2-P1) == P3 + b * (P4-P3)
在 2d 中,这是两个具有两个未知数的方程式 -> 可解
这是我的假设:
- 你图片的左下角是原点(坐标为
(0, 0)
的点) - 你有一张宽度为
w
高度为h
的图像
- 您可以将向量以线性方程的形式表示(即
y=mx+b
,其中m
是斜率,b
是 y 轴截距)
根据这些假设,执行以下操作以找到直线与图像边缘相交的离散坐标:
/// <summary>
/// Find discreet coordinates where the line y=mx+b intersects the edges of a w-by-h image.
/// </summary>
/// <param name="m">slope of the line</param>
/// <param name="b">y-intercept of the line</param>
/// <param name="w">width of the image</param>
/// <param name="h">height of the image</param>
/// <returns>the points of intersection</returns>
List<Point> GetIntersectionsForImage(double m, double b, double w, double h)
{
var intersections = new List<Point>();
// Check for intersection with left side (y-axis).
if (b >= 0 && b <= h)
{
intersections.Add(new Point(0.0, b));
}
// Check for intersection with right side (x=w).
var yValRightSide = m * w + b;
if (yValRightSide >= 0 && yValRightSide <= h)
{
intersections.Add(new Point(w, yValRightSide));
}
// If the slope is zero, intersections with top or bottom will be taken care of above.
if (m != 0.0)
{
// Check for intersection with top (y=h).
var xValTop = (h - b) / m;
if (xValTop >= 0 && xValTop <= w)
{
intersections.Add(new Point(xValTop, h));
}
// Check for intersection with bottom (y=0).
var xValBottom = (0.0 - b) / m;
if (xValBottom >= 0 && xValBottom <= w)
{
intersections.Add(new Point(xValBottom, 0));
}
}
return intersections;
}
以下是确保其有效的测试:
[TestMethod]
public void IntersectingPoints_AreCorrect()
{
// The line y=x intersects a 1x1 image at points (0, 0) and (1, 1).
var results = GetIntersectionsForImage(1.0, 0.0, 1.0, 1.0);
foreach (var p in new List<Point> { new Point(0.0, 0.0), new Point(1.0, 1.0) })
{
Assert.IsTrue(results.Contains(p));
}
// The line y=1 intersects a 2x2 image at points (0, 1), and (2, 1).
results = GetIntersectionsForImage(0.0, 1.0, 2.0, 2.0);
foreach (var p in new List<Point> { new Point(0.0, 1.0), new Point(2.0, 1.0) })
{
Assert.IsTrue(results.Contains(p));
}
}
经过一番搜索,我发现 Bresenham 的线算法或多或少正是我所需要的。
如果对我使用的算法感兴趣,请参考this answer