001/*******************************************************************************
002 * This software is provided as a supplement to the authors' textbooks on digital
003 * image processing published by Springer-Verlag in various languages and editions.
004 * Permission to use and distribute this software is granted under the BSD 2-Clause
005 * "Simplified" License (see http://opensource.org/licenses/BSD-2-Clause).
006 * Copyright (c) 2006-2023 Wilhelm Burger, Mark J. Burge. All rights reserved.
007 * Visit https://imagingbook.com for additional details.
008 ******************************************************************************/
009
010package imagingbook.common.geometry.mappings.linear;
011
012import imagingbook.common.math.Matrix;
013
014/**
015 * <p>
016 * This class represents a pure 2D rotation about the coordinate origin (as a special case of affine mapping). It can be
017 * assumed that every instance of this class is indeed a rotation. See Secs. 21.1.3 and 21.3.1 of [1] for details.
018 * </p>
019 * <p>
020 * [1] W. Burger, M.J. Burge, <em>Digital Image Processing &ndash; An Algorithmic Introduction</em>, 3rd ed, Springer
021 * (2022).
022 * </p>
023 *
024 * @author WB
025 */
026public class Rotation2D extends AffineMapping2D {
027
028        /**
029         * Constructor. Creates a 2D rotation by a given angle about the origin.
030         *
031         * @param alpha rotation angle (in radians)
032         */
033        public Rotation2D(double alpha) {
034                super(
035                         Math.cos(alpha), -Math.sin(alpha), 0,
036                         Math.sin(alpha),  Math.cos(alpha), 0);
037        }
038
039        /**
040         * Auxiliary constructor used internally for duplicating instances.
041         *
042         * @param a00 matrix element A_00
043         * @param a01 matrix element A_01
044         * @param a10 matrix element A_10
045         * @param a11 matrix element A_11
046         */
047        protected Rotation2D(double a00, double a01, double a10, double a11) {
048                super(a00, a01, 0, a10, a11, 0);
049        }
050
051        /**
052         * Constructor. Creates a new {@link Rotation2D} object from an existing instance.
053         *
054         * @param m a {@link Rotation2D} instance
055         */
056        public Rotation2D(Rotation2D m) {
057                this(m.a00, m.a01, m.a10, m.a11);
058        }
059        
060        // ----------------------------------------------------------
061
062        /**
063         * Concatenates this rotation (A) with another rotation (B) and returns a new rotation (C), such that C(x) =
064         * B(A(x)).
065         *
066         * @param B the second rotation
067         * @return the concatenated rotations
068         */
069        public Rotation2D concat(Rotation2D B) {
070                double[][] C = Matrix.multiply(B.getTransformationMatrix(), this.getTransformationMatrix());
071                return new Rotation2D(C[0][0], C[0][1], C[1][0], C[1][1]);
072        }
073        
074        @Override
075        public Rotation2D duplicate() {
076                return new Rotation2D(this);
077        }
078        
079        @Override
080        public Rotation2D getInverse() {
081                return new Rotation2D(a00, -a01, -a10, a11);
082        }
083
084}
085
086
087