DEFINITION MODULE Vector;

(*
    Title: 	vectors, segment, and boxes
    LastEdit:	"Tue Feb 19 16:55:14 1985"
    Author: 	jd
		Cambridge University Computer Laboratory
*)


EXPORT QUALIFIED
    AXIS, BOUND, RVEC, IVEC, RSEG, ISEG, RBOX, IBOX,
    Orthogonal, Opposite, Left, Right, 

    RSeg, ISeg, RSize, ISize,
    RInClosed, IInClosed, RInOpen, IInOpen, RIntersect, IIntersect, 

    RVec, IVec, REqual, IEqual, RAdd, IAdd, RSubtract, ISubtract,
    RDistance, IDistance, RLength, RSetLength,

    RBox, IBox, RBoxSeg, IBoxSeg, RSetBoxSeg, ISetBoxSeg, RInBox, IInBox;

TYPE
    AXIS = (X, Y);
    BOUND = (Low, High);
    
    (*     REAL and INTEGER vectors *)

    RVEC = ARRAY AXIS OF REAL;
    IVEC = ARRAY AXIS OF INTEGER;
    
    (*     REAL and INTEGER segments *)

    RSEG = ARRAY BOUND OF REAL;
    ISEG = ARRAY BOUND OF INTEGER;
    
    (*     REAL and INTEGER boxes *)

    RBOX = ARRAY BOUND OF RVEC;
    IBOX = ARRAY BOUND OF IVEC;

        (* DIRECTIONS *)

PROCEDURE Orthogonal (z: AXIS): AXIS;
PROCEDURE Opposite (b: BOUND): BOUND;
PROCEDURE Left (VAR z: AXIS; VAR b: BOUND);
PROCEDURE Right (VAR z: AXIS; VAR b: BOUND);

        (* INTERVALS *)

PROCEDURE RSeg (a, b: REAL; VAR s: RSEG);
PROCEDURE ISeg (a, b: INTEGER; VAR s: ISEG);
    (* define the line segment with s [Low] <= s [High] *)

PROCEDURE RSize (VAR s: RSEG): REAL;
PROCEDURE ISize (VAR s: ISEG): INTEGER;
    (* s [High] - s [Low] *)

PROCEDURE RInClosed (p: REAL; VAR s: RSEG): BOOLEAN;
PROCEDURE IInClosed (p: INTEGER; VAR s: ISEG): BOOLEAN;
    (* TRUE iff p lies in the closed interval defined by s *)

PROCEDURE RInOpen (p: REAL; VAR s: RSEG): BOOLEAN;
PROCEDURE IInOpen (p: INTEGER; VAR s: ISEG): BOOLEAN;
    (* TRUE iff p lies in the open interval defined by s *)

PROCEDURE RIntersect (VAR s1, s2, intersection: RSEG): BOOLEAN;
PROCEDURE IIntersect (VAR s1, s2, intersection: ISEG): BOOLEAN;
    (* the interval which is the intersection of s1 and s2
       FALSE is returned if the intersection is empty
    *)

        (* VECTORS *)

PROCEDURE RVec (VAR v: RVEC; x, y: REAL);
PROCEDURE IVec (VAR v: IVEC; x, y: INTEGER);
    (* define a vector *)

PROCEDURE REqual (VAR v1, v2: RVEC; epsilon: REAL): BOOLEAN;
PROCEDURE IEqual (VAR v1, v2: IVEC): BOOLEAN;
    (* where epsilon is the maximum allowable difference in each axis *)

PROCEDURE RAdd (VAR v, to: RVEC);
PROCEDURE IAdd (VAR v, to: IVEC);

PROCEDURE RSubtract (VAR v, from: RVEC);
PROCEDURE ISubtract (VAR v, from: IVEC);

PROCEDURE RDistance (VAR v1, v2: RVEC): REAL;
    (* the Euclidean distance between v1 and v2 *)
PROCEDURE IDistance (VAR v1, v2: IVEC): CARDINAL;
    (* the Manhattan distance between v1 and v2 *)

PROCEDURE RLength (VAR v: RVEC): REAL;
PROCEDURE RSetLength (VAR v: RVEC; l: REAL);
    (* considering v as a vector from the origin *)

        (* Boxes *)

PROCEDURE RBox (VAR b: RBOX; lx, ly, hx, hy: REAL);
PROCEDURE IBox (VAR b: IBOX; lx, ly, hx, hy: INTEGER);
    (* define a box *)

PROCEDURE RBoxSeg (VAR b: RBOX; z: AXIS; VAR s: RSEG);
PROCEDURE IBoxSeg (VAR b: IBOX; z: AXIS; VAR s: ISEG);
    (* returns the interval of the given dimension of the box *)

PROCEDURE RSetBoxSeg (VAR of: RBOX; z: AXIS; VAR s: RSEG);
PROCEDURE ISetBoxSeg (VAR of: IBOX; z: AXIS; VAR s: ISEG);
    (* sets the interval of the given dimension of the box *)

PROCEDURE RInBox (VAR v: RVEC; VAR b: RBOX): BOOLEAN;
PROCEDURE IInBox (VAR v: IVEC; VAR b: IBOX): BOOLEAN;
    (* TRUE iff point in box (InClosed in both dimensions) *)

END Vector.
