Matrix2f

I think it is correct. Translated Matrix3f pretty much, but changed to 2D. Got all the stuff from Matrix3f in it, except for some methods:


  1. One of the fillFloatBuffer method that needed tempvars (would have to modify tempvars). Just commented it out.
  2. Replaced fromAngleAxis and fromAngleNormalAxis (they are now “fromAngle(float angle)”
  3. Removed everything involving quaternions and vector cross products (just two or three methods).



    [java]

    import com.jme3.export.*;

    import com.jme3.math.FastMath;

    import com.jme3.math.Vector2f;

    import com.jme3.util.BufferUtils;

    import java.io.IOException;

    import java.nio.FloatBuffer;

    import java.util.logging.Logger;



    /**

    *
  • Matrix2f converted from Matrix3f.

    *
  • @author Androlo

    *

    ******************************************************************************

    *
  • <code>Matrix3f</code> defines a 3x3 matrix. Matrix data is maintained
  • internally and is accessible via the get and set methods. Convenience methods
  • are used for matrix operations as well as generating a matrix from a given
  • set of values.

    *
  • @author Mark Powell
  • @author Joshua Slack

    */

    public final class Matrix2f implements Savable, Cloneable, java.io.Serializable {



    // TODO is there a system for this?

    static final long serialVersionUID = 1;



    private static final Logger logger = Logger.getLogger(Matrix2f.class.getName());

    protected float m00, m01;

    protected float m10, m11;

    public static final Matrix2f ZERO = new Matrix2f(0, 0, 0, 0);

    public static final Matrix2f IDENTITY = new Matrix2f();



    /**
  • Constructor instantiates a new <code>Matrix2f</code> object. The
  • initial values for the matrix is that of the identity matrix.

    *

    */

    public Matrix2f() {

    loadIdentity();

    }



    /**
  • constructs a matrix with the given values.

    *
  • @param m00
  •        0x0 in the matrix.<br />
    
  • @param m01
  •        0x1 in the matrix.<br />
    
  • @param m10
  •        1x0 in the matrix.<br />
    
  • @param m11

    */

    public Matrix2f(float m00, float m01, float m10, float m11) {



    this.m00 = m00;

    this.m01 = m01;

    this.m10 = m10;

    this.m11 = m11;

    }



    /**
  • Copy constructor that creates a new <code>Matrix2f</code> object that
  • is the same as the provided matrix.

    *
  • @param mat
  •        the matrix to copy.<br />
    

*/

public Matrix2f(Matrix2f mat) {

set(mat);

}



/**

  • Takes the absolute value of all matrix fields locally.

    */

    public void absoluteLocal() {

    m00 = FastMath.abs(m00);

    m01 = FastMath.abs(m01);

    m10 = FastMath.abs(m10);

    m11 = FastMath.abs(m11);

    }



    /**
  • <code>copy</code> transfers the contents of a given matrix to this
  • matrix. If a null matrix is supplied, this matrix is set to the identity
  • matrix.

    *
  • @param matrix
  •        the matrix to copy.<br />
    
  • @return this

    */

    public Matrix2f set(Matrix2f matrix) {

    if (null == matrix) {

    loadIdentity();

    } else {

    m00 = matrix.m00;

    m01 = matrix.m01;

    m10 = matrix.m10;

    m11 = matrix.m11;

    }

    return this;

    }



    /**
  • <code>get</code> retrieves a value from the matrix at the given
  • position. If the position is invalid a <code>JmeException</code> is
  • thrown.

    *
  • @param i
  •        the row index.<br />
    
  • @param j
  •        the colum index.<br />
    
  • @return the value at (i, j).

    */

    @SuppressWarnings("fallthrough")

    public float get(int i, int j) {

    switch (i) {

    case 0:

    switch (j) {

    case 0:

    return m00;

    case 1:

    return m01;

    }

    case 1:

    switch (j) {

    case 0:

    return m10;

    case 1:

    return m11;

    }

    }



    logger.warning("Invalid matrix index.");

    throw new IllegalArgumentException("Invalid indices into matrix.");

    }



    /**
  • <code>get(float[])</code> returns the matrix in row-major or column-major order.

    *
  • @param data
  •  The array to return the data into. This array can be 4, 9 or 16 floats in size.<br />
    
  •  Only the upper 3x3 are assigned to in the case of a 16 element array.<br />
    
  • @param rowMajor
  •  True for row major storage in the array (translation in elements 3, 7, 11 for a 4x4),<br />
    
  •  false for column major (translation in elements 12, 13, 14 for a 4x4).<br />
    

*/

public void get(float[] data, boolean rowMajor) {

if (data.length == 4) {

if (rowMajor) {

data[0] = m00;

data[1] = m01;

data[3] = m10;

data[4] = m11;

} else {

data[0] = m00;

data[1] = m10;

data[3] = m01;

data[4] = m11;

}

if (data.length == 9) {

if (rowMajor) {

data[0] = m00;

data[1] = m01;

data[3] = m10;

data[4] = m11;

} else {

data[0] = m00;

data[1] = m10;

data[3] = m01;

data[4] = m11;

}

} else if (data.length == 16) {

if (rowMajor) {

data[0] = m00;

data[1] = m01;

data[4] = m10;

data[5] = m11;

} else {

data[0] = m00;

data[1] = m10;

data[4] = m01;

data[5] = m11;

}

} else {

throw new IndexOutOfBoundsException("Array size must be 4, 9 or 16 in Matrix3f.get().");

}

}

}



/**

  • <code>getColumn</code> returns one of three columns specified by the
  • parameter. This column is returned as a <code>Vector2f</code> object.

    *
  • @param i
  •        the column to retrieve. Must be 0 or 1.<br />
    
  • @return the column specified by the index.

    */

    public Vector2f getColumn(int i) {

    return getColumn(i, null);

    }



    /**
  • <code>getColumn</code> returns one of three columns specified by the
  • parameter. This column is returned as a <code>Vector2f</code> object.

    *
  • @param i
  •        the column to retrieve. Must be 0 or 1.<br />
    
  • @param store
  •        the vector object to store the result in. if null, a new one<br />
    
  •        is created.<br />
    
  • @return the column specified by the index.

    */

    public Vector2f getColumn(int i, Vector2f store) {

    if (store == null) {

    store = new Vector2f();

    }

    switch (i) {

    case 0:

    store.x = m00;

    store.y = m10;

    break;

    case 1:

    store.x = m01;

    store.y = m11;

    break;

    default:

    logger.warning("Invalid column index.");

    throw new IllegalArgumentException("Invalid column index. " + i);

    }

    return store;

    }



    /**
  • <code>getRow</code> returns one of three rows as specified by the
  • parameter. This row is returned as a <code>Vector2f</code> object.

    *
  • @param i
  •        the row to retrieve. Must be 0 or 1.<br />
    
  • @return the row specified by the index.

    */

    public Vector2f getRow(int i) {

    return getRow(i, null);

    }



    /**
  • <code>getRow</code> returns one of three rows as specified by the
  • parameter. This row is returned as a <code>Vector2f</code> object.

    *
  • @param i
  •        the row to retrieve. Must be 0 or 1.<br />
    
  • @param store
  •        the vector object to store the result in. if null, a new one<br />
    
  •        is created.<br />
    
  • @return the row specified by the index.

    */

    public Vector2f getRow(int i, Vector2f store) {

    if (store == null) {

    store = new Vector2f();

    }

    switch (i) {

    case 0:

    store.x = m00;

    store.y = m01;

    break;

    case 1:

    store.x = m10;

    store.y = m11;

    break;

    default:

    logger.warning("Invalid row index.");

    throw new IllegalArgumentException("Invalid row index. " + i);

    }

    return store;

    }



    /**
  • <code>toFloatBuffer</code> returns a FloatBuffer object that contains
  • the matrix data.

    *
  • @return matrix data as a FloatBuffer.

    */

    public FloatBuffer toFloatBuffer() {

    FloatBuffer fb = BufferUtils.createFloatBuffer(4);



    fb.put(m00).put(m01);

    fb.put(m10).put(m11);

    fb.rewind();

    return fb;

    }



    /**
  • <code>fillFloatBuffer</code> fills a FloatBuffer object with the matrix
  • data.

    *
  • @param fb
  •        the buffer to fill, starting at current position. Must have<br />
    
  •        room for 4 more floats.<br />
    
  • @return matrix data as a FloatBuffer. (position is advanced by 4 and any
  •     limit set is not changed).<br />
    

*/

// public FloatBuffer fillFloatBuffer(FloatBuffer fb, boolean columnMajor) {

// TempVars vars = TempVars.get();

//

//

// fillFloatArray(vars.matrixWrite, columnMajor);

// fb.put(vars.matrixWrite, 0, 4);

//

// vars.release();

//

// return fb;

// }

public void fillFloatArray(float[] f, boolean columnMajor) {

if (columnMajor) {

f[0] = m00;

f[1] = m10;

f[2] = m01;

f[3] = m11;

} else {

f[0] = m00;

f[1] = m01;

f[3] = m10;

f[4] = m11;

}

}



/**

*

  • <code>setColumn</code> sets a particular column of this matrix to that
  • represented by the provided vector.

    *
  • @param i
  •        the column to set.<br />
    
  • @param column
  •        the data to set.<br />
    
  • @return this

    */

    public Matrix2f setColumn(int i, Vector2f column) {



    if (column == null) {

    logger.warning("Column is null. Ignoring.");

    return this;

    }

    switch (i) {

    case 0:

    m00 = column.x;

    m10 = column.y;

    break;

    case 1:

    m01 = column.x;

    m11 = column.y;

    break;

    default:

    logger.warning("Invalid column index.");

    throw new IllegalArgumentException("Invalid column index. " + i);

    }

    return this;

    }



    /**

    *
  • <code>setRow</code> sets a particular row of this matrix to that
  • represented by the provided vector.

    *
  • @param i
  •        the row to set.<br />
    
  • @param row
  •        the data to set.<br />
    
  • @return this

    */

    public Matrix2f setRow(int i, Vector2f row) {



    if (row == null) {

    logger.warning("Row is null. Ignoring.");

    return this;

    }

    switch (i) {

    case 0:

    m00 = row.x;

    m01 = row.y;

    break;

    case 1:

    m10 = row.x;

    m11 = row.y;

    break;

    default:

    logger.warning("Invalid row index.");

    throw new IllegalArgumentException("Invalid row index. " + i);

    }

    return this;

    }



    /**
  • <code>set</code> places a given value into the matrix at the given
  • position. If the position is invalid a <code>JmeException</code> is
  • thrown.

    *
  • @param i
  •        the row index.<br />
    
  • @param j
  •        the colum index.<br />
    
  • @param value
  •        the value for (i, j).<br />
    
  • @return this

    */

    @SuppressWarnings("fallthrough")

    public Matrix2f set(int i, int j, float value) {

    switch (i) {

    case 0:

    switch (j) {

    case 0:

    m00 = value;

    return this;

    case 1:

    m01 = value;

    return this;

    }

    case 1:

    switch (j) {

    case 0:

    m10 = value;

    return this;

    case 1:

    m11 = value;

    return this;

    }

    }



    logger.warning("Invalid matrix index.");

    throw new IllegalArgumentException("Invalid indices into matrix.");

    }



    /**

    *
  • <code>set</code> sets the values of the matrix to those supplied by the
  • 2x2 two dimenion array.

    *
  • @param matrix
  •        the new values of the matrix.<br />
    
  • @throws JmeException
  •         if the array is not of size 4.<br />
    
  • @return this

    */

    public Matrix2f set(float[][] matrix) {

    if (matrix.length != 2 || matrix[0].length != 2) {

    throw new IllegalArgumentException(

    "Array must be of size 9.");

    }



    m00 = matrix[0][0];

    m01 = matrix[0][1];

    m10 = matrix[1][0];

    m11 = matrix[1][1];



    return this;

    }



    /**
  • Recreate Matrix using the provided axes.

    *
  • @param uAxis
  •        Vector3f<br />
    
  • @param vAxis
  •        Vector3f<br />
    

*/

public void fromAxes(Vector2f uAxis, Vector2f vAxis) {

m00 = uAxis.x;

m10 = uAxis.y;



m01 = vAxis.x;

m11 = vAxis.y;

}



/**

  • <code>set</code> sets the values of this matrix from an array of
  • values assuming that the data is rowMajor order;

    *
  • @param matrix
  •        the matrix to set the value to.<br />
    
  • @return this

    */

    public Matrix2f set(float[] matrix) {

    return set(matrix, true);

    }



    /**
  • <code>set</code> sets the values of this matrix from an array of
  • values;

    *
  • @param matrix
  •        the matrix to set the value to.<br />
    
  • @param rowMajor
  •        whether the incoming data is in row or column major order.<br />
    
  • @return this

    */

    public Matrix2f set(float[] matrix, boolean rowMajor) {

    if (matrix.length != 4) {

    throw new IllegalArgumentException(

    "Array must be of size 9.");

    }



    if (rowMajor) {

    m00 = matrix[0];

    m01 = matrix[1];

    m10 = matrix[2];

    m11 = matrix[3];

    } else {

    m00 = matrix[0];

    m01 = matrix[2];

    m10 = matrix[1];

    m11 = matrix[4];

    }

    return this;

    }



    /**
  • <code>loadIdentity</code> sets this matrix to the identity matrix.
  • Where all values are zero except those along the diagonal which are one.

    *

    */

    public void loadIdentity() {

    m01 = m10 = 0;

    m00 = m11 = 1;

    }



    /**
  • @return true if this matrix is identity

    */

    public boolean isIdentity() {

    return (m00 == 1 && m01 == 0)

    && (m10 == 0 && m11 == 1);

    }



    /**
  • <code>fromAngle</code> sets this matrix2f to the values
  • specified by an angle of rotation.

    *
  • @param angle
  •        the angle to rotate (in radians).<br />
    

*/

public void fromAngle(float angle) {

float fCos = FastMath.cos(angle);

float fSin = FastMath.sin(angle);



m00 = fCos;

m01 = -fSin;

m10 = fSin;

m11 = fCos;

}



/**

  • <code>mult</code> multiplies this matrix by a given matrix. The result
  • matrix is returned as a new object. If the given matrix is null, a null
  • matrix is returned.

    *
  • @param mat
  •        the matrix to multiply this matrix by.<br />
    
  • @return the result matrix.

    */

    public Matrix2f mult(Matrix2f mat) {

    return mult(mat, null);

    }



    /**
  • <code>mult</code> multiplies this matrix by a given matrix. The result
  • matrix is returned as a new object.

    *
  • @param mat
  •        the matrix to multiply this matrix by.<br />
    
  • @param product
  •        the matrix to store the result in. if null, a new matrix3f is<br />
    
  •        created.  It is safe for mat and product to be the same object.<br />
    
  • @return a matrix2f object containing the result of this operation

    */

    public Matrix2f mult(Matrix2f mat, Matrix2f product) {



    float temp00, temp01;

    float temp10, temp11;



    if (product == null) {

    product = new Matrix2f();

    }

    temp00 = m00 * mat.m00 + m01 * mat.m10;

    temp01 = m00 * mat.m01 + m01 * mat.m11;

    temp10 = m10 * mat.m00 + m11 * mat.m10;

    temp11 = m10 * mat.m01 + m11 * mat.m11;



    product.m00 = temp00;

    product.m01 = temp01;

    product.m10 = temp10;

    product.m11 = temp11;



    return product;

    }



    /**
  • <code>mult</code> multiplies this matrix by a given
  • <code>Vector2f</code> object. The result vector is returned. If the
  • given vector is null, null will be returned.

    *
  • @param vec
  •        the vector to multiply this matrix by.<br />
    
  • @return the result vector.

    */

    public Vector2f mult(Vector2f vec) {

    return mult(vec, null);

    }



    /**
  • Multiplies this 2x2 matrix by the 1x2 Vector vec and stores the result in
  • product.

    *
  • @param vec
  •        The Vector2f to multiply.<br />
    
  • @param product
  •        The Vector2f to store the result, it is safe for this to be<br />
    
  •        the same as vec.<br />
    
  • @return The given product vector.

    */

    public Vector2f mult(Vector2f vec, Vector2f product) {



    if (null == product) {

    product = new Vector2f();

    }



    float x = vec.x;

    float y = vec.y;



    product.x = m00 * x + m01 * y;

    product.y = m10 * x + m11 * y;



    return product;

    }



    /**
  • <code>multLocal</code> multiplies this matrix internally by
  • a given float scale factor.

    *
  • @param scale
  •        the value to scale by.<br />
    
  • @return this Matrix2f

    */

    public Matrix2f multLocal(float scale) {

    m00 *= scale;

    m01 *= scale;

    m10 *= scale;

    m11 *= scale;



    return this;

    }



    /**
  • <code>multLocal</code> multiplies this matrix by a given
  • <code>Vector2f</code> object. The result vector is stored inside the
  • passed vector, then returned . If the given vector is null, null will be
  • returned.

    *
  • @param vec
  •        the vector to multiply this matrix by.<br />
    
  • @return The passed vector after multiplication

    */

    public Vector2f multLocal(Vector2f vec) {

    if (vec == null) {

    return null;

    }

    float x = vec.x;

    float y = vec.y;

    vec.x = m00 * x + m01 * y;

    vec.y = m10 * x + m11 * y;

    return vec;

    }



    /**
  • <code>mult</code> multiplies this matrix by a given matrix. The result
  • matrix is saved in the current matrix. If the given matrix is null,
  • nothing happens. The current matrix is returned. This is equivalent to
  • this*=mat

    *
  • @param mat
  •        the matrix to multiply this matrix by.<br />
    
  • @return This matrix, after the multiplication

    */

    public Matrix2f multLocal(Matrix2f mat) {

    return mult(mat, this);

    }



    /**
  • Transposes this matrix in place. Returns this matrix for chaining

    *
  • @return This matrix after transpose

    */

    public Matrix2f transposeLocal() {



    float tmp = m01;

    m01 = m10;

    m10 = tmp;



    return this;

    }



    /**
  • Inverts this matrix as a new Matrix2f.

    *
  • @return The new inverse matrix

    */

    public Matrix2f invert() {

    return invert(null);

    }



    /**
  • Inverts this matrix and stores it in the given store.

    *
  • @return The store

    */

    public Matrix2f invert(Matrix2f store) {

    if (store == null) {

    store = new Matrix2f();

    }



    float det = determinant();

    if (FastMath.abs(det) <= FastMath.FLT_EPSILON) {

    return store.zero();

    }



    store.m00 = m11;

    store.m01 = -m01;

    store.m10 = -m10;

    store.m11 = m00;



    store.multLocal(1f / det);

    return store;

    }



    /**
  • Inverts this matrix locally.

    *
  • @return this

    */

    public Matrix2f invertLocal() {

    float det = determinant();

    if (FastMath.abs(det) <= 0f) {

    return zero();

    }



    float f00 = m11;

    float f01 = -m01;

    float f10 = -m10;

    float f11 = m00;



    m00 = f00;

    m01 = f01;

    m10 = f10;

    m11 = f11;



    multLocal(1f / det);

    return this;

    }



    /**
  • Returns a new matrix representing the adjoint of this matrix.

    *
  • @return The adjoint matrix

    */

    public Matrix2f adjoint() {

    return adjoint(null);

    }



    /**
  • Places the adjoint of this matrix in store (creates store if null.)

    *
  • @param store
  •        The matrix to store the result in.  If null, a new matrix is created.<br />
    
  • @return store

    */

    public Matrix2f adjoint(Matrix2f store) {

    if (store == null) {

    store = new Matrix2f();

    }



    store.m00 = m11;

    store.m01 = -m01;

    store.m10 = -m10;

    store.m11 = m00;



    return store;

    }



    /**
  • <code>determinant</code> generates the determinant of this matrix.

    *
  • @return the determinant

    */

    public float determinant() {

    float fDet = m00 * m11 - m01 * m10;

    return fDet;

    }



    /**
  • Sets all of the values in this matrix to zero.

    *
  • @return this matrix

    */

    public Matrix2f zero() {

    m00 = m01 = m10 = m11 = 0.0f;

    return this;

    }



    /**
  • <code>transposeNew</code> returns a transposed version of this matrix.

    *
  • @return The new Matrix2f object.

    */

    public Matrix2f transpose() {

    Matrix2f ret = new Matrix2f(m00, m10, m01, m11);

    return ret;

    }



    /**
  • <code>toString</code> returns the string representation of this object.
  • It is in a format of a 2x2 matrix. For example, an identity matrix would
  • be represented by the following string. com.jme.math.Matrix2f <br>[<br>
  • 1.0 0.0<br>
  • 0.0 1.0<br>]<br>

    *
  • @return the string representation of this object.

    */

    @Override

    public String toString() {

    StringBuilder result = new StringBuilder("Matrix3fn[n");

    result.append(" ");

    result.append(m00);

    result.append(" ");

    result.append(m01);

    result.append(" n");

    result.append(" ");

    result.append(m10);

    result.append(" ");

    result.append(m11);

    result.append(" n]");

    return result.toString();

    }



    /**

    *
  • <code>hashCode</code> returns the hash code value as an integer and is
  • supported for the benefit of hashing based collection classes such as
  • Hashtable, HashMap, HashSet etc.

    *
  • @return the hashcode for this instance of Matrix2f.
  • @see java.lang.Object#hashCode()

    */

    @Override

    public int hashCode() {

    int hash = 37;

    hash = 37 * hash + Float.floatToIntBits(m00);

    hash = 37 * hash + Float.floatToIntBits(m01);



    hash = 37 * hash + Float.floatToIntBits(m10);

    hash = 37 * hash + Float.floatToIntBits(m11);



    return hash;

    }



    /**
  • are these two matrices the same? they are is they both have the same mXX values.

    *
  • @param o
  •        the object to compare for equality<br />
    
  • @return true if they are equal

    */

    @Override

    public boolean equals(Object o) {

    if (!(o instanceof Matrix2f) || o == null) {

    return false;

    }



    if (this == o) {

    return true;

    }



    Matrix2f comp = (Matrix2f) o;

    if (Float.compare(m00, comp.m00) != 0) {

    return false;

    }

    if (Float.compare(m01, comp.m01) != 0) {

    return false;

    }



    if (Float.compare(m10, comp.m10) != 0) {

    return false;

    }

    if (Float.compare(m11, comp.m11) != 0) {

    return false;

    }



    return true;

    }



    public void write(JmeExporter e) throws IOException {

    OutputCapsule cap = e.getCapsule(this);

    cap.write(m00, "m00", 1);

    cap.write(m01, "m01", 0);

    cap.write(m10, "m10", 0);

    cap.write(m11, "m11", 1);

    }



    public void read(JmeImporter e) throws IOException {

    InputCapsule cap = e.getCapsule(this);

    m00 = cap.readFloat("m00", 1);

    m01 = cap.readFloat("m01", 0);

    m10 = cap.readFloat("m10", 0);

    m11 = cap.readFloat("m11", 1);

    }



    /**
  • <code>scale</code> scales the operation performed by this matrix on a
  • per-component basis.

    *
  • @param scale
  •     The scale applied to the X and Y output values.<br />
    

*/

public void scale(Vector2f scale) {

m00 *= scale.x;

m10 *= scale.x;

m01 *= scale.y;

m11 *= scale.y;

}



static boolean equalIdentity(Matrix2f mat) {

if (Math.abs(mat.m00 - 1) > 1e-4) {

return false;

}

if (Math.abs(mat.m11 - 1) > 1e-4) {

return false;

}



if (Math.abs(mat.m01) > 1e-4) {

return false;

}



if (Math.abs(mat.m10) > 1e-4) {

return false;

}



return true;

}



@Override

public Matrix2f clone() {

try {

return (Matrix2f) super.clone();

} catch (CloneNotSupportedException e) {

throw new AssertionError(); // can not happen

}

}

}

[/java]

1 Like

Ok seems line 55 should be the text “1x1 in the matrix,”. That’s an error in the comments.

Some errors in the comments starting at line 140 as well. It’s not complete. I’ll clean up the comments some more…

Maybe invert and invertLocal should just run adjoint then multiply with 1/det instead of having its own code. Would work just as well (in the 3 and 4d versions as well). Not that it really matters.

[java]*

  • <code>Matrix3f</code> defines a 3x3 matrix. Matrix data is maintained
  • internally and is accessible via the get and set methods. Convenience methods
  • are used for matrix operations as well as generating a matrix from a given
  • set of values.

    *

    [/java]



    This comment seems to need updating too…

Thanks but ugh… diff please.

Ok. Yeah i left that there since its basically the same code as in Matrix3f, like an attribution.

@normen said:
Thanks but ugh.. diff please.


diff of what? It's a new class.
@pspeed said:
diff of what? It's a new class.

errr.... the folder :P yeah, saw that is was a new class just now but theres a handful of people who will always be there to correct me ^^

I am adding some more stuff to the class. Like if you use “fromAngle(float angle)”, it returns the object now, so you can “Matrix2f rot = new Matrix2f().fromAngle(float f)”. Not sure if that should be useful for others tho.



A constructor would be a better alternative I guess “Matrix2f(float angleOfRotation)”.



It’s just based on my experience tho, I use them only for rotating vectors (2f).