在 Three.js 中旋转椭圆曲线
Rotating Ellipse Curve in Three.js
目标
我正在尝试创建相机应在其上移动的 EllipseCurve (https://threejs.org/docs/#api/en/extras/curves/EllipseCurve)。
我做了什么来实现目标?
这是目前椭圆的代码。
var curve = new THREE.EllipseCurve(
0,0,
1, 1,
0, 2 * Math.PI,
false,
1.57
)
const points = curve.getPoints( 50 );
const geometry = new THREE.BufferGeometry().setFromPoints( points );
var material = new THREE.LineBasicMaterial( { color : 0xffffff } );
// Create the final object to add to the scene
var curveObject = new THREE.Line( geometry, material );
scene.add(curveObject);
我在现场看到是这样的:
问题
我尝试将椭圆曲线绕 x 轴顺时针旋转 90 度。正如我从文档中了解到的那样,定义函数的最后一个参数应该旋转它。
const curve = new THREE.EllipseCurve(
0, 0, // ax, aY
10, 10, // xRadius, yRadius
0, 2 * Math.PI, // aStartAngle, aEndAngle
false, // aClockwise
0 // aRotation
);
预先感谢您的回答。我是 Three.js 的新手,如果这个问题可能很愚蠢,我很抱歉 :D
获取曲线上的一个点并对其应用 matrix4。
这是一个关于如何做到这一点的概念(参见动画循环中带有 cam
的行,最好用“整页”观看):
body{
overflow: hidden;
margin: 0;
}
<script type="module">
import * as THREE from "https://cdn.skypack.dev/three@0.134.0";
import {
OrbitControls
} from "https://cdn.skypack.dev/three@0.134.0/examples/jsm/controls/OrbitControls.js";
let scene = new THREE.Scene();
let camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 1, 1000);
camera.position.set(-10, 10, 10);
let renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(innerWidth, innerHeight);
renderer.autoClear = false;
document.body.appendChild(renderer.domElement);
window.addEventListener("resize", () => {
camera.aspect = innerWidth / innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(innerWidth, innerHeight);
})
let controls = new OrbitControls(camera, renderer.domElement);
let light = new THREE.DirectionalLight(0xffffff, 1);
light.position.setScalar(1);
scene.add(light, new THREE.AmbientLight(0xffffff, 0.5));
let grid = new THREE.GridHelper();
grid.position.y = -5;
scene.add(grid);
let obj = new THREE.Mesh(new THREE.IcosahedronGeometry(1, 0), new THREE.MeshLambertMaterial({
color: "aqua"
}));
scene.add(obj);
let curve = new THREE.EllipseCurve(0, 0, 10, 5);
let line = new THREE.Line(new THREE.BufferGeometry().setFromPoints(curve.getSpacedPoints(100)), new THREE.LineBasicMaterial({
color: "yellow"
}));
line.rotation.x = -Math.PI * 0.25;
line.rotation.z = Math.PI * 0.125;
line.position.x = 5;
scene.add(line);
let cam = new THREE.PerspectiveCamera(25, 1, 1.5, 25);
let camHelper = new THREE.CameraHelper(cam);
scene.add(camHelper);
let clock = new THREE.Clock();
let v = new THREE.Vector3();
renderer.setAnimationLoop(() => {
let t = (clock.getElapsedTime() * 0.05) % 1;
// magic is in these lines //////////////////
cam.position.copy(curve.getPointAt(t, v));
cam.position.applyMatrix4(line.matrixWorld);
cam.lookAt(obj.position);
/////////////////////////////////////////////
renderer.clear();
renderer.setViewport(0, 0, innerWidth, innerHeight);
renderer.render(scene, camera);
renderer.setViewport(0, innerHeight - 256, 256, 256);
renderer.render(scene, cam);
})
</script>
aRotation,angle-rotation,会影响这条曲线其他角度设置的局部原点。不是整体椭圆旋转,而是任意偏移相对于默认的方向。不同的起点。它会将吃豆人的嘴巴变成 +/- 180 度的向后吃豆人嘴巴。要在 world-space 中旋转整体曲线,请使用可用的各种方法之一,例如 curve.rotation.set(0,1,0) 或 rotation.y += 1。请参阅文档对于特定的旋转变体。
目标
我正在尝试创建相机应在其上移动的 EllipseCurve (https://threejs.org/docs/#api/en/extras/curves/EllipseCurve)。
我做了什么来实现目标?
这是目前椭圆的代码。
var curve = new THREE.EllipseCurve(
0,0,
1, 1,
0, 2 * Math.PI,
false,
1.57
)
const points = curve.getPoints( 50 );
const geometry = new THREE.BufferGeometry().setFromPoints( points );
var material = new THREE.LineBasicMaterial( { color : 0xffffff } );
// Create the final object to add to the scene
var curveObject = new THREE.Line( geometry, material );
scene.add(curveObject);
我在现场看到是这样的:
问题
我尝试将椭圆曲线绕 x 轴顺时针旋转 90 度。正如我从文档中了解到的那样,定义函数的最后一个参数应该旋转它。
const curve = new THREE.EllipseCurve(
0, 0, // ax, aY
10, 10, // xRadius, yRadius
0, 2 * Math.PI, // aStartAngle, aEndAngle
false, // aClockwise
0 // aRotation
);
预先感谢您的回答。我是 Three.js 的新手,如果这个问题可能很愚蠢,我很抱歉 :D
获取曲线上的一个点并对其应用 matrix4。
这是一个关于如何做到这一点的概念(参见动画循环中带有 cam
的行,最好用“整页”观看):
body{
overflow: hidden;
margin: 0;
}
<script type="module">
import * as THREE from "https://cdn.skypack.dev/three@0.134.0";
import {
OrbitControls
} from "https://cdn.skypack.dev/three@0.134.0/examples/jsm/controls/OrbitControls.js";
let scene = new THREE.Scene();
let camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 1, 1000);
camera.position.set(-10, 10, 10);
let renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(innerWidth, innerHeight);
renderer.autoClear = false;
document.body.appendChild(renderer.domElement);
window.addEventListener("resize", () => {
camera.aspect = innerWidth / innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(innerWidth, innerHeight);
})
let controls = new OrbitControls(camera, renderer.domElement);
let light = new THREE.DirectionalLight(0xffffff, 1);
light.position.setScalar(1);
scene.add(light, new THREE.AmbientLight(0xffffff, 0.5));
let grid = new THREE.GridHelper();
grid.position.y = -5;
scene.add(grid);
let obj = new THREE.Mesh(new THREE.IcosahedronGeometry(1, 0), new THREE.MeshLambertMaterial({
color: "aqua"
}));
scene.add(obj);
let curve = new THREE.EllipseCurve(0, 0, 10, 5);
let line = new THREE.Line(new THREE.BufferGeometry().setFromPoints(curve.getSpacedPoints(100)), new THREE.LineBasicMaterial({
color: "yellow"
}));
line.rotation.x = -Math.PI * 0.25;
line.rotation.z = Math.PI * 0.125;
line.position.x = 5;
scene.add(line);
let cam = new THREE.PerspectiveCamera(25, 1, 1.5, 25);
let camHelper = new THREE.CameraHelper(cam);
scene.add(camHelper);
let clock = new THREE.Clock();
let v = new THREE.Vector3();
renderer.setAnimationLoop(() => {
let t = (clock.getElapsedTime() * 0.05) % 1;
// magic is in these lines //////////////////
cam.position.copy(curve.getPointAt(t, v));
cam.position.applyMatrix4(line.matrixWorld);
cam.lookAt(obj.position);
/////////////////////////////////////////////
renderer.clear();
renderer.setViewport(0, 0, innerWidth, innerHeight);
renderer.render(scene, camera);
renderer.setViewport(0, innerHeight - 256, 256, 256);
renderer.render(scene, cam);
})
</script>
aRotation,angle-rotation,会影响这条曲线其他角度设置的局部原点。不是整体椭圆旋转,而是任意偏移相对于默认的方向。不同的起点。它会将吃豆人的嘴巴变成 +/- 180 度的向后吃豆人嘴巴。要在 world-space 中旋转整体曲线,请使用可用的各种方法之一,例如 curve.rotation.set(0,1,0) 或 rotation.y += 1。请参阅文档对于特定的旋转变体。