如何围绕组内的一个点旋转 Three.js 组?
Posted
技术标签:
【中文标题】如何围绕组内的一个点旋转 Three.js 组?【英文标题】:How can I rotate a Three.js group around a point inside the group? 【发布时间】:2021-09-24 03:23:41 【问题描述】:tl;dr:目标是改变围绕圆圈的箭头方向。
我们有一种方法可以将形状 (https://imgur.com/a/F6M43kF)(由三个网格组成)添加到场景中。 默认绘制指向右侧,但我们希望给它一个旋转(90°,Pi/2 指向上,180°,Pi 指向右侧等)。中心点(两个圆)应始终在同一位置,只有三角形应围绕中心点旋转。
我们尝试使用欧拉旋转并将轴设置到中心点。 大多数时候,旋转节点会改变位置,但组对象中的 x-y 坐标不会改变。
那么有人可以解决我们如何围绕中心旋转节点吗? 下面我添加了我们用来将节点添加到场景中的代码。
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, //Tranpart
antialias: true //For smoother edges
);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
//we use ortographic camera so perspective doesn't manipulate how we see the objects
//example: https://i.stack.imgur.com/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); //Rotate is necessary because we changed the axis so Z is aimed to 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 on 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
//Rotate that goes wrong: nodeGroup.rotateZ(THREE.MathUtils.degToRad(rotation));
scene.add(nodeGroup);
//Unique identifer of nodegroup, each child has 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>
【问题讨论】:
改变组的轴心点 @Rodener Dajes 你能详细说明一下吗?当然,他们已经尝试过了,但没有成功。 ***.com/questions/37779104/… 这能回答你的问题吗? How can I rotate around the center of a group in Three.js 【参考方案1】:这里的诀窍是所有的旋转大约是 0,0,0。为了旋转箭头,您需要将要旋转的点放在原点的中心,旋转它,然后平移它。
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(0, 0, 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(0, 0, 0);
//Points of the triangle
const points = [];
points.push(new THREE.Vector3(0, 0 - 1 / 4, 0));
points.push(new THREE.Vector3(0, 0 + 1 / 4, 0));
points.push(new THREE.Vector3(0 + 1 / 4, 0, 0));
points.push(new THREE.Vector3(0, 0 - 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 on 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);
nodeGroup.rotateZ(rotation*3.14/180);
nodeGroup.position.set(xcoord, ycoord, 0)
scene.add(nodeGroup);
//Unique identifer of nodegroup, each child has own uuid.
return nodeGroup.uuid;
您可以查看我的工作示例here
【讨论】:
以上是关于如何围绕组内的一个点旋转 Three.js 组?的主要内容,如果未能解决你的问题,请参考以下文章