View Javadoc
1   package org.djunits.value.vdouble.scalar;
2   
3   import java.util.regex.Matcher;
4   
5   import org.djunits.unit.AreaUnit;
6   import org.djunits.unit.DimensionlessUnit;
7   import org.djunits.unit.DurationUnit;
8   import org.djunits.unit.EnergyUnit;
9   import org.djunits.unit.LengthUnit;
10  import org.djunits.unit.LinearDensityUnit;
11  import org.djunits.unit.MoneyUnit;
12  import org.djunits.unit.PositionUnit;
13  import org.djunits.unit.SpeedUnit;
14  import org.djunits.unit.Unit;
15  import org.djunits.unit.VolumeUnit;
16  
17  /**
18   * Easy access methods for the Relative Length DoubleScalar. Instead of:
19   * 
20   * <pre>
21   * DoubleScalar&lt;LengthUnit&gt; value = new DoubleScalar&lt;LengthUnit&gt;(100.0, LengthUnit.SI);
22   * </pre>
23   * 
24   * we can now write:
25   * 
26   * <pre>
27   * Length value = new Length(100.0, LengthUnit.SI);
28   * </pre>
29   * 
30   * The compiler will automatically recognize which units belong to which quantity, and whether the quantity type and the unit
31   * used are compatible.
32   * <p>
33   * Copyright (c) 2013-2019 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. <br>
34   * All rights reserved. <br>
35   * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
36   * <p>
37   * $LastChangedDate: 2019-03-03 00:53:50 +0100 (Sun, 03 Mar 2019) $, @version $Revision: 349 $, by $Author: averbraeck $,
38   * initial version Sep 1, 2015 <br>
39   * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
40   * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
41   */
42  public class Length extends AbstractDoubleScalarRel<LengthUnit, Length>
43  {
44      /** */
45      private static final long serialVersionUID = 20150901L;
46  
47      /** constant with value zero. */
48      public static final Length ZERO = new Length(0.0, LengthUnit.SI);
49  
50      /** constant with value NaN. */
51      @SuppressWarnings("checkstyle:constantname")
52      public static final Length NaN = new Length(Double.NaN, LengthUnit.SI);
53  
54      /** constant with value POSITIVE_INFINITY. */
55      public static final Length POSITIVE_INFINITY = new Length(Double.POSITIVE_INFINITY, LengthUnit.SI);
56  
57      /** constant with value NEGATIVE_INFINITY. */
58      public static final Length NEGATIVE_INFINITY = new Length(Double.NEGATIVE_INFINITY, LengthUnit.SI);
59  
60      /** constant with value MAX_VALUE. */
61      public static final Length POS_MAXVALUE = new Length(Double.MAX_VALUE, LengthUnit.SI);
62  
63      /** constant with value -MAX_VALUE. */
64      public static final Length NEG_MAXVALUE = new Length(-Double.MAX_VALUE, LengthUnit.SI);
65  
66      /**
67       * Construct Length scalar.
68       * @param value double value
69       * @param unit unit for the double value
70       */
71      public Length(final double value, final LengthUnit unit)
72      {
73          super(value, unit);
74      }
75  
76      /**
77       * Construct Length scalar.
78       * @param value Scalar from which to construct this instance
79       */
80      public Length(final Length value)
81      {
82          super(value);
83      }
84  
85      /** {@inheritDoc} */
86      @Override
87      public final Length instantiateRel(final double value, final LengthUnit unit)
88      {
89          return new Length(value, unit);
90      }
91  
92      /**
93       * Construct a new Absolute Immutable DoubleScalar of the right type. Each extending class must implement this method.
94       * @param value the double value
95       * @param unit the unit
96       * @return A a new absolute instance of the DoubleScalar of the right type
97       */
98      public final Position instantiateAbs(final double value, final PositionUnit unit)
99      {
100         return new Position(value, unit);
101     }
102 
103     /**
104      * Construct Length scalar.
105      * @param value double value in SI units
106      * @return the new scalar with the SI value
107      */
108     public static final Length createSI(final double value)
109     {
110         return new Length(value, LengthUnit.SI);
111     }
112 
113     /**
114      * Interpolate between two values.
115      * @param zero the low value
116      * @param one the high value
117      * @param ratio the ratio between 0 and 1, inclusive
118      * @return a Scalar at the ratio between
119      */
120     public static Length interpolate(final Length zero, final Length one, final double ratio)
121     {
122         return new Length(zero.getInUnit() * (1 - ratio) + one.getInUnit(zero.getUnit()) * ratio, zero.getUnit());
123     }
124 
125     /**
126      * Relative scalar plus Absolute scalar = Absolute scalar.
127      * @param v the value to add
128      * @return sum of this value and v as a new object
129      */
130     public final Position plus(final Position v)
131     {
132         PositionUnit targetUnit = v.getUnit();
133         return instantiateAbs(v.getInUnit() + getInUnit(targetUnit.getRelativeUnit()), targetUnit);
134     }
135 
136     /**
137      * Return the maximum value of two relative scalars.
138      * @param r1 the first scalar
139      * @param r2 the second scalar
140      * @return the maximum value of two relative scalars
141      */
142     public static Length max(final Length r1, final Length r2)
143     {
144         return (r1.gt(r2)) ? r1 : r2;
145     }
146 
147     /**
148      * Return the maximum value of more than two relative scalars.
149      * @param r1 the first scalar
150      * @param r2 the second scalar
151      * @param rn the other scalars
152      * @return the maximum value of more than two relative scalars
153      */
154     public static Length max(final Length r1, final Length r2, final Length... rn)
155     {
156         Length maxr = (r1.gt(r2)) ? r1 : r2;
157         for (Length r : rn)
158         {
159             if (r.gt(maxr))
160             {
161                 maxr = r;
162             }
163         }
164         return maxr;
165     }
166 
167     /**
168      * Return the minimum value of two relative scalars.
169      * @param r1 the first scalar
170      * @param r2 the second scalar
171      * @return the minimum value of two relative scalars
172      */
173     public static Length min(final Length r1, final Length r2)
174     {
175         return (r1.lt(r2)) ? r1 : r2;
176     }
177 
178     /**
179      * Return the minimum value of more than two relative scalars.
180      * @param r1 the first scalar
181      * @param r2 the second scalar
182      * @param rn the other scalars
183      * @return the minimum value of more than two relative scalars
184      */
185     public static Length min(final Length r1, final Length r2, final Length... rn)
186     {
187         Length minr = (r1.lt(r2)) ? r1 : r2;
188         for (Length r : rn)
189         {
190             if (r.lt(minr))
191             {
192                 minr = r;
193             }
194         }
195         return minr;
196     }
197 
198     /**
199      * Returns a Length representation of a textual representation of a value with a unit. The String representation that can be
200      * parsed is the double value in the unit, followed by the official abbreviation of the unit. Spaces are allowed, but not
201      * necessary, between the value and the unit.
202      * @param text String; the textual representation to parse into a Length
203      * @return the String representation of the value in its unit, followed by the official abbreviation of the unit
204      * @throws IllegalArgumentException when the text cannot be parsed
205      */
206     public static Length valueOf(final String text) throws IllegalArgumentException
207     {
208         if (text == null || text.length() == 0)
209         {
210             throw new IllegalArgumentException("Error parsing Length -- null or empty argument");
211         }
212         Matcher matcher = NUMBER_PATTERN.matcher(text);
213         if (matcher.find())
214         {
215             int index = matcher.end();
216             try
217             {
218                 String unitString = text.substring(index).trim();
219                 String valueString = text.substring(0, index).trim();
220                 for (LengthUnit unit : Unit.getUnits(LengthUnit.class))
221                 {
222                     if (unit.getDefaultLocaleTextualRepresentations().contains(unitString))
223                     {
224                         double d = Double.parseDouble(valueString);
225                         return new Length(d, unit);
226                     }
227                 }
228             }
229             catch (Exception exception)
230             {
231                 throw new IllegalArgumentException("Error parsing Length from " + text, exception);
232             }
233         }
234         throw new IllegalArgumentException("Error parsing Length from " + text);
235     }
236 
237     /**
238      * Calculate the division of Length and Length, which results in a Dimensionless scalar.
239      * @param v Length scalar
240      * @return Dimensionless scalar as a division of Length and Length
241      */
242     public final Dimensionless divideBy(final Length v)
243     {
244         return new Dimensionless(this.si / v.si, DimensionlessUnit.SI);
245     }
246 
247     /**
248      * Calculate the multiplication of Length and Length, which results in a Area scalar.
249      * @param v Length scalar
250      * @return Area scalar as a multiplication of Length and Length
251      */
252     public final Area multiplyBy(final Length v)
253     {
254         return new Area(this.si * v.si, AreaUnit.SI);
255     }
256 
257     /**
258      * Calculate the division of Length and LinearDensity, which results in a Area scalar.
259      * @param v Length scalar
260      * @return Area scalar as a division of Length and LinearDensity
261      */
262     public final Area divideBy(final LinearDensity v)
263     {
264         return new Area(this.si / v.si, AreaUnit.SI);
265     }
266 
267     /**
268      * Calculate the division of Length and Area, which results in a LinearDensity scalar.
269      * @param v Length scalar
270      * @return LinearDensity scalar as a division of Length and Area
271      */
272     public final LinearDensity divideBy(final Area v)
273     {
274         return new LinearDensity(this.si / v.si, LinearDensityUnit.SI);
275     }
276 
277     /**
278      * Calculate the multiplication of Length and Area, which results in a Volume scalar.
279      * @param v Length scalar
280      * @return Volume scalar as a multiplication of Length and Area
281      */
282     public final Volume multiplyBy(final Area v)
283     {
284         return new Volume(this.si * v.si, VolumeUnit.SI);
285     }
286 
287     /**
288      * Calculate the multiplication of Length and Force, which results in a Energy scalar.
289      * @param v Length scalar
290      * @return Energy scalar as a multiplication of Length and Force
291      */
292     public final Energy multiplyBy(final Force v)
293     {
294         return new Energy(this.si * v.si, EnergyUnit.SI);
295     }
296 
297     /**
298      * Calculate the multiplication of Length and Frequency, which results in a Speed scalar.
299      * @param v Length scalar
300      * @return Speed scalar as a multiplication of Length and Frequency
301      */
302     public final Speed multiplyBy(final Frequency v)
303     {
304         return new Speed(this.si * v.si, SpeedUnit.SI);
305     }
306 
307     /**
308      * Calculate the division of Length and Duration, which results in a Speed scalar.
309      * @param v Length scalar
310      * @return Speed scalar as a division of Length and Duration
311      */
312     public final Speed divideBy(final Duration v)
313     {
314         return new Speed(this.si / v.si, SpeedUnit.SI);
315     }
316 
317     /**
318      * Calculate the division of Length and Speed, which results in a Duration scalar.
319      * @param v Length scalar
320      * @return Duration scalar as a division of Length and Speed
321      */
322     public final Duration divideBy(final Speed v)
323     {
324         return new Duration(this.si / v.si, DurationUnit.SI);
325     }
326 
327     /**
328      * Calculate the multiplication of Length and MoneyPerLength, which results in a Money scalar.
329      * @param v Length scalar
330      * @return Money scalar as a multiplication of Length and MoneyPerLength
331      */
332     public final Money multiplyBy(final MoneyPerLength v)
333     {
334         return new Money(this.si * v.si, MoneyUnit.getStandardMoneyUnit());
335     }
336 
337 }