Summary: The objective is to adjust the arrow's orientation around the circle.
We have a function that introduces a shape (https://i.sstatic.net/l3lZB.jpg) (comprising of three Meshes) into the scene. By default, it points to the right, but we desire to rotate it (90°, Pi/2 upwards, 180°, Pi to the right, and so forth). The central point (the two circles) should stay fixed while the triangle rotates around it.
We attempted the Euler rotation method and setting the axis to the central point. Most of the time, when we rotate the node, the position changes, but the x-y coordinates remain unchanged in the group object.
Does anyone have a solution on how we can rotate the node around the center accurately? Below is the code snippet used to add the node to the scene.
let scene;
let renderer;
let camera;
setup();
//params: xcoord, ycoord, rotation (in degrees)
drawNode(1, 1, 0);
renderer.render(scene, camera);
function setup() {
scene = new THREE.Scene();
renderer = new THREE.WebGLRenderer({
alpha: true, //Transparent
antialias: true //For smoother edges
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
//we use orthographic camera so perspective doesn't manipulate how we see the objects
//example: https://i.sstatic.net/q1SNB.png
camera = new THREE.OrthographicCamera(
window.innerWidth / -100, //Camera frustum left plane.
window.innerWidth / 100, // Camera frustum right plane.
window.innerHeight / 100, //Camera frustum top plane.
window.innerHeight / -100, //Camera frustum bottom plane
-1, //near — Camera frustum near plane.
100 //far — Camera frustum far plane.
//frustum:https://en.wikipedia.org/wiki/Viewing_frustum
);
//Creates background grid
const gridHelper = new THREE.GridHelper(50, 50);
gridHelper.rotateX(-Math.PI / 2); //Rotation is necessary because we changed the axis so Z is aimed towards the screen
scene.add(gridHelper);
}
function drawNode(xcoord, ycoord, rotation) {
//Small white circle
const innerCircleGeometry = new THREE.CircleGeometry(1 / 32, 32);
const innerCircle = new THREE.Mesh(innerCircleGeometry, new THREE.MeshBasicMaterial({
color: 0xFFFFFF
}));
innerCircle.position.set(xcoord, ycoord, 0);
//Bigger grey circle
const outerCircleGeometry = new THREE.CircleGeometry(1 / 16, 32);
const outerCircle = new THREE.Mesh(outerCircleGeometry, new THREE.MeshBasicMaterial({
color: 0xC4C4C4
}));
outerCircle.position.set(xcoord, ycoord, 0);
//Points of the triangle
const points = [];
points.push(new THREE.Vector3(xcoord, ycoord - 1 / 4, 0));
points.push(new THREE.Vector3(xcoord, ycoord + 1 / 4, 0));
points.push(new THREE.Vector3(xcoord + 1 / 4, ycoord, 0));
points.push(new THREE.Vector3(xcoord, ycoord - 1 / 4, 0));
const geometrytriangle = new THREE.BufferGeometry().setFromPoints(points); //connects the points
const triangle = new THREE.Mesh(geometrytriangle, new THREE.MeshBasicMaterial({
side: THREE.DoubleSide,
color: 0x5C5C5C
}));
//Set order so triangle is always at the bottom
triangle.renderOrder = 0;
outerCircle.renderOrder = 1;
innerCircle.renderOrder = 2;
const nodeGroup = new THREE.Group();
nodeGroup.add(triangle);
nodeGroup.add(outerCircle);
nodeGroup.add(innerCircle);
//TODO: rotate the node
//Incorrect rotation: nodeGroup.rotateZ(THREE.MathUtils.degToRad(rotation));
scene.add(nodeGroup);
//Unique identifier of nodegroup, each child has its own uuid
return nodeGroup.uuid;
}
body { min-height: 100vh; }
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script src="https://github.com/mrdoob/three.js/blob/master/examples/jsm/controls/OrbitControls.js"></script>
<title>Document</title>
</head>
<body>
</body>
</html>