"Collision detection tutorial" - читать интересную книгу автора (Christopoulos Dimitrios)

Ray – Plane intersection detection

A plane is represented using its Vector representation as

Xn dot X = d

Xn, X are vectors and d is a floating point value.

Xn is its normal

X is a point on its surface

d is a float representing the distance of the plane along the normal, from the center of the coordinate system.

Essentially a plane represents a half space. So all that we need to define a plane is a 3D point and a normal from that point which is perpendicular to that plane. These two vectors form a plane, ie. if we take for the 3D point the vector (0,0,0) and for the normal (0,1,0) we essentially define a plane across x,z axes. Therefore defining a point and a normal is enough to compute the Vector representation of a plane.

Using the vector equation of the plane the normal is substituted as Xn and the 3D point from which the normal originates is substituted as X. The only value that is missing is d which can easily be computed using a dot product (from the vector equation).

(Note: This Vector representation is equivalent to the widely known parametric form of the plane Ax + By + Cz + D=0 just take the three x,y,z values of the normal as A,B,C and set D=-d).

The two equations we have until know are

PointOnRay = Raystart + t * Raydirection

Xn dot X = d

If a ray intersects the plane at some point then there must be some point on the ray which satisfies the plane equation as follows

Xn dot PointOnRay = d

or

(Xn dot Raystart) + t* (Xn dot Raydirection) = d

solving for t

t = (d – Xn dot Raystart) / (Xn dot Raydirection)

or by replacing d

t= (Xn dot PointOnRay – Xn dot Raystart) / (Xn dot Raydirection)

or by summing it up

t= (Xn dot (PointOnRay – Raystart)) / (Xn dot Raydirection)

t represents the distance from the start until the intersection point along the direction of the ray. Therefore substituting t into the ray equation we can get the collision point. There are a few special cases though.

If Xn dot Raydirection = 0 then these two vectors are perpendicular (ray runs parallel to plane) and there will be no collision. If t is negative the collision takes place behind the starting point of the ray along the opposite direction and again there is no intersection. In the code now the function

int TestIntersionPlane(const Planeamp; plane,const TVectoramp; position,const TVectoramp; direction, doubleamp; lamda, TVectoramp; pNormal) {

 double DotProduct = direction.dot(plane._Normal); //Dot product between plane normal and ray direction

 double l2;

 //Determine if ray paralle to plane

 if ((DotProduct lt; ZERO) amp;amp; (DotProduct gt; -ZERO)) return 0;

 l2=(plane._Normal.dot(plane._Position-position)) / DotProduct; //Find distance to collision point

 if (l2 lt; -ZERO) //Test if collision behind start

  return 0;

 pNormal = plane._Normal;

 lamda=l2;

 return 1;

}

It calculates and returns the intersection. Returns 1 if there is an intersection otherwise 0. The parameters are the plane, the start and direction of the vector, a double (lamda) where the collision distance is stored if there was any, and the returned normal at the collision point.