From ffa9d4aa84b0a1ab2001d946bbb242dad4491a4b Mon Sep 17 00:00:00 2001
From: Jamie Temple <jamie-temple@live.de>
Date: Fri, 13 May 2022 01:16:12 +0200
Subject: [PATCH] enhance: better options for quat

---
 index.html                       |  4 --
 src/init.ts                      | 22 +++++++---
 src/quaternion/Quaternion.ts     |  2 +-
 src/quaternion/RotationObject.ts | 75 ++++++++++++++++++++------------
 src/style.css                    |  2 +-
 5 files changed, 65 insertions(+), 40 deletions(-)

diff --git a/index.html b/index.html
index 1aaf5d7..7a06ea9 100644
--- a/index.html
+++ b/index.html
@@ -11,10 +11,6 @@
 
   <link rel="stylesheet" href="src/style.css" />
   <link rel="icon" type="image/svg+xml" href="favicon.svg" />
-
-  <link rel="preconnect" href="https://fonts.googleapis.com">
-  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
-  <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@500&display=swap" rel="stylesheet">
 </head>
 
 <body>
diff --git a/src/init.ts b/src/init.ts
index 547bad5..5252524 100644
--- a/src/init.ts
+++ b/src/init.ts
@@ -16,23 +16,33 @@ function init() {
     const simulationLink = document.querySelector("#simulation") as HTMLAnchorElement;
 
     // actions to be performed when the link is clicked
-    bezierLink.addEventListener("click", () => {
+    
+    const bezierFunc = () => {
         sceneElement.classList.remove("hidden");
         mainElement.classList.add("hidden");
         Main.demos(Main.examples["bezier"]);
-    });
+    };
 
-    quaternionLink.addEventListener("click", () => {
+    const quaternionFunc = () => {
         sceneElement.classList.remove("hidden");
         mainElement.classList.add("hidden");
         Main.demos(Main.examples["quaternion"]);
-    });
+    };
 
-    simulationLink.addEventListener("click", () => {
+    const simulationFunc = () => {
         sceneElement.classList.add("hidden");
         mainElement.classList.remove("hidden");
         // TODO: add simulation
-    });
+    };
+
+    bezierLink.addEventListener("click", bezierFunc);
+
+    quaternionLink.addEventListener("click", quaternionFunc);
+
+    simulationLink.addEventListener("click", simulationFunc);
+
+    quaternionFunc();
+    return;
 
     // start animation
     RotCube.init();
diff --git a/src/quaternion/Quaternion.ts b/src/quaternion/Quaternion.ts
index 9e151c8..9a8fe24 100644
--- a/src/quaternion/Quaternion.ts
+++ b/src/quaternion/Quaternion.ts
@@ -51,7 +51,7 @@ export class Quaternion {
         this._w = w;
 
         const length = Math.sqrt(x * x + y * y + z * z + w * w);
-        if (this._keepUnitQuaternion && length !== 0) {
+        if (this._keepUnitQuaternion && length > 0) {
             this._x = x / length;
             this._y = y / length;
             this._z = z / length;
diff --git a/src/quaternion/RotationObject.ts b/src/quaternion/RotationObject.ts
index 4baf82b..cf2487e 100644
--- a/src/quaternion/RotationObject.ts
+++ b/src/quaternion/RotationObject.ts
@@ -27,11 +27,13 @@ export class RotationObject implements Updatable, Modifiable {
      * Updates the qworking quaternion which is applied to the mesh
      * qa and qb are used to calculate the quaternion and left in their original state
      */
-    update(): void {
+    update(throughWorking: boolean = false): void {
 
-        if (this.SLERP) this.qworking = Quaternion.slerp(this.qa, this.qb, this.t);
-        else if (this.MODE === "Single") this.qworking = this.qa.clone();
-        else this.qworking = Quaternion.multiply(this.qa, this.qb);
+        if (!throughWorking) {
+            if (this.SLERP) this.qworking = Quaternion.slerp(this.qa, this.qb, this.t);
+            else if (this.MODE === "Single") this.qworking = this.qa.clone();
+            else this.qworking = Quaternion.multiply(this.qa, this.qb);
+        }
 
         if (this._mesh) {
             this._mesh.setRotationFromMatrix(this.qworking.toMatrix());
@@ -72,6 +74,7 @@ export class RotationObject implements Updatable, Modifiable {
         else {
             folder.add(this, "MODE", ["Single", "Multi"]).onFinishChange(() => {
                 this.createElement(gui);
+                this.update()
             });
         }
 
@@ -82,31 +85,35 @@ export class RotationObject implements Updatable, Modifiable {
         const range: number = 1;
         const step: number = .01;
 
-        const func = (): void => { this.update(); }
-
-        if (this.MODE === "Single" || this.MODE === "Multi") {
-
-            const fqa = folder.addFolder(this.MODE === "Single" ? "Quaternion" : "Quaternion A");
-            fqa.open();
-            fqa.add(this.qa, "keepUnitQuaternion").onChange(func);
-            fqa.add(this.qa, "x", -range, range, step).onChange(func);
-            fqa.add(this.qa, "y", -range, range, step).onChange(func);
-            fqa.add(this.qa, "z", -range, range, step).onChange(func);
-            fqa.add(this.qa, "w", -range, range, step).onChange(func);
-
-        }
+        const fqa = folder.addFolder(this.MODE === "Single" ? "Quaternion" : "Quaternion A");
+        fqa.open();
+        fqa.add(this.qa, "keepUnitQuaternion").name("auto. value").onChange(() => { this.update() });
+        fqa.add(this, "showRotAxisQa").name("show rot. axis").onChange(() => { this.update() });
+        fqa.add(this.qa, "x", -range, range, step).listen().onChange(() => { this.update() });
+        fqa.add(this.qa, "y", -range, range, step).listen().onChange(() => { this.update() });
+        fqa.add(this.qa, "z", -range, range, step).listen().onChange(() => { this.update() });
+        fqa.add(this.qa, "w", -range, range, step).listen().onChange(() => { this.update() });
 
         if (this.MODE === "Multi") {
 
             const fqb = folder.addFolder("Quaternion B");
             fqb.open();
-            fqb.add(this.qb, "keepUnitQuaternion").onChange(func);
-            fqb.add(this.qb, "x", -range, range, step).onChange(func);
-            fqb.add(this.qb, "y", -range, range, step).onChange(func);
-            fqb.add(this.qb, "z", -range, range, step).onChange(func);
-            fqb.add(this.qb, "w", -range, range, step).onChange(func);
+            fqb.add(this.qb, "keepUnitQuaternion").name("auto. value").onChange(() => { this.update() });
+            fqb.add(this, "showRotAxisQb").name("show rot. axis").onChange(() => { this.update() });
+            fqb.add(this.qb, "x", -range, range, step).listen().onChange(() => { this.update() });
+            fqb.add(this.qb, "y", -range, range, step).listen().onChange(() => { this.update() });
+            fqb.add(this.qb, "z", -range, range, step).listen().onChange(() => { this.update() });
+            fqb.add(this.qb, "w", -range, range, step).listen().onChange(() => { this.update() });
 
         }
+
+        const fqw = folder.addFolder("Working Quaternion");
+        fqw.add(this.qworking, "keepUnitQuaternion").name("auto. value").onChange(() => { this.update() });
+        fqw.add(this, "showRotAxisQworking").name("show rot. axis").onChange(() => { this.update() });
+        fqw.add(this.qworking, "x", -range, range, step).listen().onChange((v: number) => { this.qworking.x = v; this.update(true) });
+        fqw.add(this.qworking, "y", -range, range, step).listen().onChange((v: number) => { this.qworking.y = v; this.update(true) });
+        fqw.add(this.qworking, "z", -range, range, step).listen().onChange((v: number) => { this.qworking.z = v; this.update(true) });
+        fqw.add(this.qworking, "w", -range, range, step).listen().onChange((v: number) => { this.qworking.w = v; this.update(true) });
     }
 
 
@@ -153,8 +160,9 @@ export class RotationObject implements Updatable, Modifiable {
 
         const suffix: string[] = ["A", "B", "C"];
         const ref: Quaternion[] = [this.qa, this.qb, this.qworking];
+        const show: boolean[] = [this.showRotAxisQa, this.showRotAxisQb, this.showRotAxisQworking];
 
-        for (let i = 0; i < ref.length; i++) {
+        for (let i = 0; i < ref.length - (this.MODE === "Single" ? 1 : 0); i++) {
             const line = this._rotationAxis.getObjectByName("rotationAxisLine" + suffix[i]) as Line;
             const point = this._rotationAxis.getObjectByName("rotationAxisPoint" + suffix[i]) as Mesh;
 
@@ -171,8 +179,14 @@ export class RotationObject implements Updatable, Modifiable {
             let factor: number = 3.5;
             if (suffix[i] === "C") factor = 4;
 
-            line.geometry = new BufferGeometry().setFromPoints([origin, dir.normalize().multiplyScalar(factor)]);
-            point.position.copy(dir);
+            if (show[i]) {
+                line.geometry = new BufferGeometry().setFromPoints([origin, dir.normalize().multiplyScalar(factor)]);
+                point.position.copy(dir);
+            }
+            else {
+                line.geometry = new BufferGeometry();
+                point.position.copy(origin);
+            }
         }
     }
 
@@ -216,9 +230,14 @@ export class RotationObject implements Updatable, Modifiable {
     public SLERP: boolean = false;
     public MODE: string = "Single";
 
-    public qa: Quaternion = new Quaternion();;
-    public qb: Quaternion = new Quaternion();;
-    public qworking: Quaternion = new Quaternion();;
+    public qa: Quaternion = new Quaternion();
+    public qb: Quaternion = new Quaternion();
+    public qworking: Quaternion = new Quaternion();
+
+    public showRotAxisQa: boolean = true;
+    public showRotAxisQb: boolean = true;
+    public showRotAxisQworking: boolean = true;
+
     public t: number = 0;
 
     private _coordinate: Group = new Group();
diff --git a/src/style.css b/src/style.css
index 910f237..d7c22f4 100644
--- a/src/style.css
+++ b/src/style.css
@@ -2,7 +2,7 @@
   margin: 0;
   padding: 0;
   box-sizing: border-box;
-  font-family: 'Poppins', sans-serif;
+  font-family: 'Arial', sans-serif;
 }
 
 canvas {
-- 
GitLab