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.core;
    18
    19  import java.util.function.UnaryOperator;
    20
    21  /** Interface representing geometric transforms in a space, i.e. mappings from points to points.
    22   * Implementations <em>must</em> fulfill a set of requirements, listed below, that preserve the
    23   * consistency of partitionings on the space. Transforms that do not meet these requirements, while
    24   * potentially valid mathematically, cannot be expected to produce correct results with algorithms
    25   * that use this interface.
    26   *
    27   * <ol>
    28   *      <li>Transforms must represent functions that are <em>one-to-one</em> and <em>onto</em> (i.e.
    29   *      <a href="https://en.wikipedia.org/wiki/Bijection">bijections</a>). This means that every point
    30   *      in the space must be mapped to exactly one other point in the space. This also implies that the
    31   *      function is invertible.</li>
    32   *      <li>Transforms must preserve <a href="https://en.wikipedia.org/wiki/Collinearity">collinearity</a>.
    33   *      This means that if a set of points lie on a common hyperplane before the transform, then they must
    34   *      also lie on a common hyperplane after the transform. For example, if the Euclidean 2D points {@code a},
    35   *      {@code b}, and {@code c} lie on line {@code L}, then the transformed points {@code a'}, {@code b'}, and
    36   *      {@code c'} must lie on line {@code L'}, where {@code L'} is the transformed form of the line.</li>
    37   *      <li>Transforms must preserve the concept of
    38   *      <a href="https://en.wikipedia.org/wiki/Parallel_(geometry)">parallelism</a> defined for the space.
    39   *      This means that hyperplanes that are parallel before the transformation must remain parallel afterwards,
    40   *      and hyperplanes that intersect must also intersect afterwards. For example, a transform that causes parallel
    41   *      lines to converge to a single point in Euclidean space (such as the projective transforms used to create
    42   *      perspective viewpoints in 3D graphics) would not meet this requirement. However, a transform that turns
    43   *      a square into a rhombus with no right angles would fulfill the requirement, since the two pairs of parallel
    44   *      lines forming the square remain parallel after the transformation.
    45   *      </li>
    46   * </ol>
    47   *
    48   * <p>Transforms that meet the above requirements in Euclidean space (and other affine spaces) are known as
    49   * <a href="https://en.wikipedia.org/wiki/Affine_transformation">affine transforms</a>. Common affine transforms
    50   * include translation, scaling, rotation, reflection, and any compositions thereof.
    51   * </p>
    52   *
    53   * @param <P> Point implementation type
    54   * @see <a href="https://en.wikipedia.org/wiki/Geometric_transformation">Geometric Transformation</a>
    55   */
    56  public interface Transform<P extends Point<P>> extends UnaryOperator<P> {
    57
    58      /** Get an instance representing the inverse transform.
    59       * @return an instance representing the inverse transform
    60       */
    61      Transform<P> inverse();
    62
    63      /** Return true if the transform preserves the orientation of the space.
    64       * For example, in Euclidean 2D space, this will be true for translations,
    65       * rotations, and scalings but will be false for reflections.
    66       * @return true if the transform preserves the orientation of the space
    67       * @see <a href="https://en.wikipedia.org/wiki/Orientation_(vector_space)">Orientation</a>
    68       */
    69      boolean preservesOrientation();
    70  }