1 package org.djunits.vecmat.d3;
2
3 import org.djunits.quantity.def.AbsQuantity;
4 import org.djunits.quantity.def.Quantity;
5 import org.djunits.quantity.def.Reference;
6 import org.djunits.unit.Unit;
7 import org.djunits.vecmat.def.AbsVector;
8 import org.djutils.exceptions.Throw;
9
10 /**
11 * AbsVector3 implements a vector with three real-valued entries representing an absolute quantity. The vector is immutable,
12 * except for the display unit, which can be changed. Some of the method that have been defined already for a generic vector can
13 * be re-implemented for efficiency.
14 * <p>
15 * Copyright (c) 2026-2026 Delft University of Technology, Jaffalaan 5, 2628 BX Delft, the Netherlands. All rights reserved. See
16 * for project information <a href="https://djunits.org" target="_blank">https://djunits.org</a>. The DJUNITS project is
17 * distributed under a <a href="https://djunits.org/docs/license.html" target="_blank">three-clause BSD-style license</a>.
18 * @author Alexander Verbraeck
19 * @param <A> the absolute quantity type
20 * @param <Q> the corresponding relative quantity type
21 * @param <VA> the absolute vector or matrix type
22 * @param <VQ> the relative vector or matrix type
23 * @param <VAT> the type of the transposed version of the absolute vector
24 */
25 public abstract class AbsVector3<A extends AbsQuantity<A, Q, ?>, Q extends Quantity<Q>,
26 VA extends AbsVector3<A, Q, VA, VQ, VAT>, VQ extends Vector3<Q, VQ, ?, ?, ?>, VAT extends AbsVector3<A, Q, VAT, ?, VA>>
27 extends AbsVector<A, Q, VA, VQ, VAT>
28 {
29 /** */
30 private static final long serialVersionUID = 600L;
31
32 /**
33 * Instantiate an AbsVector3.
34 * @param relativeVector the vector with values relative to the reference point
35 * @param reference the reference point for the absolute values
36 */
37 public AbsVector3(final VQ relativeVector, final Reference<?, A, Q> reference)
38 {
39 super(relativeVector, reference);
40 }
41
42 /**
43 * Column vector for AbsVector3 with absolute quantities.
44 * <p>
45 * Copyright (c) 2026-2026 Delft University of Technology, Jaffalaan 5, 2628 BX Delft, the Netherlands. All rights reserved.
46 * See for project information <a href="https://djunits.org" target="_blank">https://djunits.org</a>. The DJUNITS project is
47 * distributed under a <a href="https://djunits.org/docs/license.html" target="_blank">three-clause BSD-style license</a>.
48 * @author Alexander Verbraeck
49 * @param <A> the absolute quantity type
50 * @param <Q> the corresponding relative quantity type
51 */
52 public static class Col<A extends AbsQuantity<A, Q, ?>, Q extends Quantity<Q>>
53 extends AbsVector3<A, Q, AbsVector3.Col<A, Q>, Vector3.Col<Q>, AbsVector3.Row<A, Q>>
54 implements AbsVector.Col<AbsVector3.Col<A, Q>, Q>
55 {
56 /** */
57 private static final long serialVersionUID = 600L;
58
59 /**
60 * Create a new AbsVector3 with absolute quantities, with a display unit and a reference point.
61 * @param relativeVector the vector with values relative to the reference point
62 * @param reference the reference point for the absolute values
63 */
64 public Col(final Vector3.Col<Q> relativeVector, final Reference<?, A, Q> reference)
65 {
66 super(relativeVector, reference);
67 }
68
69 @Override
70 public AbsVector3.Col<A, Q> instantiate(final Vector3.Col<Q> relativeVector, final Reference<?, A, Q> reference)
71 {
72 return new AbsVector3.Col<>(relativeVector, reference).setDisplayUnit(getDisplayUnit());
73 }
74
75 @Override
76 public AbsVector3.Row<A, Q> transpose()
77 {
78 return new AbsVector3.Row<>(getRelativeVecMat().transpose(), getReference());
79 }
80
81 // ------------------------------------------ OF METHODS ------------------------------------------
82
83 /**
84 * Create a AbsVector3.Col without needing generics.
85 * @param xInUnit the x-value expressed in the unit
86 * @param yInUnit the y-value expressed in the unit
87 * @param zInUnit the z-value expressed in the unit
88 * @param unit the unit of the data, which will also be used as the display unit
89 * @param reference the reference point for the absolute quantities
90 * @return a new AbsVector3.Col with a unit
91 * @param <A> the absolute quantity type
92 * @param <Q> the quantity type
93 * @param <R> the reference type
94 */
95 public static <A extends AbsQuantity<A, Q, R>, Q extends Quantity<Q>,
96 R extends Reference<R, A, Q>> AbsVector3.Col<A, Q> of(final double xInUnit, final double yInUnit,
97 final double zInUnit, final Unit<?, Q> unit, final R reference)
98 {
99 return new AbsVector3.Col<>(Vector3.Col.of(xInUnit, yInUnit, zInUnit, unit), reference);
100 }
101
102 /**
103 * Create a AbsVector3.Col without needing generics. The display unit will be taken from the x-quantity.
104 * @param x the x-value expressed as a quantity
105 * @param y the y-value expressed as a quantity
106 * @param z the z-value expressed as a quantity
107 * @param reference the reference point for the absolute quantities
108 * @return a new AbsVector3.Col with a unit
109 * @param <A> the absolute quantity type
110 * @param <Q> the quantity type
111 * @param <R> the reference type
112 */
113 public static <A extends AbsQuantity<A, Q, R>, Q extends Quantity<Q>,
114 R extends Reference<R, A, Q>> AbsVector3.Col<A, Q> of(final Q x, final Q y, final Q z, final R reference)
115 {
116 return new AbsVector3.Col<>(Vector3.Col.of(x, y, z), reference);
117 }
118
119 /**
120 * Create an AbsVector3.Col without needing generics.
121 * @param absX the v1-value expressed as an absolute quantity
122 * @param absY the v2-value expressed as an absolute quantity
123 * @param absZ the v3-value expressed as an absolute quantity
124 * @return a new AbsVector3.Col with a unit
125 * @param <A> the absolute quantity type
126 * @param <Q> the quantity type
127 * @param <R> the reference type
128 */
129 public static <A extends AbsQuantity<A, Q, R>, Q extends Quantity<Q>,
130 R extends Reference<R, A, Q>> AbsVector3.Col<A, Q> of(final A absX, final A absY, final A absZ)
131 {
132 Throw.whenNull(absX, "absX");
133 Throw.whenNull(absY, "absY");
134 Throw.whenNull(absZ, "absZ");
135 Throw.when(!absX.getReference().equals(absY.getReference()), IllegalArgumentException.class,
136 "absX.reference != absY.reference");
137 Throw.when(!absX.getReference().equals(absZ.getReference()), IllegalArgumentException.class,
138 "absX.reference != absZ.reference");
139 return new AbsVector3.Col<>(Vector3.Col.of(absX.getQuantity(), absY.getQuantity(), absZ.getQuantity()),
140 absX.getReference());
141 }
142
143 /**
144 * Create a AbsVector3.Col without needing generics.
145 * @param dataInUnit the vector entries expressed as an array in the unit
146 * @param unit the unit of the data, which will also be used as the display unit
147 * @param reference the reference point for the absolute quantities
148 * @return a new AbsVector3.Col with a unit
149 * @param <A> the absolute quantity type
150 * @param <Q> the quantity type
151 * @param <R> the reference type
152 */
153 public static <A extends AbsQuantity<A, Q, R>, Q extends Quantity<Q>,
154 R extends Reference<R, A, Q>> AbsVector3.Col<A, Q> of(final double[] dataInUnit, final Unit<?, Q> unit,
155 final R reference)
156 {
157 return new AbsVector3.Col<>(Vector3.Col.of(dataInUnit, unit), reference);
158 }
159
160 /**
161 * Create a AbsVector3.Col without needing generics.
162 * @param dataSi the vector entries expressed as an array in the SI units
163 * @param displayUnit the display unit to use
164 * @param reference the reference point for the absolute quantities
165 * @return a new AbsVector3.Col with a unit
166 * @param <A> the absolute quantity type
167 * @param <Q> the quantity type
168 * @param <R> the reference type
169 */
170 public static <A extends AbsQuantity<A, Q, R>, Q extends Quantity<Q>,
171 R extends Reference<R, A, Q>> AbsVector3.Col<A, Q> ofSi(final double[] dataSi, final Unit<?, Q> displayUnit,
172 final R reference)
173 {
174 return new AbsVector3.Col<>(Vector3.Col.ofSi(dataSi, displayUnit), reference);
175 }
176
177 /**
178 * Create a AbsVector3.Col without needing generics.
179 * @param xSi the x vector entry expressed in the SI unit
180 * @param ySi the y vector entry expressed in the SI unit
181 * @param zSi the z vector entry expressed in the SI unit
182 * @param displayUnit the display unit to use
183 * @param reference the reference point for the absolute quantities
184 * @return a new AbsVector3.Col with a unit
185 * @param <A> the absolute quantity type
186 * @param <Q> the quantity type
187 * @param <R> the reference type
188 */
189 public static <A extends AbsQuantity<A, Q, R>, Q extends Quantity<Q>,
190 R extends Reference<R, A, Q>> AbsVector3.Col<A, Q> ofSi(final double xSi, final double ySi, final double zSi,
191 final Unit<?, Q> displayUnit, final R reference)
192 {
193 return new AbsVector3.Col<>(Vector3.Col.ofSi(xSi, ySi, zSi, displayUnit), reference);
194 }
195
196 /**
197 * Create a AbsVector3.Col without needing generics. The display unit will be taken from the first quantity in the
198 * array.
199 * @param data the vector entries expressed as an array of quantities
200 * @param reference the reference point for the absolute quantities
201 * @return a new AbsVector3.Col with a unit
202 * @param <A> the absolute quantity type
203 * @param <Q> the quantity type
204 * @param <R> the reference type
205 */
206 public static <A extends AbsQuantity<A, Q, R>, Q extends Quantity<Q>,
207 R extends Reference<R, A, Q>> AbsVector3.Col<A, Q> of(final Q[] data, final R reference)
208 {
209 return new AbsVector3.Col<>(Vector3.Col.of(data), reference);
210 }
211
212 /**
213 * Create an AbsVector3.Col without needing generics.
214 * @param absData the {x, y} value expressed as an array of absolute quantities
215 * @return a new AbsVector3.Col with a unit
216 * @param <A> the absolute quantity type
217 * @param <Q> the quantity type
218 * @param <R> the reference type
219 */
220 public static <A extends AbsQuantity<A, Q, R>, Q extends Quantity<Q>,
221 R extends Reference<R, A, Q>> AbsVector3.Col<A, Q> of(final A[] absData)
222 {
223 Throw.whenNull(absData, "absData");
224 Throw.when(absData.length != 3, IllegalArgumentException.class, "absData.length != 3");
225 return AbsVector3.Col.of(absData[0], absData[1], absData[2]);
226 }
227
228 /**
229 * Create an AbsVector3.Col without needing generics.
230 * @param relativeVector the relative vector
231 * @param reference the reference point for the absolute quantities
232 * @return a new AbsVector3.Col with a unit
233 * @param <A> the absolute quantity type
234 * @param <Q> the quantity type
235 * @param <R> the reference type
236 */
237 public static <A extends AbsQuantity<A, Q, R>, Q extends Quantity<Q>,
238 R extends Reference<R, A, Q>> AbsVector3.Col<A, Q> of(final Vector3.Col<Q> relativeVector, final R reference)
239 {
240 Throw.whenNull(relativeVector, "relativeVector");
241 return new AbsVector3.Col<>(relativeVector, reference);
242 }
243 }
244
245 /**
246 * Row vector for AbsVector3 with absolute quantities.
247 * <p>
248 * Copyright (c) 2026-2026 Delft University of Technology, Jaffalaan 5, 2628 BX Delft, the Netherlands. All rights reserved.
249 * See for project information <a href="https://djunits.org" target="_blank">https://djunits.org</a>. The DJUNITS project is
250 * distributed under a <a href="https://djunits.org/docs/license.html" target="_blank">three-clause BSD-style license</a>.
251 * @author Alexander Verbraeck
252 * @param <A> the absolute quantity type
253 * @param <Q> the corresponding relative quantity type
254 */
255 public static class Row<A extends AbsQuantity<A, Q, ?>, Q extends Quantity<Q>>
256 extends AbsVector3<A, Q, AbsVector3.Row<A, Q>, Vector3.Row<Q>, AbsVector3.Col<A, Q>>
257 implements AbsVector.Row<AbsVector3.Row<A, Q>, Q>
258 {
259 /** */
260 private static final long serialVersionUID = 600L;
261
262 /**
263 * Create a new AbsVector3 with absolute quantities, with a display unit and a reference point.
264 * @param relativeVector the vector with values relative to the reference point
265 * @param reference the reference point for the absolute values
266 */
267 public Row(final Vector3.Row<Q> relativeVector, final Reference<?, A, Q> reference)
268 {
269 super(relativeVector, reference);
270 }
271
272 @Override
273 public AbsVector3.Row<A, Q> instantiate(final Vector3.Row<Q> relativeVector, final Reference<?, A, Q> reference)
274 {
275 return new AbsVector3.Row<>(relativeVector, reference).setDisplayUnit(getDisplayUnit());
276 }
277
278 @Override
279 public AbsVector3.Col<A, Q> transpose()
280 {
281 return new AbsVector3.Col<>(getRelativeVecMat().transpose(), getReference());
282 }
283
284 // ------------------------------------------ OF METHODS ------------------------------------------
285
286 /**
287 * Create a AbsVector3.Row without needing generics.
288 * @param xInUnit the x-value expressed in the unit
289 * @param yInUnit the y-value expressed in the unit
290 * @param zInUnit the z-value expressed in the unit
291 * @param unit the unit of the data, which will also be used as the display unit
292 * @param reference the reference point for the absolute quantities
293 * @return a new AbsVector3.Row with a unit
294 * @param <A> the absolute quantity type
295 * @param <Q> the quantity type
296 * @param <R> the reference type
297 */
298 public static <A extends AbsQuantity<A, Q, R>, Q extends Quantity<Q>,
299 R extends Reference<R, A, Q>> AbsVector3.Row<A, Q> of(final double xInUnit, final double yInUnit,
300 final double zInUnit, final Unit<?, Q> unit, final R reference)
301 {
302 return new AbsVector3.Row<>(Vector3.Row.of(xInUnit, yInUnit, zInUnit, unit), reference);
303 }
304
305 /**
306 * Create a AbsVector3.Row without needing generics. The display unit will be taken from the x-quantity.
307 * @param x the x-value expressed as a quantity
308 * @param y the y-value expressed as a quantity
309 * @param z the z-value expressed as a quantity
310 * @param reference the reference point for the absolute quantities
311 * @return a new AbsVector3.Row with a unit
312 * @param <A> the absolute quantity type
313 * @param <Q> the quantity type
314 * @param <R> the reference type
315 */
316 public static <A extends AbsQuantity<A, Q, R>, Q extends Quantity<Q>,
317 R extends Reference<R, A, Q>> AbsVector3.Row<A, Q> of(final Q x, final Q y, final Q z, final R reference)
318 {
319 return new AbsVector3.Row<>(Vector3.Row.of(x, y, z), reference);
320 }
321
322 /**
323 * Create an AbsVector3.Row without needing generics.
324 * @param absX the v1-value expressed as an absolute quantity
325 * @param absY the v2-value expressed as an absolute quantity
326 * @param absZ the v3-value expressed as an absolute quantity
327 * @return a new AbsVector3.Row with a unit
328 * @param <A> the absolute quantity type
329 * @param <Q> the quantity type
330 * @param <R> the reference type
331 */
332 public static <A extends AbsQuantity<A, Q, R>, Q extends Quantity<Q>,
333 R extends Reference<R, A, Q>> AbsVector3.Row<A, Q> of(final A absX, final A absY, final A absZ)
334 {
335 Throw.whenNull(absX, "absX");
336 Throw.whenNull(absY, "absY");
337 Throw.whenNull(absZ, "absZ");
338 Throw.when(!absX.getReference().equals(absY.getReference()), IllegalArgumentException.class,
339 "absX.reference != absY.reference");
340 Throw.when(!absX.getReference().equals(absZ.getReference()), IllegalArgumentException.class,
341 "absX.reference != absZ.reference");
342 return new AbsVector3.Row<>(Vector3.Row.of(absX.getQuantity(), absY.getQuantity(), absZ.getQuantity()),
343 absX.getReference());
344 }
345
346 /**
347 * Create a AbsVector3.Row without needing generics.
348 * @param dataInUnit the vector entries expressed as an array in the unit
349 * @param unit the unit of the data, which will also be used as the display unit
350 * @param reference the reference point for the absolute quantities
351 * @return a new AbsVector3.Row with a unit
352 * @param <A> the absolute quantity type
353 * @param <Q> the quantity type
354 * @param <R> the reference type
355 */
356 public static <A extends AbsQuantity<A, Q, R>, Q extends Quantity<Q>,
357 R extends Reference<R, A, Q>> AbsVector3.Row<A, Q> of(final double[] dataInUnit, final Unit<?, Q> unit,
358 final R reference)
359 {
360 return new AbsVector3.Row<>(Vector3.Row.of(dataInUnit, unit), reference);
361 }
362
363 /**
364 * Create a AbsVector3.Row without needing generics.
365 * @param dataSi the vector entries expressed as an array in the SI units
366 * @param displayUnit the display unit to use
367 * @param reference the reference point for the absolute quantities
368 * @return a new AbsVector3.Row with a unit
369 * @param <A> the absolute quantity type
370 * @param <Q> the quantity type
371 * @param <R> the reference type
372 */
373 public static <A extends AbsQuantity<A, Q, R>, Q extends Quantity<Q>,
374 R extends Reference<R, A, Q>> AbsVector3.Row<A, Q> ofSi(final double[] dataSi, final Unit<?, Q> displayUnit,
375 final R reference)
376 {
377 return new AbsVector3.Row<>(Vector3.Row.ofSi(dataSi, displayUnit), reference);
378 }
379
380 /**
381 * Create a AbsVector3.Row without needing generics.
382 * @param xSi the x vector entry expressed in the SI unit
383 * @param ySi the y vector entry expressed in the SI unit
384 * @param zSi the z vector entry expressed in the SI unit
385 * @param displayUnit the display unit to use
386 * @param reference the reference point for the absolute quantities
387 * @return a new AbsVector3.Row with a unit
388 * @param <A> the absolute quantity type
389 * @param <Q> the quantity type
390 * @param <R> the reference type
391 */
392 public static <A extends AbsQuantity<A, Q, R>, Q extends Quantity<Q>,
393 R extends Reference<R, A, Q>> AbsVector3.Row<A, Q> ofSi(final double xSi, final double ySi, final double zSi,
394 final Unit<?, Q> displayUnit, final R reference)
395 {
396 return new AbsVector3.Row<>(Vector3.Row.ofSi(xSi, ySi, zSi, displayUnit), reference);
397 }
398
399 /**
400 * Create a AbsVector3.Row without needing generics. The display unit will be taken from the first quantity in the
401 * array.
402 * @param data the vector entries expressed as an array of quantities
403 * @param reference the reference point for the absolute quantities
404 * @return a new AbsVector3.Row with a unit
405 * @param <A> the absolute quantity type
406 * @param <Q> the quantity type
407 * @param <R> the reference type
408 */
409 public static <A extends AbsQuantity<A, Q, R>, Q extends Quantity<Q>,
410 R extends Reference<R, A, Q>> AbsVector3.Row<A, Q> of(final Q[] data, final R reference)
411 {
412 return new AbsVector3.Row<>(Vector3.Row.of(data), reference);
413 }
414
415 /**
416 * Create an AbsVector3.Row without needing generics.
417 * @param absData the {x, y} value expressed as an array of absolute quantities
418 * @return a new AbsVector3.Row with a unit
419 * @param <A> the absolute quantity type
420 * @param <Q> the quantity type
421 * @param <R> the reference type
422 */
423 public static <A extends AbsQuantity<A, Q, R>, Q extends Quantity<Q>,
424 R extends Reference<R, A, Q>> AbsVector3.Row<A, Q> of(final A[] absData)
425 {
426 Throw.whenNull(absData, "absData");
427 Throw.when(absData.length != 3, IllegalArgumentException.class, "absData.length != 3");
428 return AbsVector3.Row.of(absData[0], absData[1], absData[2]);
429 }
430
431 /**
432 * Create an AbsVector3.Row without needing generics.
433 * @param relativeVector the relative vector
434 * @param reference the reference point for the absolute quantities
435 * @return a new AbsVector3.Row with a unit
436 * @param <A> the absolute quantity type
437 * @param <Q> the quantity type
438 * @param <R> the reference type
439 */
440 public static <A extends AbsQuantity<A, Q, R>, Q extends Quantity<Q>,
441 R extends Reference<R, A, Q>> AbsVector3.Row<A, Q> of(final Vector3.Row<Q> relativeVector, final R reference)
442 {
443 Throw.whenNull(relativeVector, "relativeVector");
444 return new AbsVector3.Row<>(relativeVector, reference);
445 }
446 }
447
448 }