Is this plane-ray intersection code correct?

2019-05-12 05:54发布

问题:

My Plane class has two fields:

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

This is the code I use for intersection, and I don't know if it is correct. I double checked my equations and everything, but I would like to get feedback from people more experienced with this.

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;
}

Also, I am not sure what to do if t is close to 0? Should I check with epsilon and how big should epsilon be? Also I am not sure if I check correctly whether the ray intersects the plane from in or out?

Thanks

回答1:

You're code looks mostly fine, see this slide. Since your plane is essentially defined as the set of rays which start at a particular point (which is encapsulate in the offset parameter) and are orthogonal to the normal vector, you just need to plug in the definition for a point on the viewing ray in order to determine which point on the viewing ray defines such an orthogonal ray.

The problem will be if your viewing ray is in the plane. In this case, the viewing ray and the normal ray will be orthogonal so their dot product will be 0 and the you'll get a divide-by-0 exception. You'll need to check for that in advance: if the dot product of the viewing vector and the normal is 0, then it means the viewing ray is parallel to the plane so there either is no intersection, or there are an infinite number of intersections (the ray is inside the plane). Either way, I think for ray tracing you would generally just say there's no point of intersection (i.e., nothing to render), because in the latter case, you're looking at a two-dimensional flat surface exactly head on, so you wouldn't see anything.

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.