Skip to content

Commit

Permalink
Merge pull request #62 from kateter-platform/fix-arc-wrap-around
Browse files Browse the repository at this point in the history
Fix arc wrap around
  • Loading branch information
jonasdeluna authored Oct 21, 2023
2 parents ab73047 + b6f4a3b commit 99db2d7
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 100 deletions.
148 changes: 48 additions & 100 deletions src/Components/Arc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -24,8 +23,6 @@ class Arc extends Component {
_arc: Mesh;
_text: Text;
_curvedOutline: Line2;
_side1Outline: Line;
_side2Outline: Line;

constructor(
pointA: InputPosition,
Expand All @@ -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({
Expand All @@ -59,134 +48,82 @@ 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],
});
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 {
Expand All @@ -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;
4 changes: 4 additions & 0 deletions src/Components/Text.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;

0 comments on commit 99db2d7

Please sign in to comment.