1. -- 
  2. -- Jan & Uwe R. Zimmer, Australia, September 2019 
  3. -- 
  4.  
  5. with Ada.Numerics;                              use Ada.Numerics; 
  6. with Ada.Numerics.Generic_Elementary_Functions; 
  7. with Ada.Strings.Bounded;                       use Ada.Strings.Bounded; 
  8.  
  9. package body Vectors_xD is 
  10.  
  11.    package Real_Elementary_Functions is 
  12.      new Ada.Numerics.Generic_Elementary_Functions (Real); 
  13.    use Real_Elementary_Functions; 
  14.  
  15.    package Strings_255 is new Ada.Strings.Bounded.Generic_Bounded_Length (Max => 255); 
  16.    use Strings_255; 
  17.  
  18.    -- 
  19.  
  20.    function Image (V : Vector_xD) return String is 
  21.  
  22.       Image_String : Strings_255.Bounded_String := Strings_255.Null_Bounded_String; 
  23.  
  24.    begin 
  25.       Image_String := Image_String & '('; 
  26.       for Axes in Vector_xD'Range loop 
  27.          Image_String := Image_String & Real'Image (V (Axes)); 
  28.          if Axes /= Vector_xD'Last then 
  29.             Image_String := Image_String & ", "; 
  30.          end if; 
  31.       end loop; 
  32.       Image_String := Image_String & ')'; 
  33.       return To_String (Image_String); 
  34.    end Image; 
  35.  
  36.    -- 
  37.  
  38.    function Norm (V : Vector_xD) return Vector_xD is 
  39.  
  40.       Abs_V : constant Real := abs (V); 
  41.  
  42.    begin 
  43.       if Abs_V = 0.0 then 
  44.          return Zero_Vector_xD; 
  45.       else 
  46.          return (V * (1.0 / Abs_V)); 
  47.       end if; 
  48.    end Norm; 
  49.  
  50.    -- 
  51.  
  52.    function "*" (Scalar : Real; V : Vector_xD) return Vector_xD is 
  53.  
  54.       Scaled_V : Vector_xD; 
  55.  
  56.    begin 
  57.       for Axis in Vector_xD'Range loop 
  58.          Scaled_V (Axis) := Scalar * V (Axis); 
  59.       end loop; 
  60.       return Scaled_V; 
  61.    end "*"; 
  62.  
  63.    -- 
  64.  
  65.    function "*" (V : Vector_xD; Scalar : Real) return Vector_xD is (Scalar * V); 
  66.  
  67.    -- 
  68.  
  69.    function "/" (V : Vector_xD; Scalar : Real) return Vector_xD is ((1.0 / Scalar) * V); 
  70.  
  71.    -- 
  72.  
  73.    function "*" (V_Left, V_Right : Vector_xD) return Real is 
  74.  
  75.       Dot : Real := 0.0; 
  76.  
  77.    begin 
  78.       for Axis in Vector_xD'Range loop 
  79.          Dot := Dot + (V_Left (Axis) * V_Right (Axis)); 
  80.       end loop; 
  81.       return Dot; 
  82.    end "*"; 
  83.  
  84.    -- 
  85.  
  86.    function Angle_Between (V_Left, V_Right : Vector_xD) return Real is 
  87.  
  88.       Abs_Left  : constant Real := abs (V_Left); 
  89.       Abs_Right : constant Real := abs (V_Right); 
  90.  
  91.    begin 
  92.       if Abs_Left = 0.0 or else Abs_Right = 0.0 then 
  93.          return 0.0; 
  94.       else 
  95.          return Arccos (Real'Max (-1.0, Real'Min (1.0, (V_Left * V_Right) / (Abs_Left * Abs_Right)))); 
  96.       end if; 
  97.    end Angle_Between; 
  98.  
  99.    -- 
  100.  
  101.    function "+" (V_Left, V_Right : Vector_xD) return Vector_xD is 
  102.  
  103.       V_Result : Vector_xD; 
  104.  
  105.    begin 
  106.       for Axis in Vector_xD'Range loop 
  107.          V_Result (Axis) := V_Left (Axis) + V_Right (Axis); 
  108.       end loop; 
  109.       return V_Result; 
  110.    end "+"; 
  111.  
  112.    -- 
  113.  
  114.    function "-" (V_Left, V_Right : Vector_xD) return Vector_xD is 
  115.  
  116.       V_Result : Vector_xD; 
  117.  
  118.    begin 
  119.       for Axis in Vector_xD'Range loop 
  120.          V_Result (Axis) := V_Left (Axis) - V_Right (Axis); 
  121.       end loop; 
  122.       return V_Result; 
  123.    end "-"; 
  124.  
  125.    -- 
  126.  
  127.    function "-" (V : Vector_xD) return Vector_xD is 
  128.  
  129.       V_Result : Vector_xD; 
  130.  
  131.    begin 
  132.       for Axis in Vector_xD'Range loop 
  133.          V_Result (Axis) := -V (Axis); 
  134.       end loop; 
  135.       return V_Result; 
  136.    end "-"; 
  137.  
  138.    -- 
  139.  
  140.    function "abs" (V : Vector_xD) return Real is 
  141.  
  142.       Sum_Sqr : Real := 0.0; 
  143.  
  144.    begin 
  145.       for Axis in Vector_xD'Range loop 
  146.          Sum_Sqr := Sum_Sqr + V (Axis)**2; 
  147.       end loop; 
  148.       return Sqrt (Sum_Sqr); 
  149.    end "abs"; 
  150.  
  151.    -- 
  152.  
  153. end Vectors_xD;