Task: Find the intersection of a line with a plane








VB: Module Module1

    Class Vector3D
        Private ReadOnly x As Double
        Private ReadOnly y As Double
        Private ReadOnly z As Double

        Sub New(nx As Double, ny As Double, nz As Double)
            x = nx
            y = ny
            z = nz
        End Sub

        Public Function Dot(rhs As Vector3D) As Double
            Return x * rhs.x + y * rhs.y + z * rhs.z
        End Function

        Public Shared Operator +(ByVal a As Vector3D, ByVal b As Vector3D) As Vector3D
            Return New Vector3D(a.x + b.x, a.y + b.y, a.z + b.z)
        End Operator

        Public Shared Operator -(ByVal a As Vector3D, ByVal b As Vector3D) As Vector3D
            Return New Vector3D(a.x - b.x, a.y - b.y, a.z - b.z)
        End Operator

        Public Shared Operator *(ByVal a As Vector3D, ByVal b As Double) As Vector3D
            Return New Vector3D(a.x * b, a.y * b, a.z * b)
        End Operator

        Public Overrides Function ToString() As String
            Return String.Format("({0:F}, {1:F}, {2:F})", x, y, z)
        End Function
    End Class

    Function IntersectPoint(rayVector As Vector3D, rayPoint As Vector3D, planeNormal As Vector3D, planePoint As Vector3D) As Vector3D
        Dim diff = rayPoint - planePoint
        Dim prod1 = diff.Dot(planeNormal)
        Dim prod2 = rayVector.Dot(planeNormal)
        Dim prod3 = prod1 / prod2
        Return rayPoint - rayVector * prod3
    End Function

    Sub Main()
        Dim rv = New Vector3D(0.0, -1.0, -1.0)
        Dim rp = New Vector3D(0.0, 0.0, 10.0)
        Dim pn = New Vector3D(0.0, 0.0, 1.0)
        Dim pp = New Vector3D(0.0, 0.0, 5.0)
        Dim ip = IntersectPoint(rv, rp, pn, pp)
        Console.WriteLine("The ray intersects the plane at {0}", ip)
    End Sub

End Module




Ada: with Ada.Numerics.Generic_Real_Arrays;
with Ada.Text_IO;

procedure Intersection is

   type Real is new Long_Float;

   package Real_Arrays is
      new Ada.Numerics.Generic_Real_Arrays (Real => Real);
   use Real_Arrays;

   package Real_IO is
      new Ada.Text_IO.Float_IO (Num => Real);

   subtype Vector_3D is Real_Vector (1 .. 3);

   function Line_Plane_Intersection (Line_Vector  : in Vector_3D;
                                     Line_Point   : in Vector_3D;
                                     Plane_Normal : in Vector_3D;
                                     Plane_Point  : in Vector_3D)
                                    return Vector_3D
   is
      Diff  : constant Vector_3D := Line_Point - Plane_Point;
      Denom : constant Real      := Line_Vector * Plane_Normal;
   begin
      if Denom = 0.0 then
         raise Constraint_Error with "Line does not intersect plane";
      end if;
      declare
         Scale : constant Real :=
           -Real'(Diff * Plane_Normal) / Denom;
         Point : constant Vector_3D :=
           Diff + Plane_Point + Scale * Line_Vector;
      begin
         return Point;
      end;
   end Line_Plane_Intersection;

   procedure Put (V : in Vector_3D) is
      use Ada.Text_IO, Real_IO;
   begin
      Put ("(");
      Put (V (1));  Put (",");
      Put (V (2));  Put (",");
      Put (V (3));  Put (")");
   end Put;

begin
   Real_IO.Default_Exp := 0;
   Real_IO.Default_Aft := 3;

   Put (Line_Plane_Intersection (Line_Vector  => (0.0, -1.0, -1.0),
                                 Line_Point   => (0.0,  0.0, 10.0),
                                 Plane_Normal => (0.0,  0.0,  1.0),
                                 Plane_Point  => (0.0,  0.0,  5.0)));
end Intersection;