JOGL v2.6.0-rc-20250712
JOGL, High-Performance Graphics Binding for Java™ (public API).
Vec2f.java
Go to the documentation of this file.
1/**
2 * Copyright 2022-2023 JogAmp Community. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without modification, are
5 * permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright notice, this list of
8 * conditions and the following disclaimer.
9 *
10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11 * of conditions and the following disclaimer in the documentation and/or other materials
12 * provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
15 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 *
24 * The views and conclusions contained in the software and documentation are those of the
25 * authors and should not be interpreted as representing official policies, either expressed
26 * or implied, of JogAmp Community.
27 */
28
29package com.jogamp.math;
30
31/**
32 * 2D Vector based upon two float components.
33 *
34 * Implementation borrowed from [gfxbox2](https://jausoft.com/cgit/cs_class/gfxbox2.git/tree/include/pixel/pixel2f.hpp#n29)
35 * and its data layout from JOAL's Vec3f.
36 */
37public final class Vec2f {
38 private float x;
39 private float y;
40
41 public static Vec2f from_length_angle(final float magnitude, final float radians) {
42 return new Vec2f((float)(magnitude * Math.cos(radians)), (float)(magnitude * Math.sin(radians)));
43 }
44
45 public Vec2f() {}
46
47 public Vec2f(final Vec2f o) {
48 set(o);
49 }
50
51 public Vec2f(final Vec2i o) {
52 set(o);
53 }
54
55 /** Creating new Vec2f using Vec3f, dropping z. */
56 public Vec2f(final Vec3f o) {
57 set(o);
58 }
59
60 public Vec2f copy() {
61 return new Vec2f(this);
62 }
63
64 public Vec2f(final float[/*2*/] xy) {
65 set(xy);
66 }
67
68 public Vec2f(final float x, final float y) {
69 set(x, y);
70 }
71
72 /** this = o, returns this. */
73 public void set(final Vec2f o) {
74 this.x = o.x;
75 this.y = o.y;
76 }
77
78 /** this = o (int -> float), returns this. */
79 public void set(final Vec2i o) {
80 this.x = o.x();
81 this.y = o.y();
82 }
83
84 /** this = o while dropping z, returns this. */
85 public void set(final Vec3f o) {
86 this.x = o.x();
87 this.y = o.y();
88 }
89
90 /** this = { x, y }, returns this. */
91 public void set(final float x, final float y) {
92 this.x = x;
93 this.y = y;
94 }
95
96 /** this = xy, returns this. */
97 public Vec2f set(final float[/*2*/] xy) {
98 this.x = xy[0];
99 this.y = xy[1];
100 return this;
101 }
102
103 /** xy[0..1] = this.{x, y}, returns this. */
104 public Vec2f toArray(final float[/*2*/] xy) {
105 xy[0] = this.x;
106 xy[1] = this.y;
107 return this;
108 }
109
110 /** Sets the ith component, 0 <= i < 2 */
111 public void set(final int i, final float val) {
112 switch (i) {
113 case 0: x = val; break;
114 case 1: y = val; break;
115 default: throw new IndexOutOfBoundsException();
116 }
117 }
118
119 /** xy = this, returns xy. */
120 public float[] get(final float[/*2*/] xy) {
121 xy[0] = this.x;
122 xy[1] = this.y;
123 return xy;
124 }
125
126 /** Gets the ith component, 0 <= i < 2 */
127 public float get(final int i) {
128 switch (i) {
129 case 0: return x;
130 case 1: return y;
131 default: throw new IndexOutOfBoundsException();
132 }
133 }
134
135 public float x() { return x; }
136 public float y() { return y; }
137
138 public void setX(final float x) { this.x = x; }
139 public void setY(final float y) { this.y = y; }
140
141 /** this = max(this, m), returns this. */
142 public Vec2f max(final Vec2f m) {
143 this.x = Math.max(this.x, m.x);
144 this.y = Math.max(this.y, m.y);
145 return this;
146 }
147 /** this = min(this, m), returns this. */
148 public Vec2f min(final Vec2f m) {
149 this.x = Math.min(this.x, m.x);
150 this.y = Math.min(this.y, m.y);
151 return this;
152 }
153
154 /** Returns this * val; creates new vector */
155 public Vec2f mul(final float val) {
156 return new Vec2f(this).scale(val);
157 }
158
159 /** this = a * b, returns this. */
160 public Vec2f mul(final Vec2f a, final Vec2f b) {
161 x = a.x * b.x;
162 y = a.y * b.y;
163 return this;
164 }
165
166 /** this = this * s, returns this. */
167 public Vec2f mul(final Vec2f s) { return mul(s.x, s.y); }
168
169 /** this = this * { sx, sy }, returns this. */
170 public Vec2f mul(final float sx, final float sy) {
171 x *= sx;
172 y *= sy;
173 return this;
174 }
175
176 /** this = a / b, returns this. */
177 public Vec2f div(final Vec2f a, final Vec2f b) {
178 x = a.x / b.x;
179 y = a.y / b.y;
180 return this;
181 }
182
183 /** this = this / a, returns this. */
184 public Vec2f div(final Vec2f a) {
185 x /= a.x;
186 y /= a.y;
187 return this;
188 }
189
190 /** this = this * s, returns this. */
191 public Vec2f scale(final float s) {
192 x *= s;
193 y *= s;
194 return this;
195 }
196
197 /** Returns this + arg; creates new vector */
198 public Vec2f plus(final Vec2f arg) {
199 return new Vec2f(this).add(arg);
200 }
201
202 /** this = a + b, returns this. */
203 public Vec2f plus(final Vec2f a, final Vec2f b) {
204 x = a.x + b.x;
205 y = a.y + b.y;
206 return this;
207 }
208
209 /** this = this + { dx, dy }, returns this. */
210 public Vec2f add(final float dx, final float dy) {
211 x += dx;
212 y += dy;
213 return this;
214 }
215
216 /** this = this + b, returns this. */
217 public Vec2f add(final Vec2f b) {
218 x += b.x;
219 y += b.y;
220 return this;
221 }
222
223 /** Returns this - arg; creates new vector */
224 public Vec2f minus(final Vec2f arg) {
225 return new Vec2f(this).sub(arg);
226 }
227
228 /** this = a - b, returns this. */
229 public Vec2f minus(final Vec2f a, final Vec2f b) {
230 x = a.x - b.x;
231 y = a.y - b.y;
232 return this;
233 }
234
235 /** this = this - b, returns this. */
236 public Vec2f sub(final Vec2f b) {
237 x -= b.x;
238 y -= b.y;
239 return this;
240 }
241
242 /** Return true if all components are zero, i.e. it's absolute value < {@link #EPSILON}. */
243 public boolean isZero() {
244 return FloatUtil.isZero(x) && FloatUtil.isZero(y);
245 }
246
247 public void rotate(final float radians, final Vec2f ctr) {
248 final float cos = (float)Math.cos(radians);
249 final float sin = (float)Math.sin(radians);
250 rotate(sin, cos, ctr);
251 }
252
253 public void rotate(final float sin, final float cos, final Vec2f ctr) {
254 final float x0 = x - ctr.x;
255 final float y0 = y - ctr.y;
256 final float tmp = x0 * cos - y0 * sin + ctr.x;
257 y = x0 * sin + y0 * cos + ctr.y;
258 x = tmp;
259 }
260
261 /**
262 * Return the length of this vector, a.k.a the <i>norm</i> or <i>magnitude</i>
263 */
264 public float length() {
265 return (float) Math.sqrt(lengthSq());
266 }
267
268 /**
269 * Return the squared length of this vector, a.k.a the squared <i>norm</i> or squared <i>magnitude</i>
270 */
271 public float lengthSq() {
272 return x*x + y*y;
273 }
274
275 /**
276 * Return the direction angle of this vector in radians
277 */
278 public float angle() {
279 // Utilize atan2 taking y=sin(a) and x=cos(a), resulting in proper direction angle for all quadrants.
280 return (float) Math.atan2(y, x);
281 }
282
283 /**
284 * Normalize this vector in place
285 */
286 public Vec2f normalize() {
287 final float lengthSq = lengthSq();
288 if ( FloatUtil.isZero( lengthSq ) ) {
289 x = 0.0f;
290 y = 0.0f;
291 } else {
292 final float invSqr = 1.0f / (float)Math.sqrt(lengthSq);
293 x *= invSqr;
294 y *= invSqr;
295 }
296 return this;
297 }
298
299 /**
300 * Return the squared distance between this vector and the given one.
301 * <p>
302 * When comparing the relative distance between two points it is usually sufficient to compare the squared
303 * distances, thus avoiding an expensive square root operation.
304 * </p>
305 */
306 public float distSq(final Vec2f o) {
307 final float dx = x - o.x;
308 final float dy = y - o.y;
309 return dx*dx + dy*dy;
310 }
311
312 /**
313 * Return the distance between this vector and the given one.
314 */
315 public float dist(final Vec2f o) {
316 return (float)Math.sqrt(distSq(o));
317 }
318
319
320 /**
321 * Return the dot product of this vector and the given one
322 * @return the dot product as float
323 */
324 public float dot(final Vec2f arg) {
325 return x * arg.x + y * arg.y;
326 }
327
328 /**
329 * Returns cross product of this vectors and the given one, i.e. *this x o.
330 *
331 * The 2D cross product is identical with the 2D perp dot product.
332 *
333 * @return the resulting scalar
334 */
335 public float cross(final Vec2f o) {
336 return x * o.y - y * o.x;
337 }
338
339 /**
340 * Return the cosines of the angle between two vectors
341 */
342 public float cosAngle(final Vec2f o) {
343 return dot(o) / ( length() * o.length() ) ;
344 }
345
346 /**
347 * Return the angle between two vectors in radians
348 */
349 public float angle(final Vec2f o) {
350 return (float) Math.acos( cosAngle(o) );
351 }
352
353 /**
354 * Return the counter-clock-wise (CCW) normal of this vector, i.e. perp(endicular) vector
355 */
356 public Vec2f normal_ccw() {
357 return new Vec2f(-y, x);
358 }
359
360 /**
361 * Equals check using a given {@link FloatUtil#EPSILON} value and {@link FloatUtil#isEqual(float, float, float)}.
362 * <p>
363 * Implementation considers following corner cases:
364 * <ul>
365 * <li>NaN == NaN</li>
366 * <li>+Inf == +Inf</li>
367 * <li>-Inf == -Inf</li>
368 * </ul>
369 * @param o comparison value
370 * @param epsilon consider using {@link FloatUtil#EPSILON}
371 * @return true if all components differ less than {@code epsilon}, otherwise false.
372 */
373 public boolean isEqual(final Vec2f o, final float epsilon) {
374 if( this == o ) {
375 return true;
376 } else {
377 return FloatUtil.isEqual(x, o.x, epsilon) &&
378 FloatUtil.isEqual(y, o.y, epsilon);
379 }
380 }
381
382 /**
383 * Equals check using {@link FloatUtil#EPSILON} in {@link FloatUtil#isEqual(float, float)}.
384 * <p>
385 * Implementation considers following corner cases:
386 * <ul>
387 * <li>NaN == NaN</li>
388 * <li>+Inf == +Inf</li>
389 * <li>-Inf == -Inf</li>
390 * </ul>
391 * @param o comparison value
392 * @return true if all components differ less than {@link FloatUtil#EPSILON}, otherwise false.
393 */
394 public boolean isEqual(final Vec2f o) {
395 if( this == o ) {
396 return true;
397 } else {
398 return FloatUtil.isEqual(x, o.x) &&
399 FloatUtil.isEqual(y, o.y);
400 }
401 }
402
403 @Override
404 public boolean equals(final Object o) {
405 if( o instanceof Vec2f ) {
406 return isEqual((Vec2f)o);
407 } else {
408 return false;
409 }
410 }
411
412 @Override
413 public String toString() {
414 return x + " / " + y;
415 }
416}
Basic Float math utility functions.
Definition: FloatUtil.java:83
static boolean isZero(final float a, final float epsilon)
Returns true if value is zero, i.e.
static boolean isEqual(final float a, final float b, final float epsilon)
Returns true if both values are equal, i.e.
2D Vector based upon two float components.
Definition: Vec2f.java:37
boolean isZero()
Return true if all components are zero, i.e.
Definition: Vec2f.java:243
Vec2f toArray(final float[] xy)
xy[0..1] = this.
Definition: Vec2f.java:104
Vec2f(final Vec2f o)
Definition: Vec2f.java:47
Vec2f plus(final Vec2f a, final Vec2f b)
this = a + b, returns this.
Definition: Vec2f.java:203
float cross(final Vec2f o)
Returns cross product of this vectors and the given one, i.e.
Definition: Vec2f.java:335
Vec2f max(final Vec2f m)
this = max(this, m), returns this.
Definition: Vec2f.java:142
float dist(final Vec2f o)
Return the distance between this vector and the given one.
Definition: Vec2f.java:315
void rotate(final float radians, final Vec2f ctr)
Definition: Vec2f.java:247
float angle()
Return the direction angle of this vector in radians.
Definition: Vec2f.java:278
Vec2f plus(final Vec2f arg)
Returns this + arg; creates new vector.
Definition: Vec2f.java:198
boolean isEqual(final Vec2f o, final float epsilon)
Equals check using a given FloatUtil#EPSILON value and FloatUtil#isEqual(float, float,...
Definition: Vec2f.java:373
Vec2f(final float[] xy)
Definition: Vec2f.java:64
Vec2f(final Vec3f o)
Creating new Vec2f using Vec3f, dropping z.
Definition: Vec2f.java:56
Vec2f mul(final float sx, final float sy)
this = this * { sx, sy }, returns this.
Definition: Vec2f.java:170
Vec2f sub(final Vec2f b)
this = this - b, returns this.
Definition: Vec2f.java:236
Vec2f normal_ccw()
Return the counter-clock-wise (CCW) normal of this vector, i.e.
Definition: Vec2f.java:356
Vec2f(final Vec2i o)
Definition: Vec2f.java:51
float distSq(final Vec2f o)
Return the squared distance between this vector and the given one.
Definition: Vec2f.java:306
boolean isEqual(final Vec2f o)
Equals check using FloatUtil#EPSILON in FloatUtil#isEqual(float, float).
Definition: Vec2f.java:394
Vec2f(final float x, final float y)
Definition: Vec2f.java:68
Vec2f minus(final Vec2f arg)
Returns this - arg; creates new vector.
Definition: Vec2f.java:224
float length()
Return the length of this vector, a.k.a the norm or magnitude
Definition: Vec2f.java:264
Vec2f div(final Vec2f a, final Vec2f b)
this = a / b, returns this.
Definition: Vec2f.java:177
float dot(final Vec2f arg)
Return the dot product of this vector and the given one.
Definition: Vec2f.java:324
Vec2f mul(final Vec2f a, final Vec2f b)
this = a * b, returns this.
Definition: Vec2f.java:160
Vec2f mul(final Vec2f s)
this = this * s, returns this.
Definition: Vec2f.java:167
Vec2f normalize()
Normalize this vector in place.
Definition: Vec2f.java:286
Vec2f add(final Vec2f b)
this = this + b, returns this.
Definition: Vec2f.java:217
static Vec2f from_length_angle(final float magnitude, final float radians)
Definition: Vec2f.java:41
Vec2f scale(final float s)
this = this * s, returns this.
Definition: Vec2f.java:191
void setY(final float y)
Definition: Vec2f.java:139
float lengthSq()
Return the squared length of this vector, a.k.a the squared norm or squared magnitude
Definition: Vec2f.java:271
void setX(final float x)
Definition: Vec2f.java:138
float cosAngle(final Vec2f o)
Return the cosines of the angle between two vectors.
Definition: Vec2f.java:342
Vec2f add(final float dx, final float dy)
this = this + { dx, dy }, returns this.
Definition: Vec2f.java:210
Vec2f minus(final Vec2f a, final Vec2f b)
this = a - b, returns this.
Definition: Vec2f.java:229
Vec2f mul(final float val)
Returns this * val; creates new vector.
Definition: Vec2f.java:155
Vec2f div(final Vec2f a)
this = this / a, returns this.
Definition: Vec2f.java:184
void rotate(final float sin, final float cos, final Vec2f ctr)
Definition: Vec2f.java:253
Vec2f min(final Vec2f m)
this = min(this, m), returns this.
Definition: Vec2f.java:148
boolean equals(final Object o)
Definition: Vec2f.java:404
float angle(final Vec2f o)
Return the angle between two vectors in radians.
Definition: Vec2f.java:349
2D Vector based upon two integer components.
Definition: Vec2i.java:34
3D Vector based upon three float components.
Definition: Vec3f.java:37