------------------------------------------------------------------ -- -- NAME: NDC_TRANSFORM - BODY -- DISCREPANCY REPORTS: ------------------------------------------------------------------ -- File: NDC_TRANSFORM_B.ADA -- Level: 1a, 2a, 1b, 2b package body NDC_TRANSFORM is function TRANSFORM (POINT : NDC . POINT; XFORM : TRANSFORMATION_MATRIX := DEFAULT_TRANSFORMATION) return NDC . POINT is -- Transform POINT using XFORM -- -- POINT - input POINT -- XFORM - transformation -- Break out the XFORM X11 : NDC_TYPE renames XFORM (1,1); X12 : NDC_TYPE renames XFORM (1,2); X13 : NDC_TYPE renames XFORM (1,3); X21 : NDC_TYPE renames XFORM (2,1); X22 : NDC_TYPE renames XFORM (2,2); X23 : NDC_TYPE renames XFORM (2,3); -- Break out the POINT and convert into a type -- compatible with the result. PX : NDC_TYPE renames POINT . X; PY : NDC_TYPE renames POINT . Y; begin return NDC . POINT '( X => X11 * PX + X12 * PY + X13, Y => X21 * PX + X22 * PY + X23); end TRANSFORM; function TRANSFORM (POINT_ARRAY : NDC . POINT_ARRAY; XFORM : TRANSFORMATION_MATRIX := DEFAULT_TRANSFORMATION) return NDC . POINT_ARRAY is -- Transform all POINTs in POINT_ARRAY using XFORM -- -- POINT_ARRAY - array of input POINTs -- XFORM - transformation TRANSFORMED_POINT_ARRAY : NDC . POINT_ARRAY (POINT_ARRAY'RANGE); -- Array to hold transformed points -- Break out the XFORM X11 : NDC_TYPE renames XFORM (1,1); X12 : NDC_TYPE renames XFORM (1,2); X13 : NDC_TYPE renames XFORM (1,3); X21 : NDC_TYPE renames XFORM (2,1); X22 : NDC_TYPE renames XFORM (2,2); X23 : NDC_TYPE renames XFORM (2,3); begin for I in POINT_ARRAY'RANGE loop declare -- Break out the POINT POINT : NDC . POINT renames POINT_ARRAY(I); PX : NDC_TYPE renames POINT . X; PY : NDC_TYPE renames POINT . Y; begin TRANSFORMED_POINT_ARRAY (I) := NDC . POINT '( X => X11 * PX + X12 * PY + X13, Y => X21 * PX + X22 * PY + X23); end; end loop; return TRANSFORMED_POINT_ARRAY; end TRANSFORM; -- The following functions are for relative scaling only, -- not absolute positions function TRANSFORM (VECTOR : NDC . VECTOR; XFORM : TRANSFORMATION_MATRIX := DEFAULT_TRANSFORMATION) return NDC . VECTOR is -- Convert VECTOR to NDC units using XFORM transformation -- -- VECTOR - input VECTOR -- XFORM - transformation to NDC units -- Break out the XFORM X11 : NDC_TYPE renames XFORM (1,1); X12 : NDC_TYPE renames XFORM (1,2); X13 : NDC_TYPE renames XFORM (1,3); X21 : NDC_TYPE renames XFORM (2,1); X22 : NDC_TYPE renames XFORM (2,2); X23 : NDC_TYPE renames XFORM (2,3); -- Break out the VECTOR and convert into a type -- compatible with the result. VX : NDC_TYPE renames VECTOR . X; VY : NDC_TYPE renames VECTOR . Y; begin return NDC . VECTOR '( X => X11 * VX + X12 * VY, Y => X21 * VX + X22 * VY); end TRANSFORM; function INVERSE_TRANSFORMATION (XFORM : TRANSFORMATION_MATRIX := DEFAULT_TRANSFORMATION) return TRANSFORMATION_MATRIX is -- Calculate an inverse transformation -- XFORM - original transformation -- Break out the XFORM X11 : NDC_TYPE renames XFORM (1,1); X12 : NDC_TYPE renames XFORM (1,2); X13 : NDC_TYPE renames XFORM (1,3); X21 : NDC_TYPE renames XFORM (2,1); X22 : NDC_TYPE renames XFORM (2,2); X23 : NDC_TYPE renames XFORM (2,3); S : NDC_TYPE; -- Scaling factor based on the inverse of the determinant of the -- Rotation/scaling portion of the XFORM begin S := 1.0 / (X11 * X22 - X12 * X21); -- exception raised if (X11 * X22 - X12 * X21) is bad return TRANSFORMATION_MATRIX '( ( X22 * S, -X12 * S , (X12 * X23 - X22 * X13) * S), (-X21 * S, X11 * S , -(X11 * X23 - X21 * X13) * S)); exception when others => raise INVERSE_UNDEFINED; end INVERSE_TRANSFORMATION; end NDC_TRANSFORM;