diff --git a/src/bezier/Curve2d.ts b/src/bezier/Curve2d.ts index ee489b8da449ab22086c9dacf925ac259eb745c9..ef03275192468c50ca19c183deccc69083150fa9 100644 --- a/src/bezier/Curve2d.ts +++ b/src/bezier/Curve2d.ts @@ -4,27 +4,10 @@ import { } from "three"; import { Animatable, Updatable, Modifiable } from "../uitls/Interfaces"; import { CubicBezierCurve2d } from "./CubicBezierCurve2d"; -import { UI } from "../uitls/UI"; import { GUI } from "dat.gui"; export class Curve2d implements Animatable, Updatable, Modifiable { - private _curve: CubicBezierCurve2d = new CubicBezierCurve2d( - new Vector2(-1, 0.75), - new Vector2(2, -0.75), - new Vector2(0, 2), - new Vector2(1, -2) - ); - - private _reference: Group = new Group(); - private _bernstain: Group = new Group(); - private _points: Group = new Group(); - private _line: Line = new Line(); - - public t: number = .5; - public resolution: number = 100; - public positionBernstain: Vector2 = new Vector2(-1, -1.5); - constructor() { this._curve.generatePoints(this.resolution); this._line.material = new LineBasicMaterial({ color: 0xffffff }); @@ -32,8 +15,9 @@ export class Curve2d implements Animatable, Updatable, Modifiable { this._bernstain.position.set(this.positionBernstain.x, this.positionBernstain.y, 0); this._points.position.set(this.positionBernstain.x, this.positionBernstain.y, 0); - this.createReference(); this.createLine(); + + this.createReference(); this.createBernstain(); } @@ -41,7 +25,7 @@ export class Curve2d implements Animatable, Updatable, Modifiable { * @returns {Object3D[]} Contains all the object which are used to draw the curve */ objects(): Object3D[] { - return [this._bernstain, this._line, this._reference, this._points]; + return [this._bernstain, this._line, this._reference]; } /** @@ -86,7 +70,7 @@ export class Curve2d implements Animatable, Updatable, Modifiable { // update the bernstain for (let i = 0; i < coefficients.length; i++) { - const bernstain = this._points.getObjectByName(`bernstain_point_${i}`) as Mesh; + const bernstain = this._bernstain.getObjectByName(`bernstain_point_${i}`) as Mesh; bernstain.position.set(delta, coefficients[i], 0); } } @@ -99,11 +83,32 @@ export class Curve2d implements Animatable, Updatable, Modifiable { curve.open(); curve.add(this, 'resolution', 100, 500).step(1).onChange(() => this.update()); curve.add(this, 't', 0, 1).step(0.01).onChange(() => this.animate(this.t)); - UI.addVector<Vector2>(curve, this, this.positionBernstain, 'Bernstain position') - UI.addVector<Vector2>(curve, this, this._curve.startPoint, 'Start Point'); - UI.addVector<Vector2>(curve, this, this._curve.endPoint, 'End Point'); - UI.addVector<Vector2>(curve, this, this._curve.startControlPoint, 'Start Control Point'); - UI.addVector<Vector2>(curve, this, this._curve.endControlPoint, 'End Control Point'); + curve.add(this, '_enableBernstain', false).name("Enable Graph").onChange((b: boolean) => { this._bernstain.visible = b; }); + curve.add(this, '_enableReference', false).name("Enable Ref.").onChange((b: boolean) => { this._reference.visible = b; }); + + + const bernsteinCoordinate = gui.addFolder('Bernstein Coordinate System'); + bernsteinCoordinate.open(); + bernsteinCoordinate.add(this, "_bernsteinScale", 1, 5).step(0.01).name("scale").onChange( + () => { this._bernstain.scale.set(this._bernsteinScale, this._bernsteinScale, this._bernsteinScale) }); + bernsteinCoordinate.add(this.positionBernstain, 'x', -2, 2, .1).onChange(() => this.update()); + bernsteinCoordinate.add(this.positionBernstain, 'y', -2, 2, .1).onChange(() => this.update()); + + const range = 5; + + const start = gui.addFolder('Start'); + start.open(); + start.add(this._curve.startPoint, 'x', -range, range, .1).name("point x").onChange(() => this.update()); + start.add(this._curve.startPoint, 'y', -range, range, .1).name("point y").onChange(() => this.update()); + start.add(this._curve.startControlPoint, 'x', -range, range, .1).name("handle x").onChange(() => this.update()); + start.add(this._curve.startControlPoint, 'y', -range, range, .1).name("handle y").onChange(() => this.update()); + + const end = gui.addFolder('End'); + end.open(); + end.add(this._curve.endPoint, 'x', -range, range, .1).name("point x").onChange(() => this.update()); + end.add(this._curve.endPoint, 'y', -range, range, .1).name("point y").onChange(() => this.update()); + end.add(this._curve.endControlPoint, 'x', -range, range, .1).name("handle x").onChange(() => this.update()); + end.add(this._curve.endControlPoint, 'y', -range, range, .1).name("handle y").onChange(() => this.update()); } private createLine(): void { @@ -140,6 +145,8 @@ export class Curve2d implements Animatable, Updatable, Modifiable { circle.position.set(cpoints[i][j].x, cpoints[i][j].y, 0); circle.name = `point_${i}_${j}_${j + 1}`; this._reference.add(circle); + if (j === cpoints[i].length - 1 && i === cpoints.length - 1) circle.scale.set(3, 3, 3); + } } @@ -207,11 +214,30 @@ export class Curve2d implements Animatable, Updatable, Modifiable { const pointMesh = new Mesh(pointGeometry, pointMaterial); pointMesh.name = `bernstain_point_${i}`; pointMesh.position.set(point.x, point.y, 0); - this._points.add(pointMesh); - + this._bernstain.add(pointMesh); } - } + private _curve: CubicBezierCurve2d = new CubicBezierCurve2d( + new Vector2(-1, 0.75), + new Vector2(2, -0.75), + new Vector2(0, 2), + new Vector2(1, -2) + ); + + + private _reference: Group = new Group(); + private _bernstain: Group = new Group(); + private _points: Group = new Group(); + private _line: Line = new Line(); + private _bernsteinScale: number = 1; + private _enableBernstain: boolean = true; + private _enableReference: boolean = true; + + + public t: number = .5; + public resolution: number = 100; + public positionBernstain: Vector2 = new Vector2(-1, -1.5); + } \ No newline at end of file diff --git a/src/init.ts b/src/init.ts index 52525248e8e83c3d02866dd006187b7c062138c7..8e4444dc0a7b3a812aeca0663968175a9bf445d9 100644 --- a/src/init.ts +++ b/src/init.ts @@ -41,9 +41,6 @@ function init() { simulationLink.addEventListener("click", simulationFunc); - quaternionFunc(); - return; - // start animation RotCube.init(); RotCube.render(); diff --git a/src/quaternion/RotationObject.ts b/src/quaternion/RotationObject.ts index cf2487e5ca3bbc14315a2c2330a491f65c242056..09534f74eb45f5651c685bba6f87e48b6308858b 100644 --- a/src/quaternion/RotationObject.ts +++ b/src/quaternion/RotationObject.ts @@ -19,7 +19,7 @@ export class RotationObject implements Updatable, Modifiable { * Object which should be displayed by the renderer */ objects(): Object3D[] { - return [this._coordinate, this._rotationAxis]; + return [this._coordinate, this._rotationAxisQa, this._rotationAxisQb, this._rotationAxisQworking]; } @@ -88,7 +88,7 @@ export class RotationObject implements Updatable, Modifiable { 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, "enableRotAxisQa").name("enable rot. axis").onChange((b: boolean) => { this._rotationAxisQa.visible = b; }); 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() }); @@ -99,7 +99,7 @@ export class RotationObject implements Updatable, Modifiable { const fqb = folder.addFolder("Quaternion B"); fqb.open(); 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, "enableRotAxisQb").name("enable rot. axis").onChange((b: boolean) => { this._rotationAxisQb.visible = b; }); 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() }); @@ -109,7 +109,7 @@ export class RotationObject implements Updatable, Modifiable { 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, "enableRotAxisQworking").name("enable rot. axis").onChange((b: boolean) => { this._rotationAxisQworking.visible = b; }); 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) }); @@ -160,11 +160,11 @@ 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]; + const group: Group[] = [this._rotationAxisQa, this._rotationAxisQb, this._rotationAxisQworking]; 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; + const line = group[i].getObjectByName("rotationAxisLine" + suffix[i]) as Line; + const point = group[i].getObjectByName("rotationAxisPoint" + suffix[i]) as Mesh; if (line.geometry) line.geometry.dispose(); @@ -179,14 +179,8 @@ export class RotationObject implements Updatable, Modifiable { let factor: number = 3.5; if (suffix[i] === "C") factor = 4; - 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); - } + line.geometry = new BufferGeometry().setFromPoints([origin, dir.normalize().multiplyScalar(factor)]); + point.position.copy(dir); } } @@ -197,6 +191,7 @@ export class RotationObject implements Updatable, Modifiable { createRotationAxis(): void { const suffix: string[] = ["A", "B", "C"]; + const group: Group[] = [this._rotationAxisQa, this._rotationAxisQb, this._rotationAxisQworking]; for (let i = 0; i < suffix.length; i++) { const line = new Line( @@ -204,14 +199,14 @@ export class RotationObject implements Updatable, Modifiable { new LineBasicMaterial({ color: colorsec[i] }) ); line.name = "rotationAxisLine" + suffix[i]; - this._rotationAxis.add(line); + group[i].add(line); const point = new Mesh( new SphereBufferGeometry(.05, 32, 32), new MeshBasicMaterial({ color: colorsec[i] }) ); point.name = "rotationAxisPoint" + suffix[i]; - this._rotationAxis.add(point); + group[i].add(point); } this.updateRotationAxis(); @@ -234,13 +229,15 @@ export class RotationObject implements Updatable, Modifiable { public qb: Quaternion = new Quaternion(); public qworking: Quaternion = new Quaternion(); - public showRotAxisQa: boolean = true; - public showRotAxisQb: boolean = true; - public showRotAxisQworking: boolean = true; + public enableRotAxisQa: boolean = true; + public enableRotAxisQb: boolean = true; + public enableRotAxisQworking: boolean = true; public t: number = 0; private _coordinate: Group = new Group(); - private _rotationAxis: Group = new Group(); + private _rotationAxisQa: Group = new Group(); + private _rotationAxisQb: Group = new Group(); + private _rotationAxisQworking: Group = new Group(); private _mesh?: Mesh; } \ No newline at end of file