View Javadoc
1   package org.djunits.value.vdouble.scalar;
2   
3   import java.util.Locale;
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.MomentumUnit;
12  import org.djunits.unit.PositionUnit;
13  import org.djunits.unit.SpeedUnit;
14  import org.djunits.unit.VolumeUnit;
15  import org.djunits.value.vdouble.scalar.base.DoubleScalarRel;
16  import org.djunits.value.vdouble.scalar.base.DoubleScalarRelWithAbs;
17  import org.djutils.base.NumberParser;
18  import org.djutils.exceptions.Throw;
19  
20  import jakarta.annotation.Generated;
21  
22  /**
23   * Easy access methods for the Relative Length DoubleScalar.
24   * <p>
25   * Copyright (c) 2013-2025 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. <br>
26   * All rights reserved. <br>
27   * BSD-style license. See <a href="https://djunits.org/docs/license.html">DJUNITS License</a>.
28   * </p>
29   * @author <a href="https://www.tudelft.nl/averbraeck">Alexander Verbraeck</a>
30   * @author <a href="https://www.tudelft.nl/staff/p.knoppers/">Peter Knoppers</a>
31   */
32  @Generated(value = "org.djunits.generator.GenerateDJUNIT", date = "2025-09-06T15:16:28.380798Z")
33  public class Length extends DoubleScalarRelWithAbs<PositionUnit, Position, LengthUnit, Length>
34  {
35      /** */
36      private static final long serialVersionUID = 20150901L;
37  
38      /** Constant with value zero. */
39      public static final Length ZERO = new Length(0.0, LengthUnit.SI);
40  
41      /** Constant with value one. */
42      public static final Length ONE = new Length(1.0, LengthUnit.SI);
43  
44      /** Constant with value NaN. */
45      @SuppressWarnings("checkstyle:constantname")
46      public static final Length NaN = new Length(Double.NaN, LengthUnit.SI);
47  
48      /** Constant with value POSITIVE_INFINITY. */
49      public static final Length POSITIVE_INFINITY = new Length(Double.POSITIVE_INFINITY, LengthUnit.SI);
50  
51      /** Constant with value NEGATIVE_INFINITY. */
52      public static final Length NEGATIVE_INFINITY = new Length(Double.NEGATIVE_INFINITY, LengthUnit.SI);
53  
54      /** Constant with value MAX_VALUE. */
55      public static final Length POS_MAXVALUE = new Length(Double.MAX_VALUE, LengthUnit.SI);
56  
57      /** Constant with value -MAX_VALUE. */
58      public static final Length NEG_MAXVALUE = new Length(-Double.MAX_VALUE, LengthUnit.SI);
59  
60      /**
61       * Construct Length scalar with a unit.
62       * @param value the double value, expressed in the given unit
63       * @param unit unit for the double value
64       */
65      public Length(final double value, final LengthUnit unit)
66      {
67          super(value, unit);
68      }
69  
70      /**
71       * Construct Length scalar.
72       * @param value Scalar from which to construct this instance
73       */
74      public Length(final Length value)
75      {
76          super(value);
77      }
78  
79      @Override
80      public final Length instantiateRel(final double value, final LengthUnit unit)
81      {
82          return new Length(value, unit);
83      }
84  
85      @Override
86      public final Position instantiateAbs(final double value, final PositionUnit unit)
87      {
88          return new Position(value, unit);
89      }
90  
91      /**
92       * Construct Length scalar based on an SI value.
93       * @param value the double value in SI units
94       * @return the new scalar with the SI value
95       */
96      public static final Length ofSI(final double value)
97      {
98          return new Length(value, LengthUnit.SI);
99      }
100 
101     /**
102      * Interpolate between two values. Note that the first value does not have to be smaller than the second.
103      * @param zero the value at a ratio of zero
104      * @param one the value at a ratio of one
105      * @param ratio the ratio between 0 and 1, inclusive
106      * @return a Length at the given ratio between 0 and 1
107      */
108     public static Length interpolate(final Length zero, final Length one, final double ratio)
109     {
110         Throw.when(ratio < 0.0 || ratio > 1.0, IllegalArgumentException.class,
111                 "ratio for interpolation should be between 0 and 1, but is %f", ratio);
112         return new Length(zero.getInUnit() * (1 - ratio) + one.getInUnit(zero.getDisplayUnit()) * ratio, zero.getDisplayUnit());
113     }
114 
115     /**
116      * Return the maximum value of two relative scalars.
117      * @param r1 the first scalar
118      * @param r2 the second scalar
119      * @return the maximum value of two relative scalars
120      */
121     public static Length max(final Length r1, final Length r2)
122     {
123         return r1.gt(r2) ? r1 : r2;
124     }
125 
126     /**
127      * Return the maximum value of more than two relative scalars.
128      * @param r1 the first scalar
129      * @param r2 the second scalar
130      * @param rn the other scalars
131      * @return the maximum value of more than two relative scalars
132      */
133     public static Length max(final Length r1, final Length r2, final Length... rn)
134     {
135         Length maxr = r1.gt(r2) ? r1 : r2;
136         for (Length r : rn)
137         {
138             if (r.gt(maxr))
139             {
140                 maxr = r;
141             }
142         }
143         return maxr;
144     }
145 
146     /**
147      * Return the minimum value of two relative scalars.
148      * @param r1 the first scalar
149      * @param r2 the second scalar
150      * @return the minimum value of two relative scalars
151      */
152     public static Length min(final Length r1, final Length r2)
153     {
154         return r1.lt(r2) ? r1 : r2;
155     }
156 
157     /**
158      * Return the minimum value of more than two relative scalars.
159      * @param r1 the first scalar
160      * @param r2 the second scalar
161      * @param rn the other scalars
162      * @return the minimum value of more than two relative scalars
163      */
164     public static Length min(final Length r1, final Length r2, final Length... rn)
165     {
166         Length minr = r1.lt(r2) ? r1 : r2;
167         for (Length r : rn)
168         {
169             if (r.lt(minr))
170             {
171                 minr = r;
172             }
173         }
174         return minr;
175     }
176 
177     /**
178      * Returns a Length representation of a textual representation of a value with a unit. The String representation that can be
179      * parsed is the double value in the unit, followed by a localized or English abbreviation of the unit. Spaces are allowed,
180      * but not required, between the value and the unit.
181      * @param text the textual representation to parse into a Length
182      * @return the Scalar representation of the value in its unit
183      * @throws IllegalArgumentException when the text cannot be parsed
184      * @throws NullPointerException when the text argument is null
185      */
186     public static Length valueOf(final String text)
187     {
188         Throw.whenNull(text, "Error parsing Length: text to parse is null");
189         Throw.when(text.length() == 0, IllegalArgumentException.class, "Error parsing Length: empty text to parse");
190         try
191         {
192             NumberParser numberParser = new NumberParser().lenient().trailing();
193             double d = numberParser.parseDouble(text);
194             String unitString = text.substring(numberParser.getTrailingPosition()).trim();
195             LengthUnit unit = LengthUnit.BASE.getUnitByAbbreviation(unitString);
196             Throw.when(unit == null, IllegalArgumentException.class, "Unit %s not found for quantity Length", unitString);
197             return new Length(d, unit);
198         }
199         catch (Exception exception)
200         {
201             throw new IllegalArgumentException(
202                     "Error parsing Length from " + text + " using Locale " + Locale.getDefault(Locale.Category.FORMAT),
203                     exception);
204         }
205     }
206 
207     /**
208      * Returns a Length based on a value and the textual representation of the unit, which can be localized.
209      * @param value the value to use
210      * @param unitString the textual representation of the unit
211      * @return the Scalar representation of the value in its unit
212      * @throws IllegalArgumentException when the unit cannot be parsed or is incorrect
213      * @throws NullPointerException when the unitString argument is null
214      */
215     public static Length of(final double value, final String unitString)
216     {
217         Throw.whenNull(unitString, "Error parsing Length: unitString is null");
218         Throw.when(unitString.length() == 0, IllegalArgumentException.class, "Error parsing Length: empty unitString");
219         LengthUnit unit = LengthUnit.BASE.getUnitByAbbreviation(unitString);
220         Throw.when(unit == null, IllegalArgumentException.class, "Error parsing Length with unit %s", unitString);
221         return new Length(value, unit);
222     }
223 
224     /**
225      * Calculate the division of Length and Length, which results in a Dimensionless scalar.
226      * @param v scalar
227      * @return scalar as a division of Length and Length
228      */
229     public final Dimensionless divide(final Length v)
230     {
231         return new Dimensionless(this.si / v.si, DimensionlessUnit.SI);
232     }
233 
234     /**
235      * Calculate the multiplication of Length and LinearDensity, which results in a Dimensionless scalar.
236      * @param v scalar
237      * @return scalar as a multiplication of Length and LinearDensity
238      */
239     public final Dimensionless times(final LinearDensity v)
240     {
241         return new Dimensionless(this.si * v.si, DimensionlessUnit.SI);
242     }
243 
244     /**
245      * Calculate the multiplication of Length and Length, which results in a Area scalar.
246      * @param v scalar
247      * @return scalar as a multiplication of Length and Length
248      */
249     public final Area times(final Length v)
250     {
251         return new Area(this.si * v.si, AreaUnit.SI);
252     }
253 
254     /**
255      * Calculate the division of Length and LinearDensity, which results in a Area scalar.
256      * @param v scalar
257      * @return scalar as a division of Length and LinearDensity
258      */
259     public final Area divide(final LinearDensity v)
260     {
261         return new Area(this.si / v.si, AreaUnit.SI);
262     }
263 
264     /**
265      * Calculate the division of Length and Area, which results in a LinearDensity scalar.
266      * @param v scalar
267      * @return scalar as a division of Length and Area
268      */
269     public final LinearDensity divide(final Area v)
270     {
271         return new LinearDensity(this.si / v.si, LinearDensityUnit.SI);
272     }
273 
274     /**
275      * Calculate the multiplication of Length and Area, which results in a Volume scalar.
276      * @param v scalar
277      * @return scalar as a multiplication of Length and Area
278      */
279     public final Volume times(final Area v)
280     {
281         return new Volume(this.si * v.si, VolumeUnit.SI);
282     }
283 
284     /**
285      * Calculate the multiplication of Length and Force, which results in a Energy scalar.
286      * @param v scalar
287      * @return scalar as a multiplication of Length and Force
288      */
289     public final Energy times(final Force v)
290     {
291         return new Energy(this.si * v.si, EnergyUnit.SI);
292     }
293 
294     /**
295      * Calculate the multiplication of Length and Frequency, which results in a Speed scalar.
296      * @param v scalar
297      * @return scalar as a multiplication of Length and Frequency
298      */
299     public final Speed times(final Frequency v)
300     {
301         return new Speed(this.si * v.si, SpeedUnit.SI);
302     }
303 
304     /**
305      * Calculate the division of Length and Duration, which results in a Speed scalar.
306      * @param v scalar
307      * @return scalar as a division of Length and Duration
308      */
309     public final Speed divide(final Duration v)
310     {
311         return new Speed(this.si / v.si, SpeedUnit.SI);
312     }
313 
314     /**
315      * Calculate the division of Length and Speed, which results in a Duration scalar.
316      * @param v scalar
317      * @return scalar as a division of Length and Speed
318      */
319     public final Duration divide(final Speed v)
320     {
321         return new Duration(this.si / v.si, DurationUnit.SI);
322     }
323 
324     /**
325      * Calculate the multiplication of Length and FlowMass, which results in a Momentum scalar.
326      * @param v scalar
327      * @return scalar as a multiplication of Length and FlowMass
328      */
329     public final Momentum times(final FlowMass v)
330     {
331         return new Momentum(this.si * v.si, MomentumUnit.SI);
332     }
333 
334     @Override
335     public LinearDensity reciprocal()
336     {
337         return LinearDensity.ofSI(1.0 / this.si);
338     }
339 
340     /**
341      * Multiply two scalars that result in a scalar of type Length.
342      * @param scalar1 the first scalar
343      * @param scalar2 the second scalar
344      * @return the multiplication of both scalars as an instance of Length
345      */
346     public static Length multiply(final DoubleScalarRel<?, ?> scalar1, final DoubleScalarRel<?, ?> scalar2)
347     {
348         Throw.whenNull(scalar1, "scalar1 cannot be null");
349         Throw.whenNull(scalar2, "scalar2 cannot be null");
350         Throw.when(!scalar1.getDisplayUnit().getQuantity().getSiDimensions()
351                 .plus(scalar2.getDisplayUnit().getQuantity().getSiDimensions()).equals(LengthUnit.BASE.getSiDimensions()),
352                 IllegalArgumentException.class, "Multiplying %s by %s does not result in instance of type Length",
353                 scalar1.toDisplayString(), scalar2.toDisplayString());
354         return new Length(scalar1.si * scalar2.si, LengthUnit.SI);
355     }
356 
357     /**
358      * Divide two scalars that result in a scalar of type Length.
359      * @param scalar1 the first scalar
360      * @param scalar2 the second scalar
361      * @return the division of scalar1 by scalar2 as an instance of Length
362      */
363     public static Length divide(final DoubleScalarRel<?, ?> scalar1, final DoubleScalarRel<?, ?> scalar2)
364     {
365         Throw.whenNull(scalar1, "scalar1 cannot be null");
366         Throw.whenNull(scalar2, "scalar2 cannot be null");
367         Throw.when(!scalar1.getDisplayUnit().getQuantity().getSiDimensions()
368                 .minus(scalar2.getDisplayUnit().getQuantity().getSiDimensions()).equals(LengthUnit.BASE.getSiDimensions()),
369                 IllegalArgumentException.class, "Dividing %s by %s does not result in an instance of type Length",
370                 scalar1.toDisplayString(), scalar2.toDisplayString());
371         return new Length(scalar1.si / scalar2.si, LengthUnit.SI);
372     }
373 
374 }