Arc.java

  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.  *      https://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. /*
  18.  * This is not the original file distributed by the Apache Software Foundation
  19.  * It has been modified by the Hipparchus project
  20.  */
  21. package org.hipparchus.geometry.spherical.oned;

  22. import org.hipparchus.exception.LocalizedCoreFormats;
  23. import org.hipparchus.exception.MathIllegalArgumentException;
  24. import org.hipparchus.geometry.partitioning.Region.Location;
  25. import org.hipparchus.util.FastMath;
  26. import org.hipparchus.util.MathUtils;
  27. import org.hipparchus.util.Precision;


  28. /** This class represents an arc on a circle.
  29.  * @see ArcsSet
  30.  */
  31. public class Arc {

  32.     /** The lower angular bound of the arc. */
  33.     private final double lower;

  34.     /** The upper angular bound of the arc. */
  35.     private final double upper;

  36.     /** Middle point of the arc. */
  37.     private final double middle;

  38.     /** Tolerance below which angles are considered identical. */
  39.     private final double tolerance;

  40.     /** Simple constructor.
  41.      * <p>
  42.      * If either {@code lower} is equals to {@code upper} or
  43.      * the interval exceeds \( 2 \pi \), the arc is considered
  44.      * to be the full circle and its initial defining boundaries
  45.      * will be forgotten. {@code lower} is not allowed to be
  46.      * greater than {@code upper} (an exception is thrown in this case).
  47.      * {@code lower} will be canonicalized between 0 and \( 2 \pi \), and
  48.      * upper shifted accordingly, so the {@link #getInf()} and {@link #getSup()}
  49.      * may not return the value used at instance construction.
  50.      * </p>
  51.      * @param lower lower angular bound of the arc
  52.      * @param upper upper angular bound of the arc
  53.      * @param tolerance tolerance below which angles are considered identical
  54.      * @exception MathIllegalArgumentException if lower is greater than upper
  55.      * or tolerance is smaller than {@link Sphere1D#SMALLEST_TOLERANCE}
  56.      */
  57.     public Arc(final double lower, final double upper, final double tolerance)
  58.         throws MathIllegalArgumentException {
  59.         Sphere1D.checkTolerance(tolerance);
  60.         this.tolerance = tolerance;
  61.         if (Precision.equals(lower, upper, 0) || (upper - lower) >= MathUtils.TWO_PI) {
  62.             // the arc must cover the whole circle
  63.             this.lower  = 0;
  64.             this.upper  = MathUtils.TWO_PI;
  65.             this.middle = FastMath.PI;
  66.         } else  if (lower <= upper) {
  67.             this.lower  = MathUtils.normalizeAngle(lower, FastMath.PI);
  68.             this.upper  = this.lower + (upper - lower);
  69.             this.middle = 0.5 * (this.lower + this.upper);
  70.         } else {
  71.             throw new MathIllegalArgumentException(LocalizedCoreFormats.ENDPOINTS_NOT_AN_INTERVAL,
  72.                                                 lower, upper, true);
  73.         }
  74.     }

  75.     /** Get the lower angular bound of the arc.
  76.      * @return lower angular bound of the arc,
  77.      * always between 0 and \( 2 \pi \)
  78.      */
  79.     public double getInf() {
  80.         return lower;
  81.     }

  82.     /** Get the upper angular bound of the arc.
  83.      * @return upper angular bound of the arc,
  84.      * always between {@link #getInf()} and {@link #getInf()} \( + 2 \pi \)
  85.      */
  86.     public double getSup() {
  87.         return upper;
  88.     }

  89.     /** Get the angular size of the arc.
  90.      * @return angular size of the arc
  91.      */
  92.     public double getSize() {
  93.         return upper - lower;
  94.     }

  95.     /** Get the barycenter of the arc.
  96.      * @return barycenter of the arc
  97.      */
  98.     public double getBarycenter() {
  99.         return middle;
  100.     }

  101.     /** Get the tolerance below which angles are considered identical.
  102.      * @return tolerance below which angles are considered identical
  103.      */
  104.     public double getTolerance() {
  105.         return tolerance;
  106.     }

  107.     /** Check a point with respect to the arc.
  108.      * @param point point to check
  109.      * @return a code representing the point status: either {@link
  110.      * Location#INSIDE}, {@link Location#OUTSIDE} or {@link Location#BOUNDARY}
  111.      */
  112.     public Location checkPoint(final double point) {
  113.         final double normalizedPoint = MathUtils.normalizeAngle(point, middle);
  114.         if (normalizedPoint < lower - tolerance || normalizedPoint > upper + tolerance) {
  115.             return Location.OUTSIDE;
  116.         } else if (normalizedPoint > lower + tolerance && normalizedPoint < upper - tolerance) {
  117.             return Location.INSIDE;
  118.         } else {
  119.             return (getSize() >= MathUtils.TWO_PI - tolerance) ? Location.INSIDE : Location.BOUNDARY;
  120.         }
  121.     }

  122.     /**
  123.      * Get the distance (arc length) from a point to the edge of the arc.
  124.      *
  125.      * <p>This method does not use {@link #getTolerance()}.
  126.      *
  127.      * @param point to test.
  128.      * @return offset, negative if the point is inside the arc, positive if it is outside
  129.      * the arc, or zero if {@code point} is {@link #getInf()} or {@link #getSup()}.
  130.      */
  131.     public double getOffset(final double point) {
  132.         final double normalizedPoint = MathUtils.normalizeAngle(point, middle);
  133.         if (normalizedPoint < middle) {
  134.             return lower - normalizedPoint;
  135.         } else {
  136.             return normalizedPoint - upper;
  137.         }
  138.     }

  139.     /**
  140.      * Get the distance (arc length) from a point to the edge of the arc.
  141.      *
  142.      * <p>This method does not use {@link #getTolerance()}.
  143.      *
  144.      * @param point to test.
  145.      * @return offset, negative if the point is inside the arc, positive if it is outside
  146.      * the arc, or zero if {@code point} is {@link #getInf()} or {@link #getSup()}.
  147.      */
  148.     public double getOffset(final S1Point point) {
  149.         return getOffset(point.getAlpha());
  150.     }

  151. }