diff options
author | Sven Gothel <[email protected]> | 2023-03-22 17:01:43 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2023-03-22 17:01:43 +0100 |
commit | 089025825be32ba733313b8c2390223f14edb017 (patch) | |
tree | 3266c328a40acaa0c4dc7448e10827142a9629b0 | |
parent | 9e4d575d7f7a9817cf11fa4e33504a379d271a21 (diff) |
Add Vec2f and Vec3f, to support a more simple OO vector-math usage, e.g. for animation etc
Implementation borrowed my 'gfxbox2' C++ project
<https://jausoft.com/cgit/cs_class/gfxbox2.git/tree/include/pixel/pixel3f.hpp#n29>
and its layout from OpenAL's Vec3f.
-rw-r--r-- | src/jogl/classes/com/jogamp/opengl/math/Vec2f.java | 271 | ||||
-rw-r--r-- | src/jogl/classes/com/jogamp/opengl/math/Vec3f.java | 257 |
2 files changed, 528 insertions, 0 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/math/Vec2f.java b/src/jogl/classes/com/jogamp/opengl/math/Vec2f.java new file mode 100644 index 000000000..159a000df --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/math/Vec2f.java @@ -0,0 +1,271 @@ +/** + * Copyright 2022-2023 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.opengl.math; + +/** + * 2D Vector based upon two float components. + * + * Implementation borrowed from [gfxbox2](https://jausoft.com/cgit/cs_class/gfxbox2.git/tree/include/pixel/pixel2f.hpp#n29) + * and its layout from OpenAL's Vec3f. + */ +public final class Vec2f { + private float x; + private float y; + + public static Vec2f from_length_angle(final float magnitude, final float radians) { + return new Vec2f((float)(magnitude * Math.cos(radians)), (float)(magnitude * Math.sin(radians))); + } + + public Vec2f() {} + + public Vec2f(final Vec2f o) { + this.x = o.x; + this.y = o.y; + } + + public Vec2f copy() { + return new Vec2f(this); + } + + public Vec2f(final float x, final float y) { + this.x = x; + this.y = y; + } + + public void set(final Vec2f o) { + this.x = o.x; + this.y = o.y; + } + + public void set(final float x, final float y) { + this.x = x; + this.y = y; + } + + /** Sets the ith component, 0 <= i < 2 */ + public void set(final int i, final float val) { + switch (i) { + case 0: x = val; break; + case 1: y = val; break; + default: throw new IndexOutOfBoundsException(); + } + } + + /** Gets the ith component, 0 <= i < 2 */ + public float get(final int i) { + switch (i) { + case 0: return x; + case 1: return y; + default: throw new IndexOutOfBoundsException(); + } + } + + public float x() { return x; } + public float y() { return y; } + + public void setX(final float x) { this.x = x; } + public void setY(final float y) { this.y = y; } + + /** Returns this * val; creates new vector */ + public Vec2f mul(final float val) { + return new Vec2f(this).scale(val); + } + + /** this = this * val */ + public Vec2f scale(final float val) { + x *= val; + y *= val; + return this; + } + + /** Returns this + arg; creates new vector */ + public Vec2f plus(final Vec2f arg) { + return new Vec2f(this).add(arg); + } + + /** this = this + b */ + public Vec2f add(final Vec2f b) { + x += b.x; + y += b.y; + return this; + } + + /** Returns this + s * arg; creates new vector */ + public Vec2f plusScaled(final float s, final Vec2f arg) { + return new Vec2f(this).addScaled(s, arg); + } + + /** this = this + s * b */ + public Vec2f addScaled(final float s, final Vec2f b) { + x += s * b.x; + y += s * b.y; + return this; + } + + /** Returns this - arg; creates new vector */ + public Vec2f minus(final Vec2f arg) { + return new Vec2f(this).sub(arg); + } + + /** this = this - b */ + public Vec2f sub(final Vec2f b) { + x -= b.x; + y -= b.y; + return this; + } + + public boolean isZero() { + return FloatUtil.isZero(x) && FloatUtil.isZero(y); + } + + public void rotate(final float radians, final Vec2f ctr) { + final float cos = (float)Math.cos(radians); + final float sin = (float)Math.sin(radians); + rotate(sin, cos, ctr); + } + + public void rotate(final float sin, final float cos, final Vec2f ctr) { + final float x0 = x - ctr.x; + final float y0 = y - ctr.y; + final float tmp = x0 * cos - y0 * sin + ctr.x; + y = x0 * sin + y0 * cos + ctr.y; + x = tmp; + } + + /** + * Return the length of this vector, a.k.a the <i>norm</i> or <i>magnitude</i> + */ + public float length() { + return (float) Math.sqrt(lengthSq()); + } + + /** + * Return the squared length of this vector, a.k.a the squared <i>norm</i> or squared <i>magnitude</i> + */ + public float lengthSq() { + return x*x + y*y; + } + + /** + * Return the direction angle of this vector in radians + */ + public float angle() { + // Utilize atan2 taking y=sin(a) and x=cos(a), resulting in proper direction angle for all quadrants. + return (float) Math.atan2(y, x); + } + + /** + * Normalize this vector in place + */ + public Vec2f normalize() { + final float lengthSq = lengthSq(); + if ( FloatUtil.isZero( lengthSq ) ) { + x = 0.0f; + y = 0.0f; + } else { + final float invSqr = 1.0f / (float)Math.sqrt(lengthSq); + x *= invSqr; + y *= invSqr; + } + return this; + } + + /** + * Return the squared distance between this vector and the given one. + * <p> + * When comparing the relative distance between two points it is usually sufficient to compare the squared + * distances, thus avoiding an expensive square root operation. + * </p> + */ + public float distSq(final Vec2f o) { + final float dx = x - o.x; + final float dy = y - o.y; + return dx*dx + dy*dy; + } + + /** + * Return the distance between this vector and the given one. + */ + public float dist(final Vec2f o) { + return (float)Math.sqrt(distSq(o)); + } + + + /** + * Return the dot product of this vector and the given one + * @return the dot product as float + */ + public float dot(final Vec2f arg) { + return x * arg.x + y * arg.y; + } + + /** + * Returns cross product of this vectors and the given one, i.e. *this x o. + * + * The 2D cross product is identical with the 2D perp dot product. + * + * @return the resulting scalar + */ + public float cross(final Vec2f o) { + return x * o.y - y * o.x; + } + + /** + * Return the cosines of the angle between two vectors + */ + public float cosAngle(final Vec2f o) { + return dot(o) / ( length() * o.length() ) ; + } + + /** + * Return the angle between two vectors in radians + */ + public float angle(final Vec2f o) { + return (float) Math.acos( cosAngle(o) ); + } + + /** + * Return the counter-clock-wise (CCW) normal of this vector, i.e. perp(endicular) vector + */ + public Vec2f normal_ccw() { + return new Vec2f(-y, x); + } + + public boolean intersects(final Vec2f o) { + if( Math.abs(x-o.x) >= FloatUtil.EPSILON || Math.abs(y-o.y) >= FloatUtil.EPSILON ) { + return false; + } + return true; + } + + @Override + public String toString() { + return x + " / " + y; + } +} diff --git a/src/jogl/classes/com/jogamp/opengl/math/Vec3f.java b/src/jogl/classes/com/jogamp/opengl/math/Vec3f.java new file mode 100644 index 000000000..673f48b9a --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/math/Vec3f.java @@ -0,0 +1,257 @@ +/** + * Copyright 2022-2023 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.opengl.math; + +/** + * 3D Vector based upon three float components. + * + * Implementation borrowed from [gfxbox2](https://jausoft.com/cgit/cs_class/gfxbox2.git/tree/include/pixel/pixel3f.hpp#n29) + * and its layout from OpenAL's Vec3f. + */ +public final class Vec3f { + private float x; + private float y; + private float z; + + public Vec3f() {} + + public Vec3f(final Vec3f o) { + this.x = o.x; + this.y = o.y; + this.z = o.z; + } + + public Vec3f copy() { + return new Vec3f(this); + } + + public Vec3f(final float x, final float y, final float z) { + this.x = x; + this.y = y; + this.z = z; + } + + public void set(final Vec3f o) { + this.x = o.x; + this.y = o.y; + this.z = o.z; + } + + public void set(final float x, final float y, final float z) { + this.x = x; + this.y = y; + this.z = z; + } + + /** Sets the ith component, 0 <= i < 3 */ + public void set(final int i, final float val) { + switch (i) { + case 0: x = val; break; + case 1: y = val; break; + case 2: z = val; break; + default: throw new IndexOutOfBoundsException(); + } + } + + /** Gets the ith component, 0 <= i < 3 */ + public float get(final int i) { + switch (i) { + case 0: return x; + case 1: return y; + case 2: return z; + default: throw new IndexOutOfBoundsException(); + } + } + + public float x() { return x; } + public float y() { return y; } + public float z() { return z; } + + public void setX(final float x) { this.x = x; } + public void setY(final float y) { this.y = y; } + public void setZ(final float z) { this.z = z; } + + /** Returns this * val; creates new vector */ + public Vec3f mul(final float val) { + return new Vec3f(this).scale(val); + } + + /** this = this * val */ + public Vec3f scale(final float val) { + x *= val; + y *= val; + z *= val; + return this; + } + + /** Returns this + arg; creates new vector */ + public Vec3f plus(final Vec3f arg) { + return new Vec3f(this).add(arg); + } + + /** this = this + b */ + public Vec3f add(final Vec3f b) { + x += b.x; + y += b.y; + z += b.z; + return this; + } + + /** Returns this + s * arg; creates new vector */ + public Vec3f plusScaled(final float s, final Vec3f arg) { + return new Vec3f(this).addScaled(s, arg); + } + + /** this = this + s * b */ + public Vec3f addScaled(final float s, final Vec3f b) { + x += s * b.x; + y += s * b.y; + z += s * b.z; + return this; + } + + /** Returns this - arg; creates new vector */ + public Vec3f minus(final Vec3f arg) { + return new Vec3f(this).sub(arg); + } + + /** this = this - b */ + public Vec3f sub(final Vec3f b) { + x -= b.x; + y -= b.y; + z -= b.z; + return this; + } + + public boolean is_zero() { + return FloatUtil.isZero(x) && FloatUtil.isZero(y) && FloatUtil.isZero(z); + } + + /** + * Return the length of this vector, a.k.a the <i>norm</i> or <i>magnitude</i> + */ + public float length() { + return (float) Math.sqrt(lengthSq()); + } + + /** + * Return the squared length of this vector, a.k.a the squared <i>norm</i> or squared <i>magnitude</i> + */ + public float lengthSq() { + return x*x + y*y + z*z; + } + + /** + * Normalize this vector in place + */ + public Vec3f normalize() { + final float lengthSq = lengthSq(); + if ( FloatUtil.isZero( lengthSq ) ) { + x = 0.0f; + y = 0.0f; + z = 0.0f; + } else { + final float invSqr = 1.0f / (float)Math.sqrt(lengthSq); + x *= invSqr; + y *= invSqr; + z *= invSqr; + } + return this; + } + + /** + * Return the squared distance between this vector and the given one. + * <p> + * When comparing the relative distance between two points it is usually sufficient to compare the squared + * distances, thus avoiding an expensive square root operation. + * </p> + */ + public float distSq(final Vec3f o) { + final float dx = x - o.x; + final float dy = y - o.y; + final float dz = z - o.z; + return dx*dx + dy*dy + dz*dz; + } + + /** + * Return the distance between this vector and the given one. + */ + public float dist(final Vec3f o) { + return (float)Math.sqrt(distSq(o)); + } + + + /** + * Return the dot product of this vector and the given one + * @return the dot product as float + */ + public float dot(final Vec3f o) { + return x*o.x + y*o.y + z*o.z; + } + + /** Returns this cross arg; creates new vector */ + public Vec3f cross(final Vec3f arg) { + return new Vec3f().cross(this, arg); + } + + /** this = a cross b. NOTE: "this" must be a different vector than + both a and b. */ + public Vec3f cross(final Vec3f a, final Vec3f b) { + x = a.y * b.z - a.z * b.y; + y = a.z * b.x - a.x * b.z; + z = a.x * b.y - a.y * b.x; + return this; + } + + /** + * Return the cosines of the angle between two vectors + */ + public float cosAngle(final Vec3f o) { + return dot(o) / ( length() * o.length() ) ; + } + + /** + * Return the angle between two vectors in radians + */ + public float angle(final Vec3f o) { + return (float) Math.acos( cosAngle(o) ); + } + + public boolean intersects(final Vec3f o) { + if( Math.abs(x-o.x) >= FloatUtil.EPSILON || Math.abs(y-o.y) >= FloatUtil.EPSILON || Math.abs(z-o.z) >= FloatUtil.EPSILON ) { + return false; + } + return true; + } + + @Override + public String toString() { + return x + " / " + y + " / " + z; + } +} |