c# - C# 中线段与轴对齐框的交点

标签 c# 3d

我正在寻找一种算法来确定线段和轴对齐框之间的近交点和远交点。

这是我的方法定义:

public static Point3D[] IntersectionOfLineSegmentWithAxisAlignedBox(
    Point3D rayBegin, Point3D rayEnd, Point3D boxCenter, Size3D boxSize)

如果线段不与框相交,该方法应返回一个空的 Point3D 数组。

到目前为止,根据我的研究,我发现了一些具有高度优化算法的研究论文,但它们似乎都是用 C++ 编写的,并且需要将多个长类文件转换为 C#。就我的目的而言,优先考虑的是合理有效、获得点积和叉积的人易于理解并且简单/简短的东西。

最佳答案

这是我最终使用的:

public static List<Point3D> IntersectionOfLineSegmentWithAxisAlignedBox(
    Point3D segmentBegin, Point3D segmentEnd, Point3D boxCenter, Size3D boxSize)
{
    var beginToEnd = segmentEnd - segmentBegin;
    var minToMax = new Vector3D(boxSize.X, boxSize.Y, boxSize.Z);
    var min = boxCenter - minToMax / 2;
    var max = boxCenter + minToMax / 2;
    var beginToMin = min - segmentBegin;
    var beginToMax = max - segmentBegin;
    var tNear = double.MinValue;
    var tFar = double.MaxValue;
    var intersections = new List<Point3D>();
    foreach (Axis axis in Enum.GetValues(typeof(Axis)))
    {
        if (beginToEnd.GetCoordinate(axis) == 0) // parallel
        {
            if (beginToMin.GetCoordinate(axis) > 0 || beginToMax.GetCoordinate(axis) < 0)
                return intersections; // segment is not between planes
        }
        else
        {
            var t1 = beginToMin.GetCoordinate(axis) / beginToEnd.GetCoordinate(axis);
            var t2 = beginToMax.GetCoordinate(axis) / beginToEnd.GetCoordinate(axis);
            var tMin = Math.Min(t1, t2);
            var tMax = Math.Max(t1, t2);
            if (tMin > tNear) tNear = tMin;
            if (tMax < tFar) tFar = tMax;
            if (tNear > tFar || tFar < 0) return intersections;

        }
    }
    if (tNear >= 0 && tNear <= 1) intersections.Add(segmentBegin + beginToEnd * tNear);
    if (tFar >= 0 && tFar <= 1) intersections.Add(segmentBegin + beginToEnd * tFar);
    return intersections;
}

public enum Axis
{
    X,
    Y,
    Z
}

public static double GetCoordinate(this Point3D point, Axis axis)
{
    switch (axis)
    {
        case Axis.X:
            return point.X;
        case Axis.Y:
            return point.Y;
        case Axis.Z:
            return point.Z;
        default:
            throw new ArgumentException();
    }
}

public static double GetCoordinate(this Vector3D vector, Axis axis)
{
    switch (axis)
    {
        case Axis.X:
            return vector.X;
        case Axis.Y:
            return vector.Y;
        case Axis.Z:
            return vector.Z;
        default:
            throw new ArgumentException();
    }
}

关于c# - C# 中线段与轴对齐框的交点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3106666/

相关文章:

c# - 如何在 Spinner 中选择项目并将其用作字符串?

c# - 在 C# 中,如何从第一个类调用第二个类中的方法?

c# - 为什么我在使用 File.Copy() 时看到 IO 异常,该异常似乎来自读取文件?

javascript - 将 3D 点转换为 2D 点?

c# - 普通旧 CLR 对象与数据传输对象

c# - 在 C# 中将项目添加到 ListView 太慢

javascript - 你如何检测 three.js 中粒子系统中的粒子悬停?

algorithm - 3D 平面拟合算法

opengl - 如何将子弹物理应用于绘制的 Opengl 3d 形状

math - 如何计算正切和副法线?