3

我的 Plane 课程有两个字段:

public Vector3 Norm; //normal vector 
public double Offset; //signed distance to origin

这是我用于交集的代码,不知道是否正确。我仔细检查了我的方程式和所有内容,但我想从对此更有经验的人那里获得反馈。

public override Intersection Intersect(Ray ray)
{
    // Create Intersection.
    Intersection result = new Intersection();

    // Find t.
    double t = - (Vector3.Dot(Norm,ray.Start) + Offset) / (Vector3.Dot(Norm, ray.Dir));
    if (t < 0) // the ray does not hit the surface, that is, the surface is "behind" the ray
        return null;

    // Get a point on the plane.
    Vector3 p = ray.Start + t * ray.Dir;

    // Does the ray intersect the plane inside or outside?
    Vector3 planeToRayStart = ray.Start - p;
    double dot = Vector3.Dot (planeToRayStart, Norm);
    if (dot > 0) {
        result.Inside = false;
    } else {
        result.Inside = true;
    }

    result.Dist = t;
    return result;
}

另外,如果 t 接近 0,我不确定该怎么办?我应该检查 epsilon 以及 epsilon 应该有多大?另外我不确定我是否正确检查光线是否从内或外与平面相交?

谢谢

4

1 回答 1

2

您的代码看起来大部分都很好,请参阅这张幻灯片。由于您的平面本质上定义为从特定点开始的一组光线(封装在偏移参数中)并且与法线向量正交,因此您只需将定义插入查看光线上的点为了确定观察光线上的哪个点定义了这样的正交光线。

问题将是您的视线是否在平面内。在这种情况下,观察光线和法线光线将是正交的,因此它们的点积将为 0,您将得到除以 0 的异常。您需要提前检查:如果观察向量与法线的点积为 0,则表示观察光线平行于平面,因此要么没有相交,要么存在无限多交叉点(射线在平面内)。无论哪种方式,我认为对于光线追踪,您通常只会说没有交点(即,没有要渲染的内容),因为在后一种情况下,您正在查看一个二维平面,因此您不会什么都看不见。

I don't see any reason you need to specially handle "close to 0". Either the ray is parallel to the plane and there's nothing to render, or it's not and it intersects the plane at exactly one point. You'll get into floating point rounding errors eventually, but this is just a small source of error in your rendering which is only an approximation of the scene anyway. As long as you keep your dimensions reasonably large, the floating point errors should be insubstantial.

于 2012-12-04T13:36:16.497 回答