View Javadoc

    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    *
    9    *      http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   */
    17  package org.apache.commons.geometry.euclidean;
    18
    19  /** Base class for affine transform matrices in Euclidean space.
    20   *
    21   * @param <V> Vector/point implementation type defining the space.
    22   * @param <M> Matrix transform implementation type.
    23   */
    24  public abstract class AbstractAffineTransformMatrix<
    25          V extends EuclideanVector<V>,
    26          M extends AbstractAffineTransformMatrix<V, M>>
    27      implements EuclideanTransform<V> {
    28
    29      /** Apply this transform to the given vector, ignoring translations and normalizing the
    30       * result. This is equivalent to {@code transform.applyVector(vec).normalize()} but without
    31       * the intermediate vector instance.
    32       *
    33       * @param vec the vector to transform
    34       * @return the new, transformed unit vector
    35       * @throws IllegalArgumentException if the transformed vector coordinates cannot be normalized
    36       * @see #applyVector(EuclideanVector)
    37       */
    38      public abstract V applyDirection(V vec);
    39
    40      /** Get the determinant of the matrix.
    41       * @return the determinant of the matrix
    42       */
    43      public abstract double determinant();
    44
    45      /** {@inheritDoc}
    46       * @throws IllegalStateException if the matrix cannot be inverted
    47       */
    48      @Override
    49      public abstract M inverse();
    50
    51      /** Return a matrix containing only the linear portion of this transform.
    52       * The returned instance contains the same matrix elements as this instance
    53       * but with the translation component set to zero.
    54       * @return a matrix containing only the linear portion of this transform
    55       */
    56      public abstract M linear();
    57
    58      /** Return a matrix containing the transpose of the linear portion of this transform.
    59       * The returned instance is linear, meaning it has a translation component of zero.
    60       * @return a matrix containing the transpose of the linear portion of this transform
    61       */
    62      public abstract M linearTranspose();
    63
    64      /** Return a transform suitable for transforming normals. The returned matrix is
    65       * the inverse transpose of the linear portion of this instance, i.e.
    66       * <code>N = (L<sup>-1</sup>)<sup>T</sup></code>, where <code>L</code> is the linear portion
    67       * of this instance and <code>N</code> is the returned matrix. Note that normals
    68       * transformed with the returned matrix may be scaled during transformation and require
    69       * normalization.
    70       * @return a transform suitable for transforming normals
    71       * @throws IllegalStateException if the matrix cannot be inverted
    72       * @see <a href="https://en.wikipedia.org/wiki/Normal_(geometry)#Transforming_normals">Transforming normals</a>
    73       */
    74      public M normalTransform() {
    75          return inverse().linearTranspose();
    76      }
    77
    78      /** {@inheritDoc}
    79       *
    80       * <p>This method returns true if the determinant of the matrix is positive.</p>
    81       */
    82      @Override
    83      public boolean preservesOrientation() {
    84          return determinant() > 0.0;
    85      }
    86  }