001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.geometry.core.partitioning;
018
019import org.apache.commons.geometry.core.Point;
020import org.apache.commons.geometry.core.Transform;
021
022/** Interface representing a hyperplane, which in a space of dimension {@code n} is
023 * a subspace of dimension {@code n - 1}. (A hyperplane in Euclidean 3D space,
024 * for example, is a 2 dimensional plane.)
025 *
026 * <p>
027 * Hyperplanes partition their surrounding space into 3 distinct sets: (1) points
028 * lying on one side of the hyperplane, (2) points lying on the opposite side, and
029 * (3) points lying on the hyperplane itself. One side of the hyperplane is labeled
030 * as the <em>plus</em> side and the other as the <em>minus</em> side. The
031 * {@link #offset(Point) offset} of a point in relation to a hyperplane is the distance
032 * from the point to the hyperplane combined with the sign of the side that the point
033 * lies on: points lying on the plus side of the hyperplane have a positive offsets,
034 * those on the minus side have a negative offset, and those lying directly on the
035 * hyperplane have an offset of zero.
036 *
037 * @param <P> Point implementation type
038 * @see HyperplaneLocation
039 * @see HyperplaneSubset
040 */
041public interface Hyperplane<P extends Point<P>> {
042
043    /** Get the offset (oriented distance) of a point with respect
044     * to this instance. Points with an offset of zero lie on the
045     * hyperplane itself.
046     * @param point the point to compute the offset for
047     * @return the offset of the point
048     */
049    double offset(P point);
050
051    /** Classify a point with respect to this hyperplane.
052     * @param point the point to classify
053     * @return the relative location of the point with
054     *      respect to this instance
055     */
056    HyperplaneLocation classify(P point);
057
058    /** Return true if the given point lies on the hyperplane.
059     * @param point the point to test
060     * @return true if the point lies on the hyperplane
061     */
062    boolean contains(P point);
063
064    /** Project a point onto this instance.
065     * @param point the point to project
066     * @return the projection of the point onto this instance. The returned
067     *      point lies on the hyperplane.
068     */
069    P project(P point);
070
071    /** Return a hyperplane that has the opposite orientation as this instance.
072     * That is, the plus side of this instance is the minus side of the returned
073     * instance and vice versa.
074     * @return a hyperplane with the opposite orientation
075     */
076    Hyperplane<P> reverse();
077
078    /** Transform this instance using the given {@link Transform}.
079     * @param transform object to transform this instance with
080     * @return a new, transformed hyperplane
081     */
082    Hyperplane<P> transform(Transform<P> transform);
083
084    /** Return true if this instance has a similar orientation to the given hyperplane,
085     * meaning that they point in generally the same direction. This method is not
086     * used to determine exact equality of hyperplanes, but rather to determine whether
087     * two hyperplanes that contain the same points are parallel (point in the same direction)
088     * or anti-parallel (point in opposite directions).
089     * @param other the hyperplane to compare with
090     * @return true if the hyperplanes point in generally the same direction and could
091     *      possibly be parallel
092     */
093    boolean similarOrientation(Hyperplane<P> other);
094
095    /** Return a {@link HyperplaneConvexSubset} spanning this entire hyperplane. The returned
096     * subset contains all points lying in this hyperplane and no more.
097     * @return a {@link HyperplaneConvexSubset} containing all points lying in this hyperplane
098     */
099    HyperplaneConvexSubset<P> span();
100}