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.exception.NumberIsTooLargeException; 020import org.apache.commons.math3.exception.util.LocalizedFormats; 021import org.apache.commons.math3.geometry.partitioning.Region.Location; 022import org.apache.commons.math3.util.FastMath; 023import org.apache.commons.math3.util.MathUtils; 024import org.apache.commons.math3.util.Precision; 025 026 027/** This class represents an arc on a circle. 028 * @see ArcsSet 029 * @since 3.3 030 */ 031public class Arc { 032 033 /** The lower angular bound of the arc. */ 034 private final double lower; 035 036 /** The upper angular bound of the arc. */ 037 private final double upper; 038 039 /** Middle point of the arc. */ 040 private final double middle; 041 042 /** Tolerance below which angles are considered identical. */ 043 private final double tolerance; 044 045 /** Simple constructor. 046 * <p> 047 * If either {@code lower} is equals to {@code upper} or 048 * the interval exceeds \( 2 \pi \), the arc is considered 049 * to be the full circle and its initial defining boundaries 050 * will be forgotten. {@code lower} is not allowed to be 051 * greater than {@code upper} (an exception is thrown in this case). 052 * {@code lower} will be canonicalized between 0 and \( 2 \pi \), and 053 * upper shifted accordingly, so the {@link #getInf()} and {@link #getSup()} 054 * may not return the value used at instance construction. 055 * </p> 056 * @param lower lower angular bound of the arc 057 * @param upper upper angular bound of the arc 058 * @param tolerance tolerance below which angles are considered identical 059 * @exception NumberIsTooLargeException if lower is greater than upper 060 */ 061 public Arc(final double lower, final double upper, final double tolerance) 062 throws NumberIsTooLargeException { 063 this.tolerance = tolerance; 064 if (Precision.equals(lower, upper, 0) || (upper - lower) >= MathUtils.TWO_PI) { 065 // the arc must cover the whole circle 066 this.lower = 0; 067 this.upper = MathUtils.TWO_PI; 068 this.middle = FastMath.PI; 069 } else if (lower <= upper) { 070 this.lower = MathUtils.normalizeAngle(lower, FastMath.PI); 071 this.upper = this.lower + (upper - lower); 072 this.middle = 0.5 * (this.lower + this.upper); 073 } else { 074 throw new NumberIsTooLargeException(LocalizedFormats.ENDPOINTS_NOT_AN_INTERVAL, 075 lower, upper, true); 076 } 077 } 078 079 /** Get the lower angular bound of the arc. 080 * @return lower angular bound of the arc, 081 * always between 0 and \( 2 \pi \) 082 */ 083 public double getInf() { 084 return lower; 085 } 086 087 /** Get the upper angular bound of the arc. 088 * @return upper angular bound of the arc, 089 * always between {@link #getInf()} and {@link #getInf()} \( + 2 \pi \) 090 */ 091 public double getSup() { 092 return upper; 093 } 094 095 /** Get the angular size of the arc. 096 * @return angular size of the arc 097 */ 098 public double getSize() { 099 return upper - lower; 100 } 101 102 /** Get the barycenter of the arc. 103 * @return barycenter of the arc 104 */ 105 public double getBarycenter() { 106 return middle; 107 } 108 109 /** Get the tolerance below which angles are considered identical. 110 * @return tolerance below which angles are considered identical 111 */ 112 public double getTolerance() { 113 return tolerance; 114 } 115 116 /** Check a point with respect to the arc. 117 * @param point point to check 118 * @return a code representing the point status: either {@link 119 * Location#INSIDE}, {@link Location#OUTSIDE} or {@link Location#BOUNDARY} 120 */ 121 public Location checkPoint(final double point) { 122 final double normalizedPoint = MathUtils.normalizeAngle(point, middle); 123 if (normalizedPoint < lower - tolerance || normalizedPoint > upper + tolerance) { 124 return Location.OUTSIDE; 125 } else if (normalizedPoint > lower + tolerance && normalizedPoint < upper - tolerance) { 126 return Location.INSIDE; 127 } else { 128 return (getSize() >= MathUtils.TWO_PI - tolerance) ? Location.INSIDE : Location.BOUNDARY; 129 } 130 } 131 132}