[DEV] reorder class

This commit is contained in:
Edouard DUPIN 2021-02-08 00:20:01 +01:00
parent ea862edd8c
commit d55b83f5b8
4 changed files with 1158 additions and 1087 deletions

View File

@ -1,12 +1,63 @@
package org.atriasoft.etk.math; package org.atriasoft.etk.math;
public class Matrix3f { public class Matrix3f {
public float[] mat = new float[3*3]; //!< matrix data /**
* @brief create a skew-symmetric matrix using a given vector that can be used to compute cross product with another vector using matrix multiplication
* @param vector Vector to comute
* @return Matrix to compute
*/
public static Matrix3f computeSkewSymmetricMatrixForCrossProduct(final Vector3f vector) {
return new Matrix3f(0.0f, -vector.z, vector.y, vector.z, 0.0f, -vector.x, -vector.y, vector.x, 0.0f);
}
/**
* @brief Create a matrix 3D with a simple rotation
* @param normal vector aroud witch apply the rotation
* @param angleRad Radian angle to set at the matrix
* @return New matrix of the transformation requested
*/
public static Matrix3f createMatrixRotate(final Vector3f normal, final float angleRad) {
final Matrix3f tmp = new Matrix3f();
final float cosVal = (float) Math.cos(angleRad);
final float sinVal = (float) Math.sin(angleRad);
final float invVal = 1.0f - cosVal;
// set rotation :
tmp.mat[0] = normal.x * normal.x * invVal + cosVal;
tmp.mat[1] = normal.x * normal.y * invVal - normal.z * sinVal;
tmp.mat[2] = normal.x * normal.z * invVal + normal.y * sinVal;
tmp.mat[3] = normal.y * normal.x * invVal + normal.z * sinVal;
tmp.mat[4] = normal.y * normal.y * invVal + cosVal;
tmp.mat[5] = normal.y * normal.z * invVal - normal.x * sinVal;
tmp.mat[6] = normal.z * normal.x * invVal - normal.y * sinVal;
tmp.mat[7] = normal.z * normal.y * invVal + normal.x * sinVal;
tmp.mat[8] = normal.z * normal.z * invVal + cosVal;
return tmp;
}
/**
* @brief create a Identity matrix
* @return created new matrix
*/
public static Matrix3f identity() {
return new Matrix3f(1, 0, 0, 0, 1, 0, 0, 0, 1);
}
/**
* @brief create a ZERO matrix
* @return created new matrix
*/
public static Matrix3f zero() {
return new Matrix3f(0, 0, 0, 0, 0, 0, 0, 0, 0);
}
public float[] mat = new float[3 * 3]; //!< matrix data
/** /**
* @brief Constructor that load zero matrix * @brief Constructor that load zero matrix
*/ */
public Matrix3f(){ public Matrix3f() {
this.mat[0] = 0.0f; this.mat[0] = 0.0f;
this.mat[1] = 0.0f; this.mat[1] = 0.0f;
this.mat[2] = 0.0f; this.mat[2] = 0.0f;
@ -17,11 +68,12 @@ public class Matrix3f {
this.mat[7] = 0.0f; this.mat[7] = 0.0f;
this.mat[8] = 0.0f; this.mat[8] = 0.0f;
} }
/** /**
* @brief Configuration constructorwith single value. * @brief Configuration constructorwith single value.
* @param value single value * @param value single value
*/ */
public Matrix3f(float value){ public Matrix3f(final float value) {
this.mat[0] = value; this.mat[0] = value;
this.mat[1] = value; this.mat[1] = value;
this.mat[2] = value; this.mat[2] = value;
@ -32,6 +84,7 @@ public class Matrix3f {
this.mat[7] = value; this.mat[7] = value;
this.mat[8] = value; this.mat[8] = value;
} }
/** /**
* @brief Configuration constructor. * @brief Configuration constructor.
* @param a1 element 0x0 * @param a1 element 0x0
@ -44,19 +97,23 @@ public class Matrix3f {
* @param c2 element 2x1 * @param c2 element 2x1
* @param c3 element 2x2 * @param c3 element 2x2
*/ */
public Matrix3f(float a1, float a2, float a3, public Matrix3f(final float a1, final float a2, final float a3, final float b1, final float b2, final float b3, final float c1, final float c2, final float c3) {
float b1, float b2, float b3, this.mat[0] = a1;
float c1, float c2, float c3) { this.mat[1] = a2;
this.mat[0] = a1; this.mat[1] = a2; this.mat[2] = a3; this.mat[2] = a3;
this.mat[3] = b1; this.mat[4] = b2; this.mat[5] = b3; this.mat[3] = b1;
this.mat[6] = c1; this.mat[7] = c2; this.mat[8] = c3; this.mat[4] = b2;
this.mat[5] = b3;
this.mat[6] = c1;
this.mat[7] = c2;
this.mat[8] = c3;
} }
/** /**
* @brief Copy constructor. * @brief Copy constructor.
* @param obj Matrix object to copy * @param obj Matrix object to copy
*/ */
public Matrix3f(Matrix3f obj) { public Matrix3f(final Matrix3f obj) {
this.mat[0] = obj.mat[0]; this.mat[0] = obj.mat[0];
this.mat[1] = obj.mat[1]; this.mat[1] = obj.mat[1];
this.mat[2] = obj.mat[2]; this.mat[2] = obj.mat[2];
@ -67,6 +124,349 @@ public class Matrix3f {
this.mat[7] = obj.mat[7]; this.mat[7] = obj.mat[7];
this.mat[8] = obj.mat[8]; this.mat[8] = obj.mat[8];
} }
/**
* @brief absolutise the matrix
*/
public Matrix3f abs() {
this.mat[0] = Math.abs(this.mat[0]);
this.mat[1] = Math.abs(this.mat[1]);
this.mat[2] = Math.abs(this.mat[2]);
this.mat[3] = Math.abs(this.mat[3]);
this.mat[4] = Math.abs(this.mat[4]);
this.mat[5] = Math.abs(this.mat[5]);
this.mat[6] = Math.abs(this.mat[6]);
this.mat[7] = Math.abs(this.mat[7]);
this.mat[8] = Math.abs(this.mat[8]);
return this;
}
@Deprecated
public void absolute() {
this.mat[0] = Math.abs(this.mat[0]);
this.mat[1] = Math.abs(this.mat[1]);
this.mat[2] = Math.abs(this.mat[2]);
this.mat[3] = Math.abs(this.mat[3]);
this.mat[4] = Math.abs(this.mat[4]);
this.mat[5] = Math.abs(this.mat[5]);
this.mat[6] = Math.abs(this.mat[6]);
this.mat[7] = Math.abs(this.mat[7]);
this.mat[8] = Math.abs(this.mat[8]);
}
/**
* @brief Operator+= Addition an other matrix with this one
* @param obj Reference on the external object
* @return Local reference of the vector additionned
*/
public Matrix3f add(final Matrix3f obj) {
for (int iii = 0; iii < 3 * 3; ++iii) {
this.mat[iii] += obj.mat[iii];
}
return this;
}
/**
* @brief Operator+ Addition an other matrix with this one
* @param obj Reference on the external object
* @return New vector containing the value
*/
public Matrix3f addNew(final Matrix3f obj) {
final Matrix3f tmp = new Matrix3f(this);
tmp.add(obj);
return tmp;
}
// Return a skew-symmetric matrix using a given vector that can be used
// to compute cross product with another vector using matrix multiplication
public Matrix3f computeSkewSymmetricMatrixForCrossProductNew(final Vector3f vector) {
return new Matrix3f(0.0f, -vector.z, vector.y, vector.z, 0, -vector.x, -vector.y, vector.x, 0.0f);
}
/**
* @brief Computes the determinant of the matrix.
* @return The determinent Value.
*/
public float determinant() {
return this.mat[0] * (this.mat[4] * this.mat[8] - this.mat[7] * this.mat[5]) - this.mat[1] * (this.mat[3] * this.mat[8] - this.mat[6] * this.mat[5])
+ this.mat[2] * (this.mat[3] * this.mat[7] - this.mat[6] * this.mat[4]);
}
@Override
public boolean equals(final Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Matrix3f other = (Matrix3f) obj;
for (int iii = 0; iii < 3 * 3; ++iii) {
if (Float.floatToIntBits(this.mat[iii]) != Float.floatToIntBits(other.mat[iii])) {
return false;
}
}
return true;
}
public float get(final int iii) {
return this.mat[iii];
}
/**
* @brief get the matrix with the absolute value
* @return matix in absolute
*/
public Matrix3f getAbsolute() {
return new Matrix3f(Math.abs(this.mat[0]), Math.abs(this.mat[1]), Math.abs(this.mat[2]), Math.abs(this.mat[3]), Math.abs(this.mat[4]), Math.abs(this.mat[5]), Math.abs(this.mat[6]),
Math.abs(this.mat[7]), Math.abs(this.mat[8]));
}
/**
* @brief get the colom id values
* @param iii Id of the colomn
* @return Vector 3D vith the values
*/
public Vector3f getColumn(final int iii) {
if (iii == 0) {
return new Vector3f(this.mat[0], this.mat[3], this.mat[6]);
} else if (iii == 1) {
return new Vector3f(this.mat[1], this.mat[4], this.mat[7]);
}
return new Vector3f(this.mat[2], this.mat[5], this.mat[8]);
}
/**
* @brief get the row id values
* @param iii Id of the row
* @return Vector 3D vith the values
*/
public Vector3f getRow(final int iii) {
if (iii == 0) {
return new Vector3f(this.mat[0], this.mat[1], this.mat[2]);
} else if (iii == 1) {
return new Vector3f(this.mat[3], this.mat[4], this.mat[5]);
}
return new Vector3f(this.mat[6], this.mat[7], this.mat[8]);
}
/**
* @brief Calculate the trace of the matrix
* @return value of addition of all element in the diagonal
*/
public float getTrace() {
return (this.mat[0] + this.mat[4] + this.mat[8]);
}
@Override
public int hashCode() {
int hash = 1542;
hash += Float.floatToIntBits(this.mat[0]);
hash += Float.floatToIntBits(this.mat[1]);
hash += Float.floatToIntBits(this.mat[2]);
hash += Float.floatToIntBits(this.mat[3]);
hash += Float.floatToIntBits(this.mat[4]);
hash += Float.floatToIntBits(this.mat[5]);
hash += Float.floatToIntBits(this.mat[6]);
hash += Float.floatToIntBits(this.mat[7]);
hash += Float.floatToIntBits(this.mat[8]);
return hash;
}
/**
* @brief Inverts the current matrix.
* @note The determinant must be != 0, otherwithe the matrix can't be inverted.
*/
public Matrix3f inverse() {
final float det = determinant();
//assert(Math.abs(det) > MACHINEEPSILON);
final float invDet = 1.0f / det;
this.set((this.mat[4] * this.mat[8] - this.mat[7] * this.mat[5]), -(this.mat[1] * this.mat[8] - this.mat[7] * this.mat[2]), (this.mat[1] * this.mat[5] - this.mat[2] * this.mat[4]),
-(this.mat[3] * this.mat[8] - this.mat[6] * this.mat[5]), (this.mat[0] * this.mat[8] - this.mat[6] * this.mat[2]), -(this.mat[0] * this.mat[5] - this.mat[3] * this.mat[2]),
(this.mat[3] * this.mat[7] - this.mat[6] * this.mat[4]), -(this.mat[0] * this.mat[7] - this.mat[6] * this.mat[1]), (this.mat[0] * this.mat[4] - this.mat[1] * this.mat[3]));
this.multiply(invDet);
return this;
}
/**
* @brief Inverse the matrix.
* @note The determinant must be != 0, otherwithe the matrix can't be inverted.
* @return The inverted matrix.
*/
public Matrix3f inverseNew() {
final Matrix3f tmp = new Matrix3f(this);
tmp.inverse();
return tmp;
}
// Overloaded operator for the negative of the matrix
public Matrix3f invert() {
this.mat[0] = -this.mat[0];
this.mat[1] = -this.mat[1];
this.mat[2] = -this.mat[2];
this.mat[3] = -this.mat[3];
this.mat[4] = -this.mat[4];
this.mat[5] = -this.mat[5];
this.mat[6] = -this.mat[6];
this.mat[7] = -this.mat[7];
this.mat[8] = -this.mat[8];
return this;
}
/**
* @brief In-Equality compare operator with an other object.
* @param obj Reference on the comparing object
* @return true The Objects are NOT identical
* @return false The Objects are identical
*/
public boolean isDifferent(final Matrix3f obj) {
for (int iii = 0; iii < 3 * 3; ++iii) {
if (this.mat[iii] != obj.mat[iii]) {
return true;
}
}
return false;
}
/**
* @brief Equality compare operator with an other object.
* @param obj Reference on the comparing object
* @return true The Objects are identical
* @return false The Objects are NOT identical
*/
boolean isEqual(final Matrix3f obj) {
for (int iii = 0; iii < 3 * 3; ++iii) {
if (this.mat[iii] != obj.mat[iii]) {
return false;
}
}
return true;
}
/**
* @brief Operator-= Decrement an other matrix with this one
* @param obj Reference on the external object
* @return Local reference of the vector decremented
*/
public Matrix3f less(final Matrix3f obj) {
for (int iii = 0; iii < 3 * 3; ++iii) {
this.mat[iii] -= obj.mat[iii];
}
return this;
}
/**
* @brief Operator- Decrement an other matrix with this one
* @param obj Reference on the external object
* @return New vector containing the value
*/
public Matrix3f lessNew(final Matrix3f obj) {
final Matrix3f tmp = new Matrix3f(this);
tmp.less(obj);
return tmp;
}
/**
* @brief Operator*= Multiplication a value
* @param value value to multiply all the matrix
* @return Local reference of the vector multiplicated
*/
public Matrix3f multiply(final float value) {
this.mat[0] *= value;
this.mat[1] *= value;
this.mat[2] *= value;
this.mat[3] *= value;
this.mat[4] *= value;
this.mat[5] *= value;
this.mat[6] *= value;
this.mat[7] *= value;
this.mat[8] *= value;
return this;
}
/**
* @brief Operator*= Multiplication an other matrix with this one
* @param obj Reference on the external object
* @return Local reference of the vector multiplicated
*/
public Matrix3f multiply(final Matrix3f obj) {
final float a1 = this.mat[0] * obj.mat[0] + this.mat[1] * obj.mat[3] + this.mat[2] * obj.mat[6];
final float b1 = this.mat[3] * obj.mat[0] + this.mat[4] * obj.mat[3] + this.mat[5] * obj.mat[6];
final float c1 = this.mat[6] * obj.mat[0] + this.mat[7] * obj.mat[3] + this.mat[8] * obj.mat[6];
final float a2 = this.mat[0] * obj.mat[1] + this.mat[1] * obj.mat[4] + this.mat[2] * obj.mat[7];
final float b2 = this.mat[3] * obj.mat[1] + this.mat[4] * obj.mat[4] + this.mat[5] * obj.mat[7];
final float c2 = this.mat[6] * obj.mat[1] + this.mat[7] * obj.mat[4] + this.mat[8] * obj.mat[7];
this.mat[2] = this.mat[0] * obj.mat[2] + this.mat[1] * obj.mat[5] + this.mat[2] * obj.mat[8];
this.mat[5] = this.mat[3] * obj.mat[2] + this.mat[4] * obj.mat[5] + this.mat[5] * obj.mat[8];
this.mat[8] = this.mat[6] * obj.mat[2] + this.mat[7] * obj.mat[5] + this.mat[8] * obj.mat[8];
this.mat[0] = a1;
this.mat[3] = b1;
this.mat[6] = c1;
this.mat[1] = a2;
this.mat[4] = b2;
this.mat[7] = c2;
return this;
}
/**
* @brief Operator*= Multiplication a value
* @param value value to multiply all the matrix
* @return Local reference of the vector multiplicated
*/
public Matrix3f multiplyNew(final float value) {
final Matrix3f tmp = new Matrix3f(this);
tmp.multiply(value);
return tmp;
}
/**
* @brief Operator* Multiplication an other matrix with this one
* @param obj Reference on the external object
* @return New vector containing the value
*/
public Matrix3f multiplyNew(final Matrix3f obj) {
final Matrix3f tmp = new Matrix3f(this);
tmp.multiply(obj);
return tmp;
}
/**
* @brief Operator* apply matrix on a vector
* @param point Point value to apply the matrix
* @return New vector containing the value
*/
public Vector3f multiplyNew(final Vector3f point) {
return new Vector3f((float) ((double) point.x * (double) this.mat[0] + (double) point.y * (double) this.mat[1] + (double) point.z * (double) this.mat[2]),
(float) ((double) point.x * (double) this.mat[3] + (double) point.y * (double) this.mat[4] + (double) point.z * (double) this.mat[5]),
(float) ((double) point.x * (double) this.mat[6] + (double) point.y * (double) this.mat[7] + (double) point.z * (double) this.mat[8]));
/*
return new Vector3f(point.x * this.mat[0] + point.y * this.mat[1] + point.z * this.mat[2], point.x * this.mat[3] + point.y * this.mat[4] + point.z * this.mat[5],
point.x * this.mat[6] + point.y * this.mat[7] + point.z * this.mat[8]);
*/
}
/**
* @brief Operator*= Multiplication an other matrix with this one
* @param obj Reference on the external object
* @return Local reference of the vector multiplicated
*/
public void multiplyTo(final Matrix3f obj, final Matrix3f out) {
out.mat[2] = this.mat[0] * obj.mat[2] + this.mat[1] * obj.mat[5] + this.mat[2] * obj.mat[8];
out.mat[5] = this.mat[3] * obj.mat[2] + this.mat[4] * obj.mat[5] + this.mat[5] * obj.mat[8];
out.mat[8] = this.mat[6] * obj.mat[2] + this.mat[7] * obj.mat[5] + this.mat[8] * obj.mat[8];
out.mat[0] = this.mat[0] * obj.mat[0] + this.mat[1] * obj.mat[3] + this.mat[2] * obj.mat[6];
out.mat[3] = this.mat[3] * obj.mat[0] + this.mat[4] * obj.mat[3] + this.mat[5] * obj.mat[6];
out.mat[6] = this.mat[6] * obj.mat[0] + this.mat[7] * obj.mat[3] + this.mat[8] * obj.mat[6];
out.mat[1] = this.mat[0] * obj.mat[1] + this.mat[1] * obj.mat[4] + this.mat[2] * obj.mat[7];
out.mat[4] = this.mat[3] * obj.mat[1] + this.mat[4] * obj.mat[4] + this.mat[5] * obj.mat[7];
out.mat[7] = this.mat[6] * obj.mat[1] + this.mat[7] * obj.mat[4] + this.mat[8] * obj.mat[7];
}
public void multiplyTo(final Vector3f point, final Vector3f out) {
out.set(point.x * this.mat[0] + point.y * this.mat[1] + point.z * this.mat[2], point.x * this.mat[3] + point.y * this.mat[4] + point.z * this.mat[5],
point.x * this.mat[6] + point.y * this.mat[7] + point.z * this.mat[8]);
}
/** /**
* @brief Set Value on the matrix * @brief Set Value on the matrix
* @param a1 element 0x0 * @param a1 element 0x0
@ -79,14 +479,47 @@ public class Matrix3f {
* @param c2 element 2x1 * @param c2 element 2x1
* @param c3 element 2x2 * @param c3 element 2x2
*/ */
public Matrix3f set(float a1, float a2, float a3, public Matrix3f set(final float a1, final float a2, final float a3, final float b1, final float b2, final float b3, final float c1, final float c2, final float c3) {
float b1, float b2, float b3, this.mat[0] = a1;
float c1, float c2, float c3) { this.mat[1] = a2;
this.mat[0] = a1; this.mat[1] = a2; this.mat[2] = a3; this.mat[2] = a3;
this.mat[3] = b1; this.mat[4] = b2; this.mat[5] = b3; this.mat[3] = b1;
this.mat[6] = c1; this.mat[7] = c2; this.mat[8] = c3; this.mat[4] = b2;
this.mat[5] = b3;
this.mat[6] = c1;
this.mat[7] = c2;
this.mat[8] = c3;
return this; return this;
} }
/**
* @brief Operator= Asign the current object with an other object
* @param obj Reference on the external object
* @return Local reference of the vector asigned
*/
public Matrix3f set(final Matrix3f obj) {
for (int iii = 0; iii < 3 * 3; ++iii) {
this.mat[iii] = obj.mat[iii];
}
return this;
}
/**
* @brief Load Identity matrix
*/
public Matrix3f setIdentity() {
this.mat[0] = 1.0f;
this.mat[1] = 0.0f;
this.mat[2] = 0.0f;
this.mat[3] = 0.0f;
this.mat[4] = 1.0f;
this.mat[5] = 0.0f;
this.mat[6] = 0.0f;
this.mat[7] = 0.0f;
this.mat[8] = 1.0f;
return this;
}
/** /**
* @brief Load Zero matrix * @brief Load Zero matrix
*/ */
@ -102,46 +535,13 @@ public class Matrix3f {
this.mat[8] = 0.0f; this.mat[8] = 0.0f;
return this; return this;
} }
/** @Override
* @brief get the colom id values public String toString() {
* @param iii Id of the colomn return "Matrix3f(" + this.mat[0] + "," + this.mat[1] + "," + this.mat[2] + "," + this.mat[3] + "," + this.mat[4] + "," + this.mat[5] + "," + this.mat[6] + "," + this.mat[7] + "," + this.mat[8]
* @return Vector 3D vith the values + ")";
*/
public Vector3f getColumn(int iii) {
if (iii == 0) {
return new Vector3f(this.mat[0], this.mat[3], this.mat[6]);
} else if (iii == 1) {
return new Vector3f(this.mat[1], this.mat[4], this.mat[7]);
}
return new Vector3f(this.mat[2], this.mat[5], this.mat[8]);
} }
/**
* @brief get the row id values
* @param iii Id of the row
* @return Vector 3D vith the values
*/
public Vector3f getRow(int iii) {
if (iii == 0) {
return new Vector3f(this.mat[0], this.mat[1], this.mat[2]);
} else if (iii == 1) {
return new Vector3f(this.mat[3], this.mat[4], this.mat[5]);
}
return new Vector3f(this.mat[6], this.mat[7], this.mat[8]);
}
public float get(int iii) {
return this.mat[iii];
}
/**
* @brief get a transpose matrix of this one.
* @return the transpose matrix
*/
public Matrix3f transposeNew() {
return new Matrix3f(this.mat[0], this.mat[3], this.mat[6],
this.mat[1], this.mat[4], this.mat[7],
this.mat[2], this.mat[5], this.mat[8]);
}
/** /**
* @brief Transpose the current matrix. * @brief Transpose the current matrix.
*/ */
@ -157,367 +557,12 @@ public class Matrix3f {
this.mat[7] = tmp; this.mat[7] = tmp;
return this; return this;
} }
/**
* @brief Computes the determinant of the matrix.
* @return The determinent Value.
*/
public float determinant() {
return this.mat[0] * (this.mat[4] * this.mat[8]-this.mat[7] * this.mat[5])
- this.mat[1] * (this.mat[3] * this.mat[8]-this.mat[6] * this.mat[5])
+ this.mat[2] * (this.mat[3] * this.mat[7]-this.mat[6] * this.mat[4]);
}
/**
* @brief Calculate the trace of the matrix
* @return value of addition of all element in the diagonal
*/
public float getTrace() {
return (this.mat[0] + this.mat[4] + this.mat[8]);
}
/**
* @brief Inverse the matrix.
* @note The determinant must be != 0, otherwithe the matrix can't be inverted.
* @return The inverted matrix.
*/
public Matrix3f inverseNew() {
Matrix3f tmp = new Matrix3f(this);
tmp.inverse();
return tmp;
}
/**
* @brief Inverts the current matrix.
* @note The determinant must be != 0, otherwithe the matrix can't be inverted.
*/
public Matrix3f inverse(){
float det = determinant();
//assert(Math.abs(det) > MACHINEEPSILON);
float invDet = 1.0f / det;
this.set( (this.mat[4] * this.mat[8]-this.mat[7] * this.mat[5]),
-(this.mat[1] * this.mat[8]-this.mat[7] * this.mat[2]),
(this.mat[1] * this.mat[5]-this.mat[2] * this.mat[4]),
-(this.mat[3] * this.mat[8]-this.mat[6] * this.mat[5]),
(this.mat[0] * this.mat[8]-this.mat[6] * this.mat[2]),
-(this.mat[0] * this.mat[5]-this.mat[3] * this.mat[2]),
(this.mat[3] * this.mat[7]-this.mat[6] * this.mat[4]),
-(this.mat[0] * this.mat[7]-this.mat[6] * this.mat[1]),
(this.mat[0] * this.mat[4]-this.mat[1] * this.mat[3]));
this.multiply(invDet);
return this;
}
// Overloaded operator for the negative of the matrix
public Matrix3f invert() {
this.mat[0] = -this.mat[0];
this.mat[1] = -this.mat[1];
this.mat[2] = -this.mat[2];
this.mat[3] = -this.mat[3];
this.mat[4] = -this.mat[4];
this.mat[5] = -this.mat[5];
this.mat[6] = -this.mat[6];
this.mat[7] = -this.mat[7];
this.mat[8] = -this.mat[8];
return this;
}
/**
* @brief get the matrix with the absolute value
* @return matix in absolute
*/
public Matrix3f getAbsolute() {
return new Matrix3f(Math.abs(this.mat[0]), Math.abs(this.mat[1]), Math.abs(this.mat[2]),
Math.abs(this.mat[3]), Math.abs(this.mat[4]), Math.abs(this.mat[5]),
Math.abs(this.mat[6]), Math.abs(this.mat[7]), Math.abs(this.mat[8]));
}
/**
* @brief absolutise the matrix
*/
public Matrix3f abs(){
this.mat[0] = Math.abs(this.mat[0]);
this.mat[1] = Math.abs(this.mat[1]);
this.mat[2] = Math.abs(this.mat[2]);
this.mat[3] = Math.abs(this.mat[3]);
this.mat[4] = Math.abs(this.mat[4]);
this.mat[5] = Math.abs(this.mat[5]);
this.mat[6] = Math.abs(this.mat[6]);
this.mat[7] = Math.abs(this.mat[7]);
this.mat[8] = Math.abs(this.mat[8]);
return this;
}
@Deprecated
public void absolute(){
this.mat[0] = Math.abs(this.mat[0]);
this.mat[1] = Math.abs(this.mat[1]);
this.mat[2] = Math.abs(this.mat[2]);
this.mat[3] = Math.abs(this.mat[3]);
this.mat[4] = Math.abs(this.mat[4]);
this.mat[5] = Math.abs(this.mat[5]);
this.mat[6] = Math.abs(this.mat[6]);
this.mat[7] = Math.abs(this.mat[7]);
this.mat[8] = Math.abs(this.mat[8]);
}
/**
* @brief Load Identity matrix
*/
public Matrix3f setIdentity(){
this.mat[0] = 1.0f; this.mat[1] = 0.0f; this.mat[2] = 0.0f;
this.mat[3] = 0.0f; this.mat[4] = 1.0f; this.mat[5] = 0.0f;
this.mat[6] = 0.0f; this.mat[7] = 0.0f; this.mat[8] = 1.0f;
return this;
}
/**
* @brief create a Identity matrix
* @return created new matrix
*/
public static Matrix3f identity() {
return new Matrix3f(1, 0, 0, 0, 1, 0, 0, 0, 1);
}
/**
* @brief create a ZERO matrix
* @return created new matrix
*/
public static Matrix3f zero() {
return new Matrix3f(0, 0, 0, 0, 0, 0, 0, 0, 0);
}
/**
* @brief create a skew-symmetric matrix using a given vector that can be used to compute cross product with another vector using matrix multiplication
* @param vector Vector to comute
* @return Matrix to compute
*/
public static Matrix3f computeSkewSymmetricMatrixForCrossProduct(Vector3f vector) {
return new Matrix3f( 0.0f , -vector.z, vector.y,
vector.z, 0.0f , -vector.x,
-vector.y, vector.x, 0.0f);
}
/**
* @brief Operator= Asign the current object with an other object
* @param obj Reference on the external object
* @return Local reference of the vector asigned
*/
public Matrix3f set(Matrix3f obj ){
for(int iii=0; iii<3*3 ; ++iii) {
this.mat[iii] = obj.mat[iii];
}
return this;
}
/**
* @brief Equality compare operator with an other object.
* @param obj Reference on the comparing object
* @return true The Objects are identical
* @return false The Objects are NOT identical
*/
boolean isEqual(Matrix3f obj) {
for(int iii=0; iii<3*3 ; ++iii) {
if(this.mat[iii] != obj.mat[iii]) {
return false;
}
}
return true;
}
/**
* @brief In-Equality compare operator with an other object.
* @param obj Reference on the comparing object
* @return true The Objects are NOT identical
* @return false The Objects are identical
*/
public boolean isDifferent(Matrix3f obj) {
for(int iii=0; iii<3*3 ; ++iii) {
if(this.mat[iii] != obj.mat[iii]) {
return true;
}
}
return false;
}
/**
* @brief Operator+= Addition an other matrix with this one
* @param obj Reference on the external object
* @return Local reference of the vector additionned
*/
public Matrix3f add(Matrix3f obj){
for(int iii=0; iii<3*3 ; ++iii) {
this.mat[iii] += obj.mat[iii];
}
return this;
}
/**
* @brief Operator+ Addition an other matrix with this one
* @param obj Reference on the external object
* @return New vector containing the value
*/
public Matrix3f addNew(Matrix3f obj) {
Matrix3f tmp = new Matrix3f(this);
tmp.add(obj);
return tmp;
}
/**
* @brief Operator-= Decrement an other matrix with this one
* @param obj Reference on the external object
* @return Local reference of the vector decremented
*/
public Matrix3f less(Matrix3f obj) {
for(int iii=0; iii<3*3 ; ++iii) {
this.mat[iii] -= obj.mat[iii];
}
return this;
}
/**
* @brief Operator- Decrement an other matrix with this one
* @param obj Reference on the external object
* @return New vector containing the value
*/
public Matrix3f lessNew(Matrix3f obj) {
Matrix3f tmp = new Matrix3f(this);
tmp.less(obj);
return tmp;
}
/**
* @brief Operator*= Multiplication an other matrix with this one
* @param obj Reference on the external object
* @return Local reference of the vector multiplicated
*/
public Matrix3f multiply(Matrix3f obj) {
float a1 = this.mat[0]*obj.mat[0] + this.mat[1]*obj.mat[3] + this.mat[2]*obj.mat[6];
float b1 = this.mat[3]*obj.mat[0] + this.mat[4]*obj.mat[3] + this.mat[5]*obj.mat[6];
float c1 = this.mat[6]*obj.mat[0] + this.mat[7]*obj.mat[3] + this.mat[8]*obj.mat[6];
float a2 = this.mat[0]*obj.mat[1] + this.mat[1]*obj.mat[4] + this.mat[2]*obj.mat[7];
float b2 = this.mat[3]*obj.mat[1] + this.mat[4]*obj.mat[4] + this.mat[5]*obj.mat[7];
float c2 = this.mat[6]*obj.mat[1] + this.mat[7]*obj.mat[4] + this.mat[8]*obj.mat[7];
this.mat[2] = this.mat[0]*obj.mat[2] + this.mat[1]*obj.mat[5] + this.mat[2]*obj.mat[8];
this.mat[5] = this.mat[3]*obj.mat[2] + this.mat[4]*obj.mat[5] + this.mat[5]*obj.mat[8];
this.mat[8] = this.mat[6]*obj.mat[2] + this.mat[7]*obj.mat[5] + this.mat[8]*obj.mat[8];
this.mat[0] = a1;
this.mat[3] = b1;
this.mat[6] = c1;
this.mat[1] = a2;
this.mat[4] = b2;
this.mat[7] = c2;
return this;
}
/**
* @brief Operator*= Multiplication an other matrix with this one
* @param obj Reference on the external object
* @return Local reference of the vector multiplicated
*/
public void multiplyTo(Matrix3f obj, Matrix3f out) {
out.mat[2] = this.mat[0]*obj.mat[2] + this.mat[1]*obj.mat[5] + this.mat[2]*obj.mat[8];
out.mat[5] = this.mat[3]*obj.mat[2] + this.mat[4]*obj.mat[5] + this.mat[5]*obj.mat[8];
out.mat[8] = this.mat[6]*obj.mat[2] + this.mat[7]*obj.mat[5] + this.mat[8]*obj.mat[8];
out.mat[0] = this.mat[0]*obj.mat[0] + this.mat[1]*obj.mat[3] + this.mat[2]*obj.mat[6];
out.mat[3] = this.mat[3]*obj.mat[0] + this.mat[4]*obj.mat[3] + this.mat[5]*obj.mat[6];
out.mat[6] = this.mat[6]*obj.mat[0] + this.mat[7]*obj.mat[3] + this.mat[8]*obj.mat[6];
out.mat[1] = this.mat[0]*obj.mat[1] + this.mat[1]*obj.mat[4] + this.mat[2]*obj.mat[7];
out.mat[4] = this.mat[3]*obj.mat[1] + this.mat[4]*obj.mat[4] + this.mat[5]*obj.mat[7];
out.mat[7] = this.mat[6]*obj.mat[1] + this.mat[7]*obj.mat[4] + this.mat[8]*obj.mat[7];
}
/**
* @brief Operator* Multiplication an other matrix with this one
* @param obj Reference on the external object
* @return New vector containing the value
*/
public Matrix3f multiplyNew(Matrix3f obj) {
Matrix3f tmp = new Matrix3f(this);
tmp.multiply(obj);
return tmp;
}
/**
* @brief Operator*= Multiplication a value
* @param value value to multiply all the matrix
* @return Local reference of the vector multiplicated
*/
public Matrix3f multiply(float value){
this.mat[0] *= value;
this.mat[1] *= value;
this.mat[2] *= value;
this.mat[3] *= value;
this.mat[4] *= value;
this.mat[5] *= value;
this.mat[6] *= value;
this.mat[7] *= value;
this.mat[8] *= value;
return this;
}
/**
* @brief Operator*= Multiplication a value
* @param value value to multiply all the matrix
* @return Local reference of the vector multiplicated
*/
public Matrix3f multiplyNew(float value) {
Matrix3f tmp = new Matrix3f(this);
tmp.multiply(value);
return tmp;
}
/**
* @brief Operator* apply matrix on a vector
* @param point Point value to apply the matrix
* @return New vector containing the value
*/
public Vector3f multiplyNew(Vector3f point) {
return new Vector3f(point.x * this.mat[0] + point.y * this.mat[1] + point.z * this.mat[2],
point.x * this.mat[3] + point.y * this.mat[4] + point.z * this.mat[5],
point.x * this.mat[6] + point.y * this.mat[7] + point.z * this.mat[8]);
}
public void multiplyTo(Vector3f point, Vector3f out) {
out.set(point.x * this.mat[0] + point.y * this.mat[1] + point.z * this.mat[2],
point.x * this.mat[3] + point.y * this.mat[4] + point.z * this.mat[5],
point.x * this.mat[6] + point.y * this.mat[7] + point.z * this.mat[8]);
}
/**
* @brief Create a matrix 3D with a simple rotation
* @param normal vector aroud witch apply the rotation
* @param angleRad Radian angle to set at the matrix
* @return New matrix of the transformation requested
*/
public static Matrix3f createMatrixRotate(Vector3f normal, float angleRad) {
Matrix3f tmp = new Matrix3f();
float cosVal = (float)Math.cos(angleRad);
float sinVal = (float)Math.sin(angleRad);
float invVal = 1.0f-cosVal;
// set rotation :
tmp.mat[0] = normal.x * normal.x * invVal + cosVal;
tmp.mat[1] = normal.x * normal.y * invVal - normal.z * sinVal;
tmp.mat[2] = normal.x * normal.z * invVal + normal.y * sinVal;
tmp.mat[3] = normal.y * normal.x * invVal + normal.z * sinVal;
tmp.mat[4] = normal.y * normal.y * invVal + cosVal;
tmp.mat[5] = normal.y * normal.z * invVal - normal.x * sinVal;
tmp.mat[6] = normal.z * normal.x * invVal - normal.y * sinVal;
tmp.mat[7] = normal.z * normal.y * invVal + normal.x * sinVal;
tmp.mat[8] = normal.z * normal.z * invVal + cosVal;
return tmp;
}
@Override
public int hashCode() {
int hash = 1542;
hash += Float.floatToIntBits(this.mat[0]);
hash += Float.floatToIntBits(this.mat[1]);
hash += Float.floatToIntBits(this.mat[2]);
hash += Float.floatToIntBits(this.mat[3]);
hash += Float.floatToIntBits(this.mat[4]);
hash += Float.floatToIntBits(this.mat[5]);
hash += Float.floatToIntBits(this.mat[6]);
hash += Float.floatToIntBits(this.mat[7]);
hash += Float.floatToIntBits(this.mat[8]);
return hash;
}
@Override /**
public boolean equals(Object obj) { * @brief get a transpose matrix of this one.
if (obj == null) { * @return the transpose matrix
return false; */
} public Matrix3f transposeNew() {
if (getClass() != obj.getClass()) { return new Matrix3f(this.mat[0], this.mat[3], this.mat[6], this.mat[1], this.mat[4], this.mat[7], this.mat[2], this.mat[5], this.mat[8]);
return false;
}
final Matrix3f other = (Matrix3f) obj;
for(int iii=0; iii<3*3 ; ++iii) {
if (Float.floatToIntBits(this.mat[iii]) != Float.floatToIntBits(other.mat[iii])) {
return false;
}
}
return true;
}
// Return a skew-symmetric matrix using a given vector that can be used
// to compute cross product with another vector using matrix multiplication
public Matrix3f computeSkewSymmetricMatrixForCrossProductNew(Vector3f vector) {
return new Matrix3f(0.0f, -vector.z, vector.y, vector.z, 0, -vector.x, -vector.y, vector.x, 0.0f);
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,64 +1,75 @@
package org.atriasoft.etk.math; package org.atriasoft.etk.math;
public class Transform3D { public class Transform3D {
protected Vector3f position; //! Position
protected Quaternion orientation; //!< Orientation
public Transform3D() {
this.position = Vector3f.zero();
this.orientation = Quaternion.identity();
}
public Transform3D(Vector3f position) {
this.position = position.clone();
this.orientation = Quaternion.identity();
}
public Transform3D(Vector3f position, Matrix3f orientation) {
this.position = position.clone();
this.orientation = new Quaternion(orientation);
}
public Transform3D(Vector3f position, Quaternion orientation) {
this.position = position.clone();
this.orientation = orientation.clone();
}
public Transform3D(Transform3D transform3d) {
this.position = transform3d.position.clone();
this.orientation = transform3d.orientation.clone();
}
public Vector3f getPosition() {
return position;
}
public void setPosition(Vector3f position) {
this.position = position;
}
public Quaternion getOrientation() {
return orientation;
}
public void setOrientation(Quaternion orientation) {
this.orientation = orientation;
}
/** /**
* @brief Get the identity of the transformation * @brief Get the identity of the transformation
*/ */
public static Transform3D identity() { public static Transform3D identity() {
return new Transform3D(Vector3f.zero(), Quaternion.identity()); return new Transform3D(Vector3f.zero(), Quaternion.identity());
} }
/// Set the Transform3D to the identity transform
public void setIdentity() { // Position
protected Vector3f position;
// Orientation
protected Quaternion orientation;
public Transform3D() {
this.position = Vector3f.zero(); this.position = Vector3f.zero();
this.orientation = Quaternion.identity(); this.orientation = Quaternion.identity();
} }
/// Set the transform from an OpenGL transform matrix
public void setFromOpenGL(float[] matrix) { public Transform3D(final Transform3D transform3d) {
Matrix3f tmpMatrix = new Matrix3f(matrix[0], matrix[4], matrix[8], this.position = transform3d.position.clone();
matrix[1], matrix[5], matrix[9], this.orientation = transform3d.orientation.clone();
matrix[2], matrix[6], matrix[10]);
this.orientation = new Quaternion(tmpMatrix);
this.position.setValue(matrix[12], matrix[13], matrix[14]);
} }
public Transform3D(final Vector3f position) {
this.position = position.clone();
this.orientation = Quaternion.identity();
}
public Transform3D(final Vector3f position, final Matrix3f orientation) {
this.position = position.clone();
this.orientation = new Quaternion(orientation);
}
public Transform3D(final Vector3f position, final Quaternion orientation) {
this.position = position.clone();
this.orientation = orientation.clone();
}
public void applyRotation(final Quaternion rotation) {
this.orientation = this.orientation.multiply(rotation);
}
/**
* @brief Clone the current Transform3D.
* @return New Transform3D containing the value
*/
@Override
public Transform3D clone() {
return new Transform3D(this);
}
@Override
public boolean equals(final Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Transform3D other = (Transform3D) obj;
if (!this.position.equals(this.position)) {
return false;
}
return this.orientation.equals(other.orientation);
}
/// Get the OpenGL matrix of the transform /// Get the OpenGL matrix of the transform
public Matrix4f getOpenGLMatrix() { public Matrix4f getOpenGLMatrix() {
Matrix4f out = new Matrix4f(); final Matrix4f out = new Matrix4f();
Matrix3f tmpMatrix = this.orientation.getMatrix(); final Matrix3f tmpMatrix = this.orientation.getMatrix();
out.mat[0] = tmpMatrix.mat[0]; out.mat[0] = tmpMatrix.mat[0];
out.mat[1] = tmpMatrix.mat[1]; out.mat[1] = tmpMatrix.mat[1];
out.mat[2] = tmpMatrix.mat[2]; out.mat[2] = tmpMatrix.mat[2];
@ -77,10 +88,11 @@ public class Transform3D {
out.mat[15] = 1.0f; out.mat[15] = 1.0f;
return out; return out;
} }
/// Get the OpenGL matrix of the transform /// Get the OpenGL matrix of the transform
public Matrix4f getOpenGLMatrixTransposed() { public Matrix4f getOpenGLMatrixTransposed() {
Matrix4f out = new Matrix4f(); final Matrix4f out = new Matrix4f();
Matrix3f tmpMatrix = this.orientation.getMatrix(); final Matrix3f tmpMatrix = this.orientation.getMatrix();
// version transposer... // version transposer...
out.mat[0] = tmpMatrix.mat[0]; out.mat[0] = tmpMatrix.mat[0];
out.mat[1] = tmpMatrix.mat[3]; out.mat[1] = tmpMatrix.mat[3];
@ -100,65 +112,13 @@ public class Transform3D {
out.mat[15] = 1.0f; out.mat[15] = 1.0f;
return out; return out;
} }
/// Return the inverse of the transform
public Transform3D inverseNew() { public Quaternion getOrientation() {
Quaternion invQuaternion = this.orientation.inverseNew(); return this.orientation;
Matrix3f invMatrix = invQuaternion.getMatrix();
return new Transform3D(invMatrix.multiplyNew(this.position.multiplyNew(-1)), invQuaternion);
} }
/// Return an interpolated transform
public Transform3D interpolateTransforms(Transform3D newOne, float interpolationFactor) { public Vector3f getPosition() {
Vector3f interPosition = this.position.multiplyNew(1.0f - interpolationFactor).add(newOne.position.multiplyNew(interpolationFactor)); return this.position;
Quaternion interOrientation = this.orientation.slerp(newOne.orientation, interpolationFactor);
return new Transform3D(interPosition, interOrientation);
}
/// Return the transformed vector
public Vector3f multiply(Vector3f vector) {
return this.orientation.getMatrix().multiplyNew(vector).add(this.position);
}
/// Return the transformed vector
public Vector3f multiplyNew(Vector3f vector) {
return new Matrix3f(this.orientation.getMatrix()).multiplyNew(vector).add(this.position);
}
/// Operator of multiplication of a transform with another one
/*
public Transform3D multiply(Transform3D transform2) {
this.position = this.orientation.getMatrix().multiply(transform2.position).add(this.position);
this.orientation.multiply(transform2.orientation);
}
*/
/// Operator of multiplication of a transform with another one
public Transform3D multiplyNew(Transform3D transform2) {
return new Transform3D(this.orientation.getMatrix().multiplyNew(transform2.position).add(this.position),
this.orientation.multiplyNew(transform2.orientation));
}
/// Return true if the two transforms are equal
public boolean isEqual(Transform3D transform2) {
return this.position.isEqual(transform2.position) && this.orientation.isEqual(transform2.orientation);
}
/// Return true if the two transforms are different
public boolean isDifferent(Transform3D transform2) {
return this.position.isDifferent(transform2.position) || this.orientation.isDifferent(transform2.orientation);
}
/// Assignment operator
public Transform3D set(Transform3D transform) {
this.position = transform.position.clone();
this.orientation = transform.orientation.clone();
return this;
}
/**
* @brief Clone the current Transform3D.
* @return New Transform3D containing the value
*/
public Transform3D clone() {
return new Transform3D(this);
}
@Override
public String toString() {
return "Transform3D(" + this.position + " & " + this.orientation + ")";
}
public void applyRotation(Quaternion rotation) {
this.orientation = this.orientation.multiply(rotation);
} }
@Override @Override
@ -169,18 +129,82 @@ public class Transform3D {
return hash; return hash;
} }
/// Return an interpolated transform
public Transform3D interpolateTransforms(final Transform3D newOne, final float interpolationFactor) {
final Vector3f interPosition = this.position.multiplyNew(1.0f - interpolationFactor).add(newOne.position.multiplyNew(interpolationFactor));
final Quaternion interOrientation = this.orientation.slerp(newOne.orientation, interpolationFactor);
return new Transform3D(interPosition, interOrientation);
}
/// Return the inverse of the transform
public Transform3D inverseNew() {
final Quaternion invQuaternion = this.orientation.inverseNew();
final Matrix3f invMatrix = invQuaternion.getMatrix();
return new Transform3D(invMatrix.multiplyNew(this.position.multiplyNew(-1)), invQuaternion);
}
/// Return true if the two transforms are different
public boolean isDifferent(final Transform3D transform2) {
return this.position.isDifferent(transform2.position) || this.orientation.isDifferent(transform2.orientation);
}
/// Return true if the two transforms are equal
public boolean isEqual(final Transform3D transform2) {
return this.position.isEqual(transform2.position) && this.orientation.isEqual(transform2.orientation);
}
/// Return the transformed vector
public Vector3f multiply(final Vector3f vector) {
return this.orientation.getMatrix().multiplyNew(vector).add(this.position);
}
/// Operator of multiplication of a transform with another one
/*
public Transform3D multiply(Transform3D transform2) {
this.position = this.orientation.getMatrix().multiply(transform2.position).add(this.position);
this.orientation.multiply(transform2.orientation);
}
*/
/// Operator of multiplication of a transform with another one
public Transform3D multiplyNew(final Transform3D transform2) {
return new Transform3D(this.orientation.getMatrix().multiplyNew(transform2.position).add(this.position), this.orientation.multiplyNew(transform2.orientation));
}
/// Return the transformed vector
public Vector3f multiplyNew(final Vector3f vector) {
return new Matrix3f(this.orientation.getMatrix()).multiplyNew(vector).add(this.position);
}
/// Assignment operator
public Transform3D set(final Transform3D transform) {
this.position = transform.position.clone();
this.orientation = transform.orientation.clone();
return this;
}
/// Set the transform from an OpenGL transform matrix
public void setFromOpenGL(final float[] matrix) {
final Matrix3f tmpMatrix = new Matrix3f(matrix[0], matrix[4], matrix[8], matrix[1], matrix[5], matrix[9], matrix[2], matrix[6], matrix[10]);
this.orientation = new Quaternion(tmpMatrix);
this.position.setValue(matrix[12], matrix[13], matrix[14]);
}
/// Set the Transform3D to the identity transform
public void setIdentity() {
this.position = Vector3f.zero();
this.orientation = Quaternion.identity();
}
public void setOrientation(final Quaternion orientation) {
this.orientation = orientation;
}
public void setPosition(final Vector3f position) {
this.position = position;
}
@Override @Override
public boolean equals(Object obj) { public String toString() {
if (obj == null) { return "Transform3D(" + this.position + " & " + this.orientation + ")";
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Transform3D other = (Transform3D) obj;
if (!this.position.equals(position)) {
return false;
}
return this.orientation.equals(other.orientation);
} }
} }

View File

@ -58,9 +58,9 @@ public class Vector3f {
* @param obj The vector to add to this one * @param obj The vector to add to this one
*/ */
public Vector3f(final Vector3f obj) { public Vector3f(final Vector3f obj) {
this.x += obj.x; this.x = obj.x;
this.y += obj.y; this.y = obj.y;
this.z += obj.z; this.z = obj.z;
} }
/** /**
@ -573,9 +573,7 @@ public class Vector3f {
* @return New vector containing the value * @return New vector containing the value
*/ */
public Vector3f normalizeNew() { public Vector3f normalizeNew() {
final Vector3f out = new Vector3f(this); return clone().normalize();
out.normalize();
return out;
} }
/** /**
@ -639,9 +637,9 @@ public class Vector3f {
* @param obj The vector to add to this one * @param obj The vector to add to this one
*/ */
public Vector3f set(final Vector3f obj) { public Vector3f set(final Vector3f obj) {
this.x += obj.x; this.x = obj.x;
this.y += obj.y; this.y = obj.y;
this.z += obj.z; this.z = obj.z;
return this; return this;
} }