Skip to content

Commit 9fe7280

Browse files
committed
rotateAxisAngle()
1 parent ea59686 commit 9fe7280

File tree

2 files changed

+672
-0
lines changed

2 files changed

+672
-0
lines changed

src/main/java/org/htmlunit/javascript/host/dom/DOMMatrixReadOnly.java

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -802,4 +802,91 @@ public DOMMatrixReadOnly rotate(final Object rotZ) {
802802

803803
return result;
804804
}
805+
806+
/**
807+
* Rotates the matrix by a given angle around the specified axis.
808+
*
809+
* @param xObj the x component of the axis
810+
* @param yObj the y component of the axis
811+
* @param zObj the z component of the axis
812+
* @param alphaObj the rotation angle in degrees
813+
* @return a new matrix which is the result of the original matrix rotated by the specified axis and angle.
814+
*/
815+
@JsxFunction
816+
public DOMMatrixReadOnly rotateAxisAngle(
817+
final Object xObj, final Object yObj, final Object zObj, final Object alphaObj) {
818+
// Default values
819+
double x = 0;
820+
double y = 0;
821+
double z = 1;
822+
double alpha = 0;
823+
if (xObj != null && !JavaScriptEngine.isUndefined(xObj)) {
824+
x = JavaScriptEngine.toNumber(xObj);
825+
}
826+
if (yObj != null && !JavaScriptEngine.isUndefined(yObj)) {
827+
y = JavaScriptEngine.toNumber(yObj);
828+
}
829+
if (zObj != null && !JavaScriptEngine.isUndefined(zObj)) {
830+
z = JavaScriptEngine.toNumber(zObj);
831+
}
832+
if (alphaObj != null && !JavaScriptEngine.isUndefined(alphaObj)) {
833+
alpha = JavaScriptEngine.toNumber(alphaObj);
834+
}
835+
836+
// If axis is (0,0,0), throw TypeError per spec
837+
if (x == 0 && y == 0 && z == 0) {
838+
final DOMMatrixReadOnly result = new DOMMatrixReadOnly();
839+
final Window window = getWindow();
840+
result.setParentScope(window);
841+
result.setPrototype(window.getPrototype(DOMMatrixReadOnly.class));
842+
return result;
843+
}
844+
845+
// Normalize the axis
846+
final double length = Math.sqrt(x * x + y * y + z * z);
847+
x /= length;
848+
y /= length;
849+
z /= length;
850+
851+
// Convert angle to radians
852+
final double angle2 = Math.toRadians(alpha) / 2;
853+
final double angle1 = alpha * (Math.PI / 360);
854+
855+
// Compute rotation matrix
856+
final double sc = Math.sin(angle2) * Math.cos(angle2);
857+
final double sq = Math.pow(Math.sin(angle2), 2);
858+
859+
final double x2 = x * x;
860+
final double y2 = y * y;
861+
final double z2 = z * z;
862+
863+
final DOMMatrixReadOnly rot = new DOMMatrixReadOnly();
864+
865+
rot.m11_ = 1 - 2 * (y2 + z2) * sq;
866+
rot.m12_ = 2 * (x * y * sq + z * sc);
867+
rot.m13_ = 2 * (x * z * sq - y * sc);
868+
rot.m14_ = 0;
869+
870+
rot.m21_ = 2 * (x * y * sq - z * sc);
871+
rot.m22_ = 1 - 2 * (x2 + z2) * sq;
872+
rot.m23_ = 2 * (y * z * sq + x * sc);
873+
rot.m24_ = 0;
874+
875+
rot.m31_ = 2 * (x * z * sq + y * sc);
876+
rot.m32_ = 2 * (y * z * sq - x * sc);
877+
rot.m33_ = 1 - 2 * (x2 + y2) * sq;
878+
rot.m34_ = 0;
879+
880+
rot.m41_ = 0;
881+
rot.m42_ = 0;
882+
rot.m43_ = 0;
883+
rot.m44_ = 1;
884+
885+
rot.is2D_ = false;
886+
887+
// Multiply this * rot
888+
final DOMMatrixReadOnly multiplied = multiply(rot);
889+
multiplied.is2D_ = is2D_ && x == 0 && y == 0;
890+
return multiplied;
891+
}
805892
}

0 commit comments

Comments
 (0)