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.math3.geometry.euclidean.oned;
018
019import org.apache.commons.math3.geometry.Point;
020import org.apache.commons.math3.geometry.Vector;
021import org.apache.commons.math3.geometry.partitioning.Hyperplane;
022
023/** This class represents a 1D oriented hyperplane.
024 * <p>An hyperplane in 1D is a simple point, its orientation being a
025 * boolean.</p>
026 * <p>Instances of this class are guaranteed to be immutable.</p>
027 * @since 3.0
028 */
029public class OrientedPoint implements Hyperplane<Euclidean1D> {
030
031    /** Default value for tolerance. */
032    private static final double DEFAULT_TOLERANCE = 1.0e-10;
033
034    /** Vector location. */
035    private Vector1D location;
036
037    /** Orientation. */
038    private boolean direct;
039
040    /** Tolerance below which points are considered to belong to the hyperplane. */
041    private final double tolerance;
042
043    /** Simple constructor.
044     * @param location location of the hyperplane
045     * @param direct if true, the plus side of the hyperplane is towards
046     * abscissas greater than {@code location}
047     * @param tolerance tolerance below which points are considered to belong to the hyperplane
048     * @since 3.3
049     */
050    public OrientedPoint(final Vector1D location, final boolean direct, final double tolerance) {
051        this.location  = location;
052        this.direct    = direct;
053        this.tolerance = tolerance;
054    }
055
056    /** Simple constructor.
057     * @param location location of the hyperplane
058     * @param direct if true, the plus side of the hyperplane is towards
059     * abscissas greater than {@code location}
060     * @deprecated as of 3.3, replaced with {@link #OrientedPoint(Vector1D, boolean, double)}
061     */
062    @Deprecated
063    public OrientedPoint(final Vector1D location, final boolean direct) {
064        this(location, direct, DEFAULT_TOLERANCE);
065    }
066
067    /** Copy the instance.
068     * <p>Since instances are immutable, this method directly returns
069     * the instance.</p>
070     * @return the instance itself
071     */
072    public OrientedPoint copySelf() {
073        return this;
074    }
075
076    /** Get the offset (oriented distance) of a vector.
077     * @param vector vector to check
078     * @return offset of the vector
079     */
080    public double getOffset(Vector<Euclidean1D> vector) {
081        return getOffset((Point<Euclidean1D>) vector);
082    }
083
084    /** {@inheritDoc} */
085    public double getOffset(final Point<Euclidean1D> point) {
086        final double delta = ((Vector1D) point).getX() - location.getX();
087        return direct ? delta : -delta;
088    }
089
090    /** Build a region covering the whole hyperplane.
091     * <p>Since this class represent zero dimension spaces which does
092     * not have lower dimension sub-spaces, this method returns a dummy
093     * implementation of a {@link
094     * org.apache.commons.math3.geometry.partitioning.SubHyperplane SubHyperplane}.
095     * This implementation is only used to allow the {@link
096     * org.apache.commons.math3.geometry.partitioning.SubHyperplane
097     * SubHyperplane} class implementation to work properly, it should
098     * <em>not</em> be used otherwise.</p>
099     * @return a dummy sub hyperplane
100     */
101    public SubOrientedPoint wholeHyperplane() {
102        return new SubOrientedPoint(this, null);
103    }
104
105    /** Build a region covering the whole space.
106     * @return a region containing the instance (really an {@link
107     * IntervalsSet IntervalsSet} instance)
108     */
109    public IntervalsSet wholeSpace() {
110        return new IntervalsSet(tolerance);
111    }
112
113    /** {@inheritDoc} */
114    public boolean sameOrientationAs(final Hyperplane<Euclidean1D> other) {
115        return !(direct ^ ((OrientedPoint) other).direct);
116    }
117
118    /** {@inheritDoc}
119     * @since 3.3
120     */
121    public Point<Euclidean1D> project(Point<Euclidean1D> point) {
122        return location;
123    }
124
125    /** {@inheritDoc}
126     * @since 3.3
127     */
128    public double getTolerance() {
129        return tolerance;
130    }
131
132    /** Get the hyperplane location on the real line.
133     * @return the hyperplane location
134     */
135    public Vector1D getLocation() {
136        return location;
137    }
138
139    /** Check if the hyperplane orientation is direct.
140     * @return true if the plus side of the hyperplane is towards
141     * abscissae greater than hyperplane location
142     */
143    public boolean isDirect() {
144        return direct;
145    }
146
147    /** Revert the instance.
148     */
149    public void revertSelf() {
150        direct = !direct;
151    }
152
153}