diff --git a/src/Components/Arc.ts b/src/Components/Arc.ts index 0d1c180..3879631 100644 --- a/src/Components/Arc.ts +++ b/src/Components/Arc.ts @@ -7,8 +7,7 @@ import { Vector2, } from "three"; import { Line2, LineMaterial } from "three-fatline"; -import { toVector3 } from "../utils"; -import Line from "./Line"; +import { toVector2, toVector3 } from "../utils"; import Text from "./Text"; import { Component } from "./interfaces"; import { InputPosition } from "./types"; @@ -24,8 +23,6 @@ class Arc extends Component { _arc: Mesh; _text: Text; _curvedOutline: Line2; - _side1Outline: Line; - _side2Outline: Line; constructor( pointA: InputPosition, @@ -43,14 +40,6 @@ class Arc extends Component { this.hasLabel = hasLabel; this.color = color; - this._side1Outline = new Line([0, 0], [0, 0], { - lineWidth: 4, - color: 0x080007, - }); - this._side2Outline = new Line([0, 0], [0, 0], { - lineWidth: 4, - color: 0x080007, - }); this._curvedOutline = new Line2( undefined, new LineMaterial({ @@ -59,15 +48,16 @@ class Arc extends Component { resolution: new Vector2(window.innerWidth, window.innerHeight), }) ); - this.add(this._side1Outline); - this.add(this._side2Outline); this.add(this._curvedOutline); - this._arc = new Mesh(undefined, new MeshBasicMaterial({ color: color })); + this._arc = new Mesh( + undefined, + new MeshBasicMaterial({ color: this.color }) + ); this.add(this._arc); this._text = new Text("0", { - fontSize: hasLabel ? 20 : 0, + fontSize: this.hasLabel ? 20 : 0, anchorY: "middle", anchorX: "left", position: [0, 0], @@ -75,118 +65,65 @@ class Arc extends Component { this.add(this._text); const angle = this._calcAngle(); - this._updateOutline(angle); - this._updateArc(angle); + this._updateOutline(angle, 1); + this._updateArc(angle, 1); + this._updateText(angle, 1); } - update(camera: OrthographicCamera) { - const pointBVec = toVector3(this.pointB); - this.position.set(pointBVec.x, pointBVec.y, 0); + _calcAngle() { + const pointAvec2 = toVector2(this.pointA); + const pointBvec2 = toVector2(this.pointB); + const pointCvec2 = toVector2(this.pointC); - const angle = this._calcAngle(); - this._updateOutline(angle, camera.zoom); - this._updateArc(angle, camera.zoom); - this._updateText(angle, camera.zoom); - } + const vectorBtoA = pointAvec2.clone().sub(pointBvec2); + const vectorBtoC = pointCvec2.clone().sub(pointBvec2); - _calcAngle() { - const pointAvec3 = toVector3(this.pointA); - const pointBvec3 = toVector3(this.pointB); - const pointCvec3 = toVector3(this.pointC); - const vectorBtoA = pointAvec3.clone().sub(pointBvec3.clone()); - const vectorBtoC = pointCvec3.clone().sub(pointBvec3.clone()); - return vectorBtoA.angleTo(vectorBtoC); + const dot = vectorBtoA.dot(vectorBtoC); + const det = vectorBtoA.x * vectorBtoC.y - vectorBtoA.y * vectorBtoC.x; + let angle = Math.atan2(det, dot); + + // Normalize the angle to be between 0 and 2π + while (angle < 0) angle += 2 * Math.PI; + while (angle > 2 * Math.PI) angle -= 2 * Math.PI; + + return angle; } - _updateOutline(angle: number, cameraZoom = 1) { - const pointAvec3 = toVector3(this.pointA); - const pointBvec3 = toVector3(this.pointB); - const pointCvec3 = toVector3(this.pointC); - const vectorBtoA = pointAvec3.clone().sub(pointBvec3.clone()); - const vectorBtoC = pointCvec3.clone().sub(pointBvec3.clone()); - - //finner hvilken vinkel som er riktig - const angle1 = - (Math.atan2(vectorBtoA.y, vectorBtoA.x) + Math.PI * 2) % (Math.PI * 2); - const angle2 = - (Math.atan2(vectorBtoC.y, vectorBtoC.x) + Math.PI * 2) % (Math.PI * 2); - - let startAngle = angle2; // Starting angle of the arc in radians - - if ( - (angle1 - angle2 + Math.PI * 2) % (2 * Math.PI) > - (angle2 - angle1 + Math.PI * 2) % (2 * Math.PI) - ) { - startAngle = angle1; - } - const endAngle = startAngle + angle; // Ending angle of the arc in radians - const clockwise = false; // Whether the arc is drawn in a clockwise direction + _updateOutline(angle: number, cameraZoom: number) { + const startAngle = 0; + const endAngle = angle; + const clockwise = false; - //Create Arc-curve + // Create Arc-curve const arcCurve = new ArcCurve( 0, 0, - this.radius / cameraZoom, + (this.radius / cameraZoom) * 10, startAngle, endAngle, clockwise ); - //generate points on ArcCurve + // Generate points on ArcCurve const points = arcCurve.getPoints(50); this._curvedOutline.geometry.setPositions( points.flatMap((v) => [v.x, v.y, 3]) ); - - //punktene arcen krysser linjene - const krysningAB = vectorBtoA - .clone() - .normalize() - .multiplyScalar(this.radius / cameraZoom); - const krysningCB = vectorBtoC - .clone() - .normalize() - .multiplyScalar(this.radius / cameraZoom); - - this._side1Outline.start = new Vector2(krysningAB.x, krysningAB.y); - this._side2Outline.start = new Vector2(krysningCB.x, krysningCB.y); } - _updateArc(angle: number, cameraZoom = 1) { - const pointAvec3 = toVector3(this.pointA); - const pointBvec3 = toVector3(this.pointB); - const pointCvec3 = toVector3(this.pointC); - const vectorBtoA = pointAvec3.clone().sub(pointBvec3.clone()); - const vectorBtoC = pointCvec3.clone().sub(pointBvec3.clone()); - - //finner hvilken vinkel som er riktig - const angle1 = - (Math.atan2(vectorBtoA.y, vectorBtoA.x) + Math.PI * 2) % (Math.PI * 2); - const angle2 = - (Math.atan2(vectorBtoC.y, vectorBtoC.x) + Math.PI * 2) % (Math.PI * 2); - - let startAngle = angle2; // Starting angle of the arc in radians - - if ( - (angle1 - angle2 + Math.PI * 2) % (2 * Math.PI) > - (angle2 - angle1 + Math.PI * 2) % (2 * Math.PI) - ) { - startAngle = angle1; - } - - // Create circle-geometry -- lager fyllet i vinkelen + _updateArc(angle: number, cameraZoom: number) { this._arc.geometry.dispose(); this._arc.geometry = new CircleGeometry( - this.radius / cameraZoom, - 32, - startAngle, + (this.radius / cameraZoom) * 10, + 64, + 0, angle ); this._arc.geometry.computeVertexNormals(); } _updateText(angle: number, cameraZoom: number) { - this._text.setText(Math.round((angle * 180) / Math.PI).toString() + " °"); - this._text.position.set(-60 / cameraZoom, 0, this._text.position.z); + this._text.setText(Math.round((angle * 180) / Math.PI).toString() + "°"); + this._text.position.set((-60 / cameraZoom) * 2, 0, this._text.position.z); } public getAngle(unit = "radians"): number { @@ -195,5 +132,16 @@ class Arc extends Component { } return this._calcAngle(); } + + update(camera: OrthographicCamera) { + const pointBVec = toVector3(this.pointB); + this.position.set(pointBVec.x, pointBVec.y, 0); + + const angle = this._calcAngle(); + this._updateOutline(angle, camera.zoom); + this._updateArc(angle, camera.zoom); + this._updateText(angle, camera.zoom); + } } + export default Arc; diff --git a/src/Components/Text.ts b/src/Components/Text.ts index ead243b..2009146 100644 --- a/src/Components/Text.ts +++ b/src/Components/Text.ts @@ -115,6 +115,10 @@ class Text extends Component implements Collider { this.scale.set(1 / camera.zoom, 1 / camera.zoom, 1); } } + + public setZIndex(z: number): void { + this.position.setZ(z); + } } export default Text;