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.spherical.oned;
018
019import org.apache.commons.math3.geometry.Point;
020import org.apache.commons.math3.geometry.partitioning.Hyperplane;
021
022/** This class represents a 1D oriented hyperplane on the circle.
023 * <p>An hyperplane on the 1-sphere is an angle with an orientation.</p>
024 * <p>Instances of this class are guaranteed to be immutable.</p>
025 * @since 3.3
026 */
027public class LimitAngle implements Hyperplane<Sphere1D> {
028
029    /** Angle location. */
030    private S1Point location;
031
032    /** Orientation. */
033    private boolean direct;
034
035    /** Tolerance below which angles are considered identical. */
036    private final double tolerance;
037
038    /** Simple constructor.
039     * @param location location of the hyperplane
040     * @param direct if true, the plus side of the hyperplane is towards
041     * angles greater than {@code location}
042     * @param tolerance tolerance below which angles are considered identical
043     */
044    public LimitAngle(final S1Point location, final boolean direct, final double tolerance) {
045        this.location  = location;
046        this.direct    = direct;
047        this.tolerance = tolerance;
048    }
049
050    /** Copy the instance.
051     * <p>Since instances are immutable, this method directly returns
052     * the instance.</p>
053     * @return the instance itself
054     */
055    public LimitAngle copySelf() {
056        return this;
057    }
058
059    /** {@inheritDoc} */
060    public double getOffset(final Point<Sphere1D> point) {
061        final double delta = ((S1Point) point).getAlpha() - location.getAlpha();
062        return direct ? delta : -delta;
063    }
064
065    /** Check if the hyperplane orientation is direct.
066     * @return true if the plus side of the hyperplane is towards
067     * angles greater than hyperplane location
068     */
069    public boolean isDirect() {
070        return direct;
071    }
072
073    /** Get the reverse of the instance.
074     * <p>Get a limit angle with reversed orientation with respect to the
075     * instance. A new object is built, the instance is untouched.</p>
076     * @return a new limit angle, with orientation opposite to the instance orientation
077     */
078    public LimitAngle getReverse() {
079        return new LimitAngle(location, !direct, tolerance);
080    }
081
082    /** Build a region covering the whole hyperplane.
083     * <p>Since this class represent zero dimension spaces which does
084     * not have lower dimension sub-spaces, this method returns a dummy
085     * implementation of a {@link
086     * org.apache.commons.math3.geometry.partitioning.SubHyperplane SubHyperplane}.
087     * This implementation is only used to allow the {@link
088     * org.apache.commons.math3.geometry.partitioning.SubHyperplane
089     * SubHyperplane} class implementation to work properly, it should
090     * <em>not</em> be used otherwise.</p>
091     * @return a dummy sub hyperplane
092     */
093    public SubLimitAngle wholeHyperplane() {
094        return new SubLimitAngle(this, null);
095    }
096
097    /** Build a region covering the whole space.
098     * @return a region containing the instance (really an {@link
099     * ArcsSet IntervalsSet} instance)
100     */
101    public ArcsSet wholeSpace() {
102        return new ArcsSet(tolerance);
103    }
104
105    /** {@inheritDoc} */
106    public boolean sameOrientationAs(final Hyperplane<Sphere1D> other) {
107        return !(direct ^ ((LimitAngle) other).direct);
108    }
109
110    /** Get the hyperplane location on the circle.
111     * @return the hyperplane location
112     */
113    public S1Point getLocation() {
114        return location;
115    }
116
117    /** {@inheritDoc} */
118    public Point<Sphere1D> project(Point<Sphere1D> point) {
119        return location;
120    }
121
122    /** {@inheritDoc} */
123    public double getTolerance() {
124        return tolerance;
125    }
126
127}