在 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。请参阅文档对于特定的旋转变体。