【问题标题】:How to draw a line in 3D space across a grid with a start point and direction vector如何在具有起点和方向矢量的网格中绘制 3D 空间中的线
【发布时间】:2012-11-28 21:19:55
【问题描述】:

我正在开发一款第一人称 3D 游戏。关卡完全基于立方体,墙壁/地板/等都只是平铺的立方体 (1x1x1)。

我目前正在使用相机位置和相机旋转来创建射线以获取方向。然后我想将光线投射到第一个不为空的立方体上(或者当光线从网格上掉下来时)。通常,这些是方向向量,例如 0,0,1 或 1,0,0。

在找到适用于方向矢量而不是起点/终点的 Bresenham 线条绘制算法时,我运气不佳。特别是考虑到方向向量不仅仅包含整数。

所以,对于一个特定的问题,我想我想问是否有人可以解释我是否接近以正确的方式解决这个问题,以及是否有人可能会详细说明无论如何应该如何完成。

【问题讨论】:

    标签: c# line raytracing bresenham


    【解决方案1】:

    Bresenham 在这里帮不了你,恐怕......你需要的是 Ray/Line-Plane 相交算法:

    在非常粗略的数学伪代码中:

    (警告:我已经很久没有做 3d 图形了)

    // Ray == origin point + some distance in a direction
    myRay = Porg + t*Dir;
    
    // Plane == Some point on cube face * normal of cube face (facing out),
    // at some distance from origin
    myPlane = Pcube * Ncubeface - d;
    
    // Straight shot: from ray origin to point on cube direction
    straightTo = (Pcube - Porg);
    

    通过这两个方程,你可以推断出一些事情:

    • 如果 'straightTo' 和平面法线的点积为零(称为“angA”),则您的原点在立方体的面内。

    • 如果光线方向和平面法线的点积接近于 0(称为“angB”),则光线平行于立方体的面——也就是说,不相交(除非你如果原点在上面的立方体面中,则计数)。

    • 如果 (-angA / angB)

    还有其他东西,但我已经在逼迫我微薄的记忆力了。 :)

    编辑: 可能有一个“捷径”,现在我觉得它虽然有点......这都是假设你正在为你的“地图”使用类似 3-d 数组的结构。

    好的,请耐心等待,在我的手机上思考和打字 - 如果您使用标准的旧 Bresenham delta-error 算法,但将其“固定”为 2D 会怎样?

    那么让我们说:

    • 我们在 (10x10x10)“盒子”中的位置 (5, 5, 5)
    • 我们指向 (1 0 0)(即 +X 轴)
    • 从我们视锥体左上角投射的光线仍然只是一条线; “x”和“y”的定义发生了变化,全部
    • 在这种情况下,“X”将是(心理可视化)...比如沿着平行于眼线的轴,但与投射线齐平;也就是说,如果我们正在查看 (640x480) 的 2D 图像,“中心”是 (0,0),左上角是 (-320,-240),那么这条“X 轴线”将是一条线通过点 (-320,0) 投射到无穷远。
    • “Y”同样是正常“Y”轴的投影,所以...几乎相同,除非我们歪着头。
    • 现在,当试图找出下一个 deltaX 值是多少时,数学会变得非常棘手,但是一旦你弄清楚了公式,它基本上就是常数时间计算(现在我想它,“X 轴”只是通过您的相机投影投影的矢量 ,对吧?

    抱歉,我在回家的火车上。 ;)

    【讨论】:

    • 重读时,如果我没记错的话,我可能应该叫“angA”和“angB”“cosAngA”和“cosAngB”……
    • 潜在的建议是遍历整个游戏世界中的所有立方体以找出玩家正在查看的立方体,比较碰撞距离吗?如果是这样的话,一个简单的 ray to aabb 测试听起来更容易。我想我可以使用播放器中的泛洪填充技术来查看 X 距离内的立方体,但我真的认为会有一个简单的 3D 光线投射算法,不需要整个其他数据结构或任何东西。跨度>
    • @TimWinter - 你可以做一些优化。就像将你的立方体划分成巨型立方体,并找出它击中了哪个巨型立方体,然后更深入。这是一个非常广泛的话题。如果你有时间的话,谷歌“光线追踪”。
    • @TimWinter - 是的,这几乎是四叉树和类似“最近邻”分区方案的主要用例。
    猜你喜欢
    • 2020-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多