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