------------------------------------------------------------------ -- -- NAME: DC_POINT_OPS - BODY -- DISCREPANCY REPORTS: ------------------------------------------------------------------ -- File: DC_POINT_OPS_B.ADA -- Level: all package body DC_POINT_OPS is use GKS_TYPES; use DC; function SQRT (X : in FLOAT) return FLOAT is -- Compute the square root of X. -- Normally, a square root function would test for X < 0.0, but this -- function is never called with a negative number here. -- -- X - positive number to take the square root of -- -- Implementation note: This function uses FLOAT because the -- difference R - R0 could be zero (truncation effects, or just -- luck). -- This implementation is based on Newton-Raphson iteration for the -- roots of the function F(R) = R**2 - X. -- The Newton-Raphson iteration is: -- R' := R - F(R)/F'(R) -- Substituting F(R) = R**2 - X, and F'(R) = 2*R we get: -- R' := R - (R**2 - X)/(2*R) -- Rearranging: -- R' := R - (R**2 / R - X / R) / 2 -- R' := R - (R - X / R) / 2 -- R' := (R * 2 - R + X / R) / 2 -- R' := (R + X / R) / 2 -- Strength reduction, multiply instead of divide, yields: -- R' := (R + X/R) * 0.5 R0 : FLOAT := 1.0; -- Previous guess at square root R : FLOAT := X; -- Next quess at square root begin while abs ((R - R0) / R) > 0.000001 loop R0 := R; R := (R + X / R) * 0.5; end loop; return R; end SQRT; function SQRT (X : in MAGNITUDE) return MAGNITUDE is -- Square root of a MAGNITUDE (which is always positive) -- -- X - MAGNITUDE to take the square root of begin return MAGNITUDE ( FLOAT' ( SQRT ( FLOAT(X) ) ) ); end SQRT; function DOT (A : in VECTOR; B : in VECTOR) return COORD is -- DOT product is sum of product of components -- -- A - first vector of DOT product -- B - second vector of DOT product begin return (A.X * B.X) + (A.Y * B.Y); end DOT; function NORM (A : in VECTOR) return MAGNITUDE is -- DR078 -- Return Euclidean length of a VECTOR as a MAGNITUDE -- -- A - VECTOR whose length is sought begin return SQRT ( DC . MAGNITUDE ( DOT (A,A) ) ); -- This is a simple algorithm. Better numerical accuracy and -- greater functional domain can be had, but graphics do not -- require it. end NORM; function NORM (A : in VECTOR) return COORD is -- DR078 -- Return Euclidean length of a VECTOR as a COORD -- -- A - VECTOR whose length is sought begin return COORD ( MAGNITUDE' ( NORM(A) ) ); end NORM; function DIST (A : in POINT; B : in POINT) return MAGNITUDE is -- Return Euclidean distance between two point as a MAGNITUDE -- -- A - Starting point -- B - Ending point begin return NORM ( VECTOR' (A - B) ); end DIST; function DIST (A : in POINT; B : in POINT) return COORD is -- Return Euclidean distance between two point as a COORD -- -- A - Starting point -- B - Ending point begin return NORM ( VECTOR' (A - B) ); end DIST; -- Scalar operations: VECTOR and COORD function "*" (V : in VECTOR; -- DR078 S : in COORD) return VECTOR is -- DR078 -- Multiply a VECTOR by a COORD -- -- V - Vector to be multiplied -- S - Scalar to multiply vector by begin return VECTOR '( V.X * S, V.Y * S); end "*"; function "*" (S : in COORD; -- DR078 V : in VECTOR) return VECTOR is -- DR078 -- Multiply a COORD by a VECTOR -- -- S - Scalar to multiply vector by -- V - Vector to be multiplied begin return VECTOR '( S * V.X, S * V.Y); end "*"; function "/" (V : in VECTOR; -- DR078 S : in COORD) return VECTOR is -- DR078 -- Divide a VECTOR by a COORD -- -- V - Vector to be divided -- S - Scalar to divide vector by begin return VECTOR '( V.X / S, V.Y / S); end "/"; -- Scalar operations: POINT and COORD function "*" (P : in POINT; -- DR078 S : in COORD) return POINT is -- DR078 -- Multiply a POINT by a COORD -- -- P - POINT to be multiplied -- S - Scalar to multiply POINT by begin return POINT '( P.X * S, P.Y * S); end "*"; function "*" (S : in COORD; -- DR078 P : in POINT) return POINT is -- DR078 -- Multiply a COORD by a POINT -- -- S - Scalar to multiply POINT by -- P - POINT to be multiplied begin return POINT '( S * P.X, S * P.Y); end "*"; function "/" (P : in POINT; -- DR078 S : in COORD) return POINT is -- DR078 -- Divide a POINT by a COORD -- -- P - POINT to be divided -- S - Scalar to divide POINT by begin return POINT '( P.X / S, P.Y / S); end "/"; -- Scalar operations: VECTOR and MAGNITUDE function "*" (V : in VECTOR; -- DR078 S : in MAGNITUDE) return VECTOR is -- DR078 -- Multiply a VECTOR by a MAGNITUDE -- -- V - Vector to be multiplied -- S - Scalar to multiply vector by C : COORD := COORD ( S ); -- Convert S to a COORD begin return VECTOR '( V.X * C, V.Y * C); end "*"; function "*" (S : in MAGNITUDE; -- DR078 V : in VECTOR) return VECTOR is -- DR078 -- Multiply a MAGNITUDE by a VECTOR -- -- S - Scalar to multiply vector by -- V - Vector to be multiplied C : COORD := COORD ( S ); -- Convert S to a COORD begin return VECTOR '( C * V.X, C * V.Y); end "*"; function "/" (V : in VECTOR; -- DR078 S : in MAGNITUDE) return VECTOR is -- DR078 -- Divide a VECTOR by a MAGNITUDE -- -- V - Vector to be divided -- S - Scalar to divide vector by C : COORD := COORD ( S ); -- Convert S to a COORD begin return VECTOR '( V.X / C, V.Y / C); end "/"; -- Scalar operations: POINT and MAGNITUDE function "*" (P : in POINT; -- DR078 S : in MAGNITUDE) return POINT is -- DR078 -- Multiply a POINT by a MAGNITUDE -- -- P - POINT to be multiplied -- S - Scalar to multiply POINT by C : COORD := COORD ( S ); -- Convert S to a COORD begin return POINT '( P.X * C, P.Y * C); end "*"; function "*" (S : in MAGNITUDE; -- DR078 P : in POINT) return POINT is -- DR078 -- Multiply a MAGNITUDE by a POINT -- -- S - Scalar to multiply POINT by -- P - POINT to be multiplied C : COORD := COORD ( S ); -- Convert S to a COORD begin return POINT '( C * P.X, C * P.Y); end "*"; function "/" (P : in POINT; -- DR078 S : in MAGNITUDE) return POINT is -- DR078 -- Divide a POINT by a MAGNITUDE -- -- P - POINT to be divided -- S - Scalar to divide POINT by C : COORD := COORD ( S ); -- Convert S to a COORD begin return POINT '( P.X / C, P.Y / C); end "/"; -- -- VECTOR op VECTOR ==> VECTOR -- function "-" ( A : in VECTOR) return VECTOR is -- DR078 -- Negate a VECTOR -- -- A - a VECTOR begin return VECTOR '( -A.X, -A.Y); end "-"; function "-" (A : in VECTOR; -- DR078 B : in VECTOR) return VECTOR is -- DR078 -- Subtract two VECTORs -- -- A - a VECTOR -- B - a VECTOR to subtract from `A' begin return VECTOR '( A.X - B.X, A.Y - B.Y); end "-"; function "+" (A : in VECTOR; -- DR078 B : in VECTOR) return VECTOR is -- DR078 -- Add two VECTORs -- -- A - a VECTOR -- B - a VECTOR to add to `A' begin return VECTOR '( A.X + B.X, A.Y + B.Y); end "+"; function "*" (A : in VECTOR; -- DR078 B : in VECTOR) return VECTOR is -- DR078 -- Multiply two VECTORs -- -- A - a VECTOR -- B - a VECTOR to multiply `A' by (component-wise) begin return VECTOR '( A.X * B.X, A.Y * B.Y); end "*"; function "/" (A : in VECTOR; -- DR078 B : in VECTOR) return VECTOR is -- DR078 -- Divide two VECTORs -- -- A - a VECTOR -- B - a VECTOR to divide `A' by (component-wise) begin return VECTOR '( A.X / B.X, A.Y / B.Y); end "/"; -- -- POINT op POINT ==> POINT -- function "-" ( A : in POINT) return POINT is -- DR078 -- Negate a POINT -- -- A - a POINT begin return POINT '( -A.X, -A.Y); end "-"; function "-" (A : in POINT; -- DR078 B : in POINT) return POINT is -- DR078 -- Subtract two POINTs -- -- A - a POINT -- B - a POINT to subtract from `A' begin return POINT '( A.X - B.X, A.Y - B.Y); end "-"; function "+" (A : in POINT; -- DR078 B : in POINT) return POINT is -- DR078 -- Add two POINTs -- -- A - a POINT -- B - a POINT to add to `A' begin return POINT '( A.X + B.X, A.Y + B.Y); end "+"; function "*" (A : in POINT; -- DR078 B : in POINT) return POINT is -- DR078 -- Multiply two POINTs -- -- A - a POINT -- B - a POINT to multiply `A' by (component-wise) begin return POINT '( A.X * B.X, A.Y * B.Y); end "*"; function "/" (A : in POINT; -- DR078 B : in POINT) return POINT is -- DR078 -- Divide two POINTs -- -- A - a POINT -- B - a POINT to divide `A' by (component-wise) begin return POINT '( A.X / B.X, A.Y / B.Y); end "/"; -- Functions mixing VECTOR and POINT function "-" (HEAD : in POINT; -- DR078 TAIL : in POINT) return VECTOR is -- DR078 -- Subtract two POINTs yielding a VECTOR -- -- A - a displacement POINT -- B - a reference POINT to subtract from `A' begin return VECTOR '( HEAD.X - TAIL.X, HEAD.Y - TAIL.Y); end "-"; function "+" (P : in POINT; -- DR078 V : in VECTOR) return POINT is -- DR078 -- Add a VECTOR to a POINT yielding a POINT -- -- P - a reference POINT -- V - a displacement VECTOR to add to `A' begin return POINT '( P.X + V.X, P.Y + V.Y); end "+"; function "+" (V : in VECTOR; -- DR078 P : in POINT) return POINT is -- DR078 -- Add a VECTOR to a POINT yielding a POINT -- -- V - a displacement VECTOR to add to `A' -- P - a reference POINT begin return POINT '( V.X + P.X, V.Y + P.Y); end "+"; function "-" (P : in POINT; -- DR078 V : in VECTOR) return POINT is -- DR078 -- Subtract a VECTOR from a POINT yielding a POINT -- -- P - a reference POINT -- V - a displacement VECTOR to subtract from `A' begin return POINT '( P.X - V.X, P.Y - V.Y); end "-"; function "-" (V : in VECTOR; -- DR078 P : in POINT) return POINT is -- DR078 -- Subtract a VECTOR from a POINT yielding a POINT -- -- V - a displacement VECTOR -- P - a reference POINT to subtract from `A' begin return POINT '( V.X - P.X, V.Y - P.Y); end "-"; end DC_POINT_OPS;