View Javadoc
1   package org.djunits.quantity;
2   
3   import org.djunits.quantity.def.Quantity;
4   import org.djunits.unit.AbstractUnit;
5   import org.djunits.unit.UnitInterface;
6   import org.djunits.unit.UnitRuntimeException;
7   import org.djunits.unit.Unitless;
8   import org.djunits.unit.scale.IdentityScale;
9   import org.djunits.unit.scale.LinearScale;
10  import org.djunits.unit.scale.Scale;
11  import org.djunits.unit.si.SIPrefix;
12  import org.djunits.unit.si.SIUnit;
13  import org.djunits.unit.system.UnitSystem;
14  
15  /**
16   * Speed is the rate of change of position over time.
17   * <p>
18   * Copyright (c) 2025-2026 Delft University of Technology, Jaffalaan 5, 2628 BX Delft, the Netherlands. All rights reserved. See
19   * for project information <a href="https://djunits.org" target="_blank">https://djunits.org</a>. The DJUNITS project is
20   * distributed under a <a href="https://djunits.org/docs/license.html" target="_blank">three-clause BSD-style license</a>.
21   * @author Alexander Verbraeck
22   */
23  public class Speed extends Quantity<Speed>
24  {
25      /** Constant with value zero. */
26      public static final Speed ZERO = ofSi(0.0);
27  
28      /** Constant with value one. */
29      public static final Speed ONE = ofSi(1.0);
30  
31      /** Constant with value NaN. */
32      @SuppressWarnings("checkstyle:constantname")
33      public static final Speed NaN = ofSi(Double.NaN);
34  
35      /** Constant with value POSITIVE_INFINITY. */
36      public static final Speed POSITIVE_INFINITY = ofSi(Double.POSITIVE_INFINITY);
37  
38      /** Constant with value NEGATIVE_INFINITY. */
39      public static final Speed NEGATIVE_INFINITY = ofSi(Double.NEGATIVE_INFINITY);
40  
41      /** Constant with value MAX_VALUE. */
42      public static final Speed POS_MAXVALUE = ofSi(Double.MAX_VALUE);
43  
44      /** Constant with value -MAX_VALUE. */
45      public static final Speed NEG_MAXVALUE = ofSi(-Double.MAX_VALUE);
46  
47      /** */
48      private static final long serialVersionUID = 600L;
49  
50      /**
51       * Instantiate a Speed quantity with an SI or base value and a display unit.
52       * @param value the quantity value expressed in the SI or base unit
53       * @param displayUnit the display unit to use
54       * @param useSi use SI value when true, use value in unit when false
55       */
56      public Speed(final double value, final Speed.Unit displayUnit, final boolean useSi)
57      {
58          super(value, displayUnit, useSi);
59      }
60  
61      /**
62       * Instantiate a Speed quantity expressed in the given unit.
63       * @param valueInUnit the quantity value expressed in the given unit
64       * @param unit the unit of the value, also acts as the display unit
65       */
66      public Speed(final double valueInUnit, final Speed.Unit unit)
67      {
68          this(valueInUnit, unit, false);
69      }
70  
71      /**
72       * Return a Speed instance based on an SI value.
73       * @param si the si value
74       * @return the Speed instance based on an SI value
75       */
76      public static Speed ofSi(final double si)
77      {
78          return new Speed(si, Speed.Unit.SI, true);
79      }
80  
81      /**
82       * Instantiate a Speed quantity with an SI or base value and a display unit.
83       * @param siValue the quantity value expressed in the SI or base unit
84       * @param displayUnit the display unit to use
85       * @return the Speed instance based on an SI value with the given display unit
86       */
87      public static Speed ofSi(final double siValue, final Speed.Unit displayUnit)
88      {
89          return new Speed(siValue, displayUnit, true);
90      }
91  
92      @Override
93      public Speed instantiateSi(final double siValue, final UnitInterface<Speed> displayUnit)
94      {
95          return new Speed(siValue, (Speed.Unit) displayUnit, true);
96      }
97  
98      /**
99       * Returns a Speed representation of a textual representation of a value with a unit. The String representation that can be
100      * parsed is the double value in the unit, followed by a localized or English abbreviation of the unit. Spaces are allowed,
101      * but not required, between the value and the unit.
102      * @param text the textual representation to parse into a Speed
103      * @return the Scalar representation of the value in its unit
104      * @throws IllegalArgumentException when the text cannot be parsed
105      * @throws NullPointerException when the text argument is null
106      */
107     public static Speed valueOf(final String text)
108     {
109         return Quantity.valueOf(text, ZERO);
110     }
111 
112     /**
113      * Returns a Speed based on a value expressed in the unit.
114      * @param valueInUnit the value, expressed in the given unit
115      * @param unit the unit of the value, also acts as the display unit
116      * @return ab Speed representation of the value in its unit
117      */
118     public static Speed of(final double valueInUnit, final Speed.Unit unit)
119     {
120         return new Speed(valueInUnit, unit);
121     }
122 
123     /**
124      * Returns a Speed based on a value and the textual representation of the unit, which can be localized.
125      * @param valueInUnit the value, expressed in the unit as given by unitString
126      * @param unitString the textual representation of the unit
127      * @return the Scalar representation of the value in its unit
128      * @throws IllegalArgumentException when the unit cannot be parsed or is incorrect
129      * @throws NullPointerException when the unitString argument is null
130      */
131     public static Speed of(final double valueInUnit, final String unitString)
132     {
133         return Quantity.of(valueInUnit, unitString, ZERO);
134     }
135 
136     @Override
137     public Speed.Unit getDisplayUnit()
138     {
139         return (Speed.Unit) super.getDisplayUnit();
140     }
141 
142     /**
143      * Calculate the division of Speed and Speed, which results in a Dimensionless scalar.
144      * @param v scalar
145      * @return scalar as a division of Speed and Speed
146      */
147     public Dimensionless divide(final Speed v)
148     {
149         return new Dimensionless(this.si() / v.si(), Unitless.BASE);
150     }
151 
152     /**
153      * Calculate the multiplication of Speed and Area, which results in a FlowVolume scalar.
154      * @param v scalar
155      * @return scalar as a multiplication of Speed and Area
156      */
157     public FlowVolume multiply(final Area v)
158     {
159         return new FlowVolume(this.si() * v.si(), FlowVolume.Unit.SI);
160     }
161 
162     /**
163      * Calculate the multiplication of Speed and Force, which results in a Power scalar.
164      * @param v scalar
165      * @return scalar as a multiplication of Speed and Force
166      */
167     public Power multiply(final Force v)
168     {
169         return new Power(this.si() * v.si(), Power.Unit.SI);
170     }
171 
172     /**
173      * Calculate the multiplication of Speed and Frequency, which results in a Acceleration scalar.
174      * @param v scalar
175      * @return scalar as a multiplication of Speed and Frequency
176      */
177     public Acceleration multiply(final Frequency v)
178     {
179         return new Acceleration(this.si() * v.si(), Acceleration.Unit.SI);
180     }
181 
182     /**
183      * Calculate the division of Speed and Length, which results in a Frequency scalar.
184      * @param v scalar
185      * @return scalar as a division of Speed and Length
186      */
187     public Frequency divide(final Length v)
188     {
189         return new Frequency(this.si() / v.si(), Frequency.Unit.SI);
190     }
191 
192     /**
193      * Calculate the division of Speed and Frequency, which results in a Length scalar.
194      * @param v scalar
195      * @return scalar as a division of Speed and Frequency
196      */
197     public Length divide(final Frequency v)
198     {
199         return new Length(this.si() / v.si(), Length.Unit.SI);
200     }
201 
202     /**
203      * Calculate the multiplication of Speed and LinearObjectDensity, which results in a Frequency scalar.
204      * @param v scalar
205      * @return scalar as a multiplication of Speed and LinearObjectDensity
206      */
207     public Frequency multiply(final LinearObjectDensity v)
208     {
209         return new Frequency(this.si() * v.si(), Frequency.Unit.SI);
210     }
211 
212     /**
213      * Calculate the multiplication of Speed and Duration, which results in a Length scalar.
214      * @param v scalar
215      * @return scalar as a multiplication of Speed and Duration
216      */
217     public Length multiply(final Duration v)
218     {
219         return new Length(this.si() * v.si(), Length.Unit.SI);
220     }
221 
222     /**
223      * Calculate the division of Speed and Duration, which results in a Acceleration scalar.
224      * @param v scalar
225      * @return scalar as a division of Speed and Duration
226      */
227     public Acceleration divide(final Duration v)
228     {
229         return new Acceleration(this.si() / v.si(), Acceleration.Unit.SI);
230     }
231 
232     /**
233      * Calculate the division of Speed and Acceleration, which results in a Duration scalar.
234      * @param v scalar
235      * @return scalar as a division of Speed and Acceleration
236      */
237     public Duration divide(final Acceleration v)
238     {
239         return new Duration(this.si() / v.si(), Duration.Unit.SI);
240     }
241 
242     /**
243      * Calculate the multiplication of Speed and FlowMass, which results in a Force scalar.
244      * @param v scalar
245      * @return scalar as a multiplication of Speed and FlowMass
246      */
247     public Force multiply(final FlowMass v)
248     {
249         return new Force(this.si() * v.si(), Force.Unit.SI);
250     }
251 
252     /**
253      * Calculate the multiplication of Speed and Mass, which results in a Momentum scalar.
254      * @param v scalar
255      * @return scalar as a multiplication of Speed and Mass
256      */
257     public Momentum multiply(final Mass v)
258     {
259         return new Momentum(this.si() * v.si(), Momentum.Unit.SI);
260     }
261 
262     /**
263      * Calculate the multiplication of Speed and Momentum, which results in a Energy scalar.
264      * @param v scalar
265      * @return scalar as a multiplication of Speed and Momentum
266      */
267     public Energy multiply(final Momentum v)
268     {
269         return new Energy(this.si() * v.si(), Energy.Unit.SI);
270     }
271 
272     /******************************************************************************************************/
273     /********************************************** UNIT CLASS ********************************************/
274     /******************************************************************************************************/
275 
276     /**
277      * Speed.Unit encodes the units of the rate of change of a position over time.
278      * <p>
279      * Copyright (c) 2025-2026 Delft University of Technology, Jaffalaan 5, 2628 BX Delft, the Netherlands. All rights reserved.
280      * See for project information <a href="https://djunits.org" target="_blank">https://djunits.org</a>. The DJUNITS project is
281      * distributed under a <a href="https://djunits.org/docs/license.html" target="_blank">three-clause BSD-style license</a>.
282      * @author Alexander Verbraeck
283      */
284     @SuppressWarnings("checkstyle:constantname")
285     public static class Unit extends AbstractUnit<Speed>
286     {
287         /** The dimensions of Speed: m/s. */
288         public static final SIUnit SI_UNIT = SIUnit.of("m/s");
289 
290         /** Meter per second. */
291         public static final Speed.Unit m_s =
292                 new Speed.Unit("m/s", "m/s", "meter per second", IdentityScale.SCALE, UnitSystem.SI_DERIVED, null);
293 
294         /** The SI or BASE unit. */
295         public static final Speed.Unit SI = m_s;
296 
297         /** m/h. */
298         public static final Speed.Unit m_h =
299                 new Speed.Unit("m/h", "m/h", "meter per hour", new LinearScale(1.0, 3600.0), UnitSystem.SI_ACCEPTED, null);
300 
301         /** km/s. */
302         public static final Speed.Unit km_s =
303                 new Speed.Unit("km/s", "km/s", "kilometer per second", new LinearScale(1000.0), UnitSystem.SI_ACCEPTED, null);
304 
305         /** km/h. */
306         public static final Speed.Unit km_h = new Speed.Unit("km/h", "km/h", "kilometer per hour",
307                 new LinearScale(1000.0, 3600.0), UnitSystem.SI_ACCEPTED, null);
308 
309         /** in/s. */
310         public static final Speed.Unit in_s = new Speed.Unit("in/s", "in/s", "inch per second",
311                 new LinearScale(Length.Unit.CONST_IN), UnitSystem.IMPERIAL, null);
312 
313         /** in/min. */
314         public static final Speed.Unit in_min = new Speed.Unit("in/min", "in/min", "inch per minute",
315                 new LinearScale(Length.Unit.CONST_IN, 60.0), UnitSystem.IMPERIAL, null);
316 
317         /** in/h. */
318         public static final Speed.Unit in_h = new Speed.Unit("in/h", "in/h", "inch per hour",
319                 new LinearScale(Length.Unit.CONST_IN, 3600.0), UnitSystem.IMPERIAL, null);
320 
321         /** ft/s. */
322         public static final Speed.Unit ft_s = new Speed.Unit("ft/s", "ft/s", "foot per second",
323                 new LinearScale(Length.Unit.CONST_FT), UnitSystem.IMPERIAL, null);
324 
325         /** ft/min. */
326         public static final Speed.Unit ft_min = new Speed.Unit("ft/min", "ft/min", "foot per minute",
327                 new LinearScale(Length.Unit.CONST_FT, 60.0), UnitSystem.IMPERIAL, null);
328 
329         /** ft/h. */
330         public static final Speed.Unit ft_h = new Speed.Unit("ft/h", "ft/h", "foot per hour",
331                 new LinearScale(Length.Unit.CONST_FT, 3600.0), UnitSystem.IMPERIAL, null);
332 
333         /** mi/s. */
334         public static final Speed.Unit mi_s = new Speed.Unit("mi/s", "mi/s", "mile per second",
335                 new LinearScale(Length.Unit.CONST_MI), UnitSystem.IMPERIAL, null);
336 
337         /** mi/min. */
338         public static final Speed.Unit mi_min = new Speed.Unit("mi/min", "mi/min", "mile per minute",
339                 new LinearScale(Length.Unit.CONST_MI, 60.0), UnitSystem.IMPERIAL, null);
340 
341         /** mi/h. */
342         public static final Speed.Unit mi_h = new Speed.Unit("mi/h", "mi/h", "mile per hour",
343                 new LinearScale(Length.Unit.CONST_MI, 3600.0), UnitSystem.IMPERIAL, null);
344 
345         /** knot = Nautical Mile per hour. */
346         public static final Speed.Unit kt = new Speed.Unit("kt", "knot", Length.Unit.CONST_NM / 3600.0, UnitSystem.OTHER);
347 
348         /**
349          * Create a new Speed unit.
350          * @param id the id or main abbreviation of the unit
351          * @param name the full name of the unit
352          * @param scaleFactorToBaseUnit the scale factor of the unit to convert it TO the base (SI) unit
353          * @param unitSystem the unit system such as SI or IMPERIAL
354          */
355         public Unit(final String id, final String name, final double scaleFactorToBaseUnit, final UnitSystem unitSystem)
356         {
357             super(id, name, scaleFactorToBaseUnit, unitSystem);
358         }
359 
360         /**
361          * Return a derived unit for this unit, with textual abbreviation(s) and a display abbreviation.
362          * @param textualAbbreviation the textual abbreviation of the unit, which doubles as the id
363          * @param displayAbbreviation the display abbreviation of the unit
364          * @param name the full name of the unit
365          * @param scale the scale to use to convert from this unit to the standard (e.g., SI, BASE) unit
366          * @param unitSystem unit system, e.g. SI or Imperial
367          * @param siPrefix the SI Prefix of this unit
368          */
369         public Unit(final String textualAbbreviation, final String displayAbbreviation, final String name, final Scale scale,
370                 final UnitSystem unitSystem, final SIPrefix siPrefix)
371         {
372             super(textualAbbreviation, displayAbbreviation, name, scale, unitSystem, siPrefix);
373         }
374 
375         @Override
376         public SIUnit siUnit()
377         {
378             return SI_UNIT;
379         }
380 
381         @Override
382         public Unit getBaseUnit()
383         {
384             return SI;
385         }
386 
387         @Override
388         public Speed ofSi(final double si, final UnitInterface<Speed> displayUnit)
389         {
390             return new Speed(si, (Unit) displayUnit, true);
391         }
392 
393         @Override
394         public Speed.Unit deriveUnit(final String abbreviation, final String name, final double scaleFactor,
395                 final UnitSystem unitSystem)
396         {
397             return (Speed.Unit) super.deriveUnit(abbreviation, name, scaleFactor, unitSystem);
398         }
399 
400         @Override
401         public Speed.Unit deriveUnit(final String textualAbbreviation, final String displayAbbreviation, final String name,
402                 final double scaleFactor, final UnitSystem unitSystem, final SIPrefix siPrefix)
403         {
404             if (getScale() instanceof LinearScale ls)
405             {
406                 return new Speed.Unit(textualAbbreviation, displayAbbreviation, name,
407                         new LinearScale(ls.getScaleFactorToBaseUnit() * scaleFactor), unitSystem, siPrefix);
408             }
409             throw new UnitRuntimeException("Only possible to derive a unit from a unit with a linear scale");
410         }
411 
412     }
413 
414 }