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 /* 19 * This is not the original file distributed by the Apache Software Foundation 20 * It has been modified by the Hipparchus project 21 */ 22 package org.hipparchus.geometry.spherical.oned; 23 24 import org.hipparchus.exception.LocalizedCoreFormats; 25 import org.hipparchus.exception.MathIllegalArgumentException; 26 import org.hipparchus.geometry.partitioning.Region.Location; 27 import org.hipparchus.util.FastMath; 28 import org.hipparchus.util.MathUtils; 29 import org.hipparchus.util.Precision; 30 31 32 /** This class represents an arc on a circle. 33 * @see ArcsSet 34 */ 35 public class Arc { 36 37 /** The lower angular bound of the arc. */ 38 private final double lower; 39 40 /** The upper angular bound of the arc. */ 41 private final double upper; 42 43 /** Middle point of the arc. */ 44 private final double middle; 45 46 /** Tolerance below which angles are considered identical. */ 47 private final double tolerance; 48 49 /** Simple constructor. 50 * <p> 51 * If either {@code lower} is equals to {@code upper} or 52 * the interval exceeds \( 2 \pi \), the arc is considered 53 * to be the full circle and its initial defining boundaries 54 * will be forgotten. {@code lower} is not allowed to be 55 * greater than {@code upper} (an exception is thrown in this case). 56 * {@code lower} will be canonicalized between 0 and \( 2 \pi \), and 57 * upper shifted accordingly, so the {@link #getInf()} and {@link #getSup()} 58 * may not return the value used at instance construction. 59 * </p> 60 * @param lower lower angular bound of the arc 61 * @param upper upper angular bound of the arc 62 * @param tolerance tolerance below which angles are considered identical 63 * @exception MathIllegalArgumentException if lower is greater than upper 64 * or tolerance is smaller than {@link Sphere1D#SMALLEST_TOLERANCE} 65 */ 66 public Arc(final double lower, final double upper, final double tolerance) 67 throws MathIllegalArgumentException { 68 Sphere1D.checkTolerance(tolerance); 69 this.tolerance = tolerance; 70 if (Precision.equals(lower, upper, 0) || (upper - lower) >= MathUtils.TWO_PI) { 71 // the arc must cover the whole circle 72 this.lower = 0; 73 this.upper = MathUtils.TWO_PI; 74 this.middle = FastMath.PI; 75 } else if (lower <= upper) { 76 this.lower = MathUtils.normalizeAngle(lower, FastMath.PI); 77 this.upper = this.lower + (upper - lower); 78 this.middle = 0.5 * (this.lower + this.upper); 79 } else { 80 throw new MathIllegalArgumentException(LocalizedCoreFormats.ENDPOINTS_NOT_AN_INTERVAL, 81 lower, upper, true); 82 } 83 } 84 85 /** Get the lower angular bound of the arc. 86 * @return lower angular bound of the arc, 87 * always between 0 and \( 2 \pi \) 88 */ 89 public double getInf() { 90 return lower; 91 } 92 93 /** Get the upper angular bound of the arc. 94 * @return upper angular bound of the arc, 95 * always between {@link #getInf()} and {@link #getInf()} \( + 2 \pi \) 96 */ 97 public double getSup() { 98 return upper; 99 } 100 101 /** Get the angular size of the arc. 102 * @return angular size of the arc 103 */ 104 public double getSize() { 105 return upper - lower; 106 } 107 108 /** Get the barycenter of the arc. 109 * @return barycenter of the arc 110 */ 111 public double getBarycenter() { 112 return middle; 113 } 114 115 /** Get the tolerance below which angles are considered identical. 116 * @return tolerance below which angles are considered identical 117 */ 118 public double getTolerance() { 119 return tolerance; 120 } 121 122 /** Check a point with respect to the arc. 123 * @param point point to check 124 * @return a code representing the point status: either {@link 125 * Location#INSIDE}, {@link Location#OUTSIDE} or {@link Location#BOUNDARY} 126 */ 127 public Location checkPoint(final double point) { 128 final double normalizedPoint = MathUtils.normalizeAngle(point, middle); 129 if (normalizedPoint < lower - tolerance || normalizedPoint > upper + tolerance) { 130 return Location.OUTSIDE; 131 } else if (normalizedPoint > lower + tolerance && normalizedPoint < upper - tolerance) { 132 return Location.INSIDE; 133 } else { 134 return (getSize() >= MathUtils.TWO_PI - tolerance) ? Location.INSIDE : Location.BOUNDARY; 135 } 136 } 137 138 /** 139 * Get the distance (arc length) from a point to the edge of the arc. 140 * 141 * <p>This method does not use {@link #getTolerance()}. 142 * 143 * @param point to test. 144 * @return offset, negative if the point is inside the arc, positive if it is outside 145 * the arc, or zero if {@code point} is {@link #getInf()} or {@link #getSup()}. 146 */ 147 public double getOffset(final double point) { 148 final double normalizedPoint = MathUtils.normalizeAngle(point, middle); 149 if (normalizedPoint < middle) { 150 return lower - normalizedPoint; 151 } else { 152 return normalizedPoint - upper; 153 } 154 } 155 156 /** 157 * Get the distance (arc length) from a point to the edge of the arc. 158 * 159 * <p>This method does not use {@link #getTolerance()}. 160 * 161 * @param point to test. 162 * @return offset, negative if the point is inside the arc, positive if it is outside 163 * the arc, or zero if {@code point} is {@link #getInf()} or {@link #getSup()}. 164 */ 165 public double getOffset(final S1Point point) { 166 return getOffset(point.getAlpha()); 167 } 168 169 }