1 package org.djunits.value.vdouble.scalar;
2
3 import java.util.regex.Matcher;
4
5 import org.djunits.unit.AngleUnit;
6 import org.djunits.unit.DimensionlessUnit;
7 import org.djunits.unit.DirectionUnit;
8 import org.djunits.unit.Unit;
9
10 /**
11 * Easy access methods for the Relative Angle DoubleScalar. Instead of:
12 *
13 * <pre>
14 * DoubleScalar<AngleUnit> value = new DoubleScalar<AngleUnit>(100.0, AngleUnit.SI);
15 * </pre>
16 *
17 * we can now write:
18 *
19 * <pre>
20 * Angle value = new Angle(100.0, AngleUnit.SI);
21 * </pre>
22 *
23 * The compiler will automatically recognize which units belong to which quantity, and whether the quantity type and the unit
24 * used are compatible.
25 * <p>
26 * Copyright (c) 2013-2019 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. <br>
27 * All rights reserved. <br>
28 * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
29 * <p>
30 * $LastChangedDate: 2015-12-22 04:32:39 +0100 (Tue, 22 Dec 2015) $, @version $Revision: 180 $, by $Author: averbraeck $,
31 * initial version Sep 1, 2015 <br>
32 * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
33 * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
34 */
35 public class Angle extends AbstractDoubleScalarRel<AngleUnit, Angle>
36 {
37 /** */
38 private static final long serialVersionUID = 20150901L;
39
40 /** constant with value zero. */
41 public static final Angle ZERO = new Angle(0.0, AngleUnit.SI);
42
43 /** constant with value NaN. */
44 @SuppressWarnings("checkstyle:constantname")
45 public static final Angle NaN = new Angle(Double.NaN, AngleUnit.SI);
46
47 /** constant with value POSITIVE_INFINITY. */
48 public static final Angle POSITIVE_INFINITY = new Angle(Double.POSITIVE_INFINITY, AngleUnit.SI);
49
50 /** constant with value NEGATIVE_INFINITY. */
51 public static final Angle NEGATIVE_INFINITY = new Angle(Double.NEGATIVE_INFINITY, AngleUnit.SI);
52
53 /** constant with value MAX_VALUE. */
54 public static final Angle POS_MAXVALUE = new Angle(Double.MAX_VALUE, AngleUnit.SI);
55
56 /** constant with value -MAX_VALUE. */
57 public static final Angle NEG_MAXVALUE = new Angle(-Double.MAX_VALUE, AngleUnit.SI);
58
59 /**
60 * Construct Angle scalar.
61 * @param value double value
62 * @param unit unit for the double value
63 */
64 public Angle(final double value, final AngleUnit unit)
65 {
66 super(value, unit);
67 }
68
69 /**
70 * Construct Angle scalar.
71 * @param value Scalar from which to construct this instance
72 */
73 public Angle(final Angle value)
74 {
75 super(value);
76 }
77
78 /** {@inheritDoc} */
79 @Override
80 public final Angle instantiateRel(final double value, final AngleUnit unit)
81 {
82 return new Angle(value, unit);
83 }
84
85 /**
86 * Construct a new Absolute Immutable DoubleScalar of the right type. Each extending class must implement this method.
87 * @param value the double value
88 * @param unit the unit
89 * @return A a new absolute instance of the DoubleScalar of the right type
90 */
91 public final Direction instantiateAbs(final double value, final DirectionUnit unit)
92 {
93 return new Direction(value, unit);
94 }
95
96 /**
97 * Construct Angle scalar.
98 * @param value double value in SI units
99 * @return the new scalar with the SI value
100 */
101 public static final Angle createSI(final double value)
102 {
103 return new Angle(value, AngleUnit.SI);
104 }
105
106 /**
107 * Interpolate between two values.
108 * @param zero the low value
109 * @param one the high value
110 * @param ratio the ratio between 0 and 1, inclusive
111 * @return a Scalar at the ratio between
112 */
113 public static Angle interpolate(final Angle zero, final Angle one, final double ratio)
114 {
115 return new Angle(zero.getInUnit() * (1 - ratio) + one.getInUnit(zero.getUnit()) * ratio, zero.getUnit());
116 }
117
118 /**
119 * Relative scalar plus Absolute scalar = Absolute scalar.
120 * @param v the value to add
121 * @return sum of this value and v as a new object
122 */
123 public final Direction plus(final Direction v)
124 {
125 DirectionUnit targetUnit = v.getUnit();
126 return instantiateAbs(v.getInUnit() + getInUnit(targetUnit.getRelativeUnit()), targetUnit);
127 }
128
129 /**
130 * Return the maximum value of two relative scalars.
131 * @param r1 the first scalar
132 * @param r2 the second scalar
133 * @return the maximum value of two relative scalars
134 */
135 public static Angle max(final Angle r1, final Angle r2)
136 {
137 return (r1.gt(r2)) ? r1 : r2;
138 }
139
140 /**
141 * Return the maximum value of more than two relative scalars.
142 * @param r1 the first scalar
143 * @param r2 the second scalar
144 * @param rn the other scalars
145 * @return the maximum value of more than two relative scalars
146 */
147 public static Angle max(final Angle r1, final Angle r2, final Angle... rn)
148 {
149 Angle maxr = (r1.gt(r2)) ? r1 : r2;
150 for (Angle r : rn)
151 {
152 if (r.gt(maxr))
153 {
154 maxr = r;
155 }
156 }
157 return maxr;
158 }
159
160 /**
161 * Return the minimum value of two relative scalars.
162 * @param r1 the first scalar
163 * @param r2 the second scalar
164 * @return the minimum value of two relative scalars
165 */
166 public static Angle min(final Angle r1, final Angle r2)
167 {
168 return (r1.lt(r2)) ? r1 : r2;
169 }
170
171 /**
172 * Return the minimum value of more than two relative scalars.
173 * @param r1 the first scalar
174 * @param r2 the second scalar
175 * @param rn the other scalars
176 * @return the minimum value of more than two relative scalars
177 */
178 public static Angle min(final Angle r1, final Angle r2, final Angle... rn)
179 {
180 Angle minr = (r1.lt(r2)) ? r1 : r2;
181 for (Angle r : rn)
182 {
183 if (r.lt(minr))
184 {
185 minr = r;
186 }
187 }
188 return minr;
189 }
190
191 /**
192 * Returns a Angle representation of a textual representation of a value with a unit. The String representation that can be
193 * parsed is the double value in the unit, followed by the official abbreviation of the unit. Spaces are allowed, but not
194 * necessary, between the value and the unit.
195 * @param text String; the textual representation to parse into a Angle
196 * @return the String representation of the value in its unit, followed by the official abbreviation of the unit
197 * @throws IllegalArgumentException when the text cannot be parsed
198 */
199 public static Angle valueOf(final String text) throws IllegalArgumentException
200 {
201 if (text == null || text.length() == 0)
202 {
203 throw new IllegalArgumentException("Error parsing Angle -- null or empty argument");
204 }
205 Matcher matcher = NUMBER_PATTERN.matcher(text);
206 if (matcher.find())
207 {
208 int index = matcher.end();
209 try
210 {
211 String unitString = text.substring(index).trim();
212 String valueString = text.substring(0, index).trim();
213 for (AngleUnit unit : Unit.getUnits(AngleUnit.class))
214 {
215 if (unit.getDefaultLocaleTextualRepresentations().contains(unitString))
216 {
217 double d = Double.parseDouble(valueString);
218 return new Angle(d, unit);
219 }
220 }
221 }
222 catch (Exception exception)
223 {
224 throw new IllegalArgumentException("Error parsing Angle from " + text, exception);
225 }
226 }
227 throw new IllegalArgumentException("Error parsing Angle from " + text);
228 }
229
230 /**
231 * Calculate the division of Angle and Angle, which results in a Dimensionless scalar.
232 * @param v Angle scalar
233 * @return Dimensionless scalar as a division of Angle and Angle
234 */
235 public final Dimensionless divideBy(final Angle v)
236 {
237 return new Dimensionless(this.si / v.si, DimensionlessUnit.SI);
238 }
239
240 }