+ Simple transformations

This commit is contained in:
Vovanium 2024-03-28 13:02:25 +03:00
parent 2e85393a56
commit 5d01e562cd
2 changed files with 57 additions and 1 deletions

View File

@ -0,0 +1,56 @@
--
-- Simple affine transformations, that keep scale and ortogonality
package Video.Integer_Geometry.Unitary_Transformations is
subtype Unitary_Coordinate is Coordinate range -1 .. 1;
type Unitary_Vector is record
X, Y : Unitary_Coordinate;
end record;
function "+" (P, Q : Unitary_Vector) return Unitary_Vector is
(X => P.X + Q.X, Y => P.Y + Q.Y);
function "*" (P : Unitary_Vector; K : Unitary_Coordinate) return Unitary_Vector is
(X => P.X * K, Y => P.Y * K);
function To_Point (P : Unitary_Vector) return Point is (X => P.X, Y => P.Y);
type Transformation is record
X : Unitary_Vector := (1, 0); -- New direction of original X coordinate axis
Y : Unitary_Vector := (0, 1); -- New direction of original Y coordinate axis
B : Point := (0, 0); -- Origin offset
end record;
-- Note: transformation matrix is stored by-column.
-- || m_xx m_xy m_xt || ((m_xx, m_yx),
-- || m_yx m_yy m_yt || -> (m_xy, m_yy),
-- || 0 0 1 || (m_xt, m_yt))
No_Transformation : constant Transformation := ((1, 0), (0, 1), (0, 0));
Flip_X : constant Transformation := ((-1, 0), (0, 1), (0, 0));
Flip_Y : constant Transformation := ((1, 0), (0, -1), (0, 0));
Exchange_X_Y : constant Transformation := ((0, 1), (1, 0), (0, 0));
Rotate_90 : constant Transformation := ((0, 1), (-1, 0), (0, 0));
Rotate_180 : constant Transformation := ((-1, 0), (0, -1), (0, 0));
Rotate_270 : constant Transformation := ((0, -1), (1, 0), (0, 0));
function Translate (Offset : Point) return Transformation is ((1, 0), (0, 1), Offset);
-- Apply transformation to point
function "*" (M : Transformation; P : Point) return Point is
(To_Point (M.X) * P.X + To_Point (M.Y) * P.Y + M.B);
-- Combining transformations:
-- Result is a transformation M applied after transformation N
function "*" (M, N : Transformation) return Transformation is (
X => M.X * N.X.X + M.Y * N.X.Y,
Y => M.X * N.Y.X + M.Y * N.Y.Y,
B => M * N.B);
-- Moves center of transformation from origin to an arbitrary point
-- Works in flips and rotations
function Transform_About (M : Transformation; P : Point) return Transformation is
(Translate (P) * M * Translate (-P));
end Video.Integer_Geometry.Unitary_Transformations;

View File

@ -134,7 +134,7 @@ package Video.Integer_Geometry with Pure is
function "-" (A : Interval; B : Nonempty_Interval) return Interval
is (if Is_Empty (A) then Empty_Interval else (
(if A.First <= Coordinate'First then A.First else A.First - B.First),
(if A.First <= Coordinate'First then A.First else A.First - B.First),
(if A.Last >= Coordinate'Last then A.Last else A.Last - B.Last)));
-- Minkowski difference
-- That is the result (if not empty) is the argument to minkowski sum with B to get A.