Finding the intersection of an infinite ray with a plane in 3D is an important topic in collision detection.



Task

Find the point of intersection for the infinite ray with direction   (0, -1, -1)   passing through position   (0, 0, 10)   with the infinite plane with a normal vector of   (0, 0, 1)   and which passes through [0, 0, 5].




INCLUDE "D2:REAL.ACT" ;from the Action! Tool Kit
 
DEFINE REALPTR="CARD"
TYPE VectorR=[REALPTR x,y,z]
 
PROC PrintVector(VectorR POINTER v)
  Print("(") PrintR(v.x)
  Print(",") PrintR(v.y)
  Print(",") PrintR(v.z)
  Print(")")
RETURN
 
PROC Vector(REAL POINTER vx,vy,vz VectorR POINTER v)
  v.x=vx v.y=vy v.z=vz
RETURN
 
PROC VectorSub(VectorR POINTER a,b,res)
  RealSub(a.x,b.x,res.x)
  RealSub(a.y,b.y,res.y)
  RealSub(a.z,b.z,res.z)
RETURN
 
PROC VectorDot(VectorR POINTER a,b REAL POINTER res)
  REAL tmp1,tmp2
 
  RealMult(a.x,b.x,res)
  RealMult(a.y,b.y,tmp1)
  RealAdd(res,tmp1,tmp2)
  RealMult(a.z,b.z,tmp1)
  RealAdd(tmp1,tmp2,res)
RETURN
 
PROC VectorMul(VectorR POINTER a REAL POINTER b VectorR POINTER res)
  RealMult(a.x,b,res.x)
  RealMult(a.y,b,res.y)
  RealMult(a.z,b,res.z)
RETURN
 
BYTE FUNC IsZero(REAL POINTER a)
  CHAR ARRAY s(10)
 
  StrR(a,s)
  IF s(0)=1 AND s(1)='0 THEN
    RETURN (1)
  FI
RETURN (0)
 
BYTE FUNC Intersection(VectorR POINTER
  rayVector,rayPoint,planeNormal,planePoint,result)
 
  REAL tmpx,tmpy,tmpz,prod1,prod2,prod3
  VectorR tmp
 
  Vector(tmpx,tmpy,tmpz,tmp)
 
  VectorSub(rayPoint,planePoint,tmp)
  VectorDot(tmp,planeNormal,prod1)
  VectorDot(rayVector,planeNormal,prod2)
 
  IF IsZero(prod2) THEN
    RETURN (1)
  FI
 
  RealDiv(prod1,prod2,prod3)
  VectorMul(rayVector,prod3,tmp)
  VectorSub(rayPoint,tmp,result)
RETURN (0)
 
PROC Test(VectorR POINTER rayVector,rayPoint,planeNormal,planePoint)
  BYTE res
  REAL px,py,pz
  VectorR p
 
  Vector(px,py,pz,p)
  res=Intersection(rayVector,rayPoint,planeNormal,planePoint,p)
 
  Print("Ray vector: ")
  PrintVector(rayVector) PutE()
  Print("Ray point: ")
  PrintVector(rayPoint) PutE()
  Print("Plane normal: ")
  PrintVector(planeNormal) PutE()
  Print("Plane point: ")
  PrintVector(planePoint) PutE()
 
  IF res=0 THEN
    Print("Intersection point: ")
    PrintVector(p) PutE()
  ELSEIF res=1 THEN
    PrintE("There is no intersection")
  FI
  PutE()
RETURN
 
PROC Main()
  REAL r0,r1,r5,r10,rm1    
  VectorR rayVector,rayPoint,planeNormal,planePoint
 
  Put(125) PutE() ;clear screen
 
  ValR("0",r0) ValR("1",r1) ValR("5",r5)
  ValR("10",r10) ValR("-1",rm1)
 
  Vector(r0,rm1,rm1,rayVector)
  Vector(r0,r0,r10,rayPoint)
  Vector(r0,r0,r1,planeNormal)
  Vector(r0,r0,r5,planePoint)
  Test(rayVector,rayPoint,planeNormal,planePoint)
 
  Vector(r1,r1,r0,rayVector)
  Vector(r1,r1,r0,rayPoint)
  Vector(r0,r0,r1,planeNormal)
  Vector(r5,r1,r0,planePoint)
  Test(rayVector,rayPoint,planeNormal,planePoint)
RETURN