-- $Date: 2004/01/11 00:59:06 $
-- $Revision: 1.10 $
-- $Author: jcrocholl $

with Real_Numbers; use Real_Numbers;
with Real_Vectors; use Real_Vectors;
with Lines; use Lines;

-- Cubic bezier curves.
package Cubics is

   -- Cubic bezier curve. Extends Line with two control points.
   type Cubic_Record is new Line_Record with record
      Control_A, Control_B : Vector;
   end record;

   -- Access type for cubic bezier curves.
   type Cubic is access Cubic_Record;

   -- Create a cubic bezier curve.
   function Create
     (To        : in Vector-- End point of the curve.
      Control_A : in Vector-- First control point of curve.
      Control_B : in Vector-- Second control point of curve.
     return Line;            -- The newly created curve.

   -- Calculate the arc length of this curve. Results are cached for
   -- reuse. So make sure the starting point always remains the same
   -- between calls.
   function Length
     (Start : in Vector;           -- Starting point of the curve.
      This  : access Cubic_Record-- Get this curve's arc length.
     return Real;                  -- The length of the arc.

   -- Scale a curve by a given factor.
   procedure Scale
     (This   : access Cubic_Record-- Scale this curve.
      Factor : in Real);            -- Scaling factor.

   -- Translate a curve by a given offset.
   procedure Translate
     (This   : access Cubic_Record-- Translate this curve.
      Offset : in Vector);          -- Translating offset.

   -- Get one point from the cubic bezier curve.
   function Way_Point
     (Start : in Vector;           -- Starting point of the curve.
      This  : access Cubic_Record-- Definition of the curve.
      Part  : in Real)             -- Parametrization variable from 0 to 1.
     return Vector;                -- The point on the curve.

   -- Create a cubic bezier curve that goes through 4 given points.
   function Make_Cubic_Through_Points
     (F0 : in Vector-- Starting point.
      F1 : in Vector-- Go through this inner point at t=1/3.
      F2 : in Vector-- Go through this inner point at t=2/3.
      F3 : in Vector-- End point.
     return Line;     -- The newly created cubic bezier curve.

   -- Create a cubic bezier curve by joining two adjacent lines.
   -- Output value Error is the maximum distance between the original
   -- lines and the newly created curve.
   procedure Make_Cubic
     (Start  : in Vector-- Starting vector.
      A, B   : in Line;   -- Two adjacent lines.
      Result : out Line;  -- The new cubic bezier curve.
      Error  : out Real); -- The maximum error.

   -- Format a cubic bezier curve for postscript output.
   function Postscript
     (This : access Cubic_Record-- Format this curve.
     return String;               -- The resulting postscript code.

end Cubics;