在Three.js

时间:2016-11-16 10:53:38

标签: javascript animation three.js

我想使用Three.js在屏幕上绘制线条的动画。在这种情况下,我想要绘制的线是Lorenz吸引子,使用this YouTube tutorial作为指导。

到目前为止,我已经创建了一个片段:



// CONFIGURE SCENE
// ------------------------------------

// Create Scene - acts as container
var scene = new THREE.Scene();

// Create camera - (field of view, aspect ratio, near and far planes)
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );	

// Renderer - webgl
var renderer = new THREE.WebGLRenderer( { alpha: true,  antialias: true } );
renderer.setClearColor( 0x000000, 0 ); // set to show background of page

// Tell renderer to render to size of window
renderer.setSize( window.innerWidth, window.innerHeight );

// Add renderer to DOM
document.body.appendChild(renderer.domElement);
var controls = new THREE.OrbitControls(camera, renderer.domElement);

// ADD GEOMETRY
// ------------------------------------
var x = -12.1;
var y = -22;
var z = 0;

var a = 10; // sigma
var b = 28; // beta
var c = 8/3; // rho

var dt, dx, dy, dz;
var points = [];

// A mesh is made up of geometry and material
// Geometry is like a scaffold. Made up of x,y,z coordinates called vertices 
// Material is the fill (faces) of the geometry

// Create Material (MeshBasic is not influenced by light)
var material = new THREE.LineBasicMaterial({
    color: 0x0000ff
});

var geometry = new THREE.Geometry();

// Create mesh, passing in geometry and material
var line = new THREE.Line(geometry, material);

// Calculate the 50000 Lorenz attractor vertices
for (var i = 0; i < 50000; i++) {
	dt = 0.01;
    dx = (a * (y - x)) * dt;
    dy = (x * (b - z) - y) * dt;
    dz = (x * y - c * z) * dt;
    
    x = x + dx;
    y = y + dy;
    z = z + dz;

    geometry.vertices.push(new THREE.Vector3(x, y, z));
}

// Add line to scene
scene.add(line);

// Move the camera out, else our camera will be at 0,0,0 and the attractor won't be visible by default
camera.position.z = 80;

// RENDER LOOP
// ------------------------------------
function render() {

	/**
	// Does not work - experimenting with animating the drawing of the attractor
	// ------------------------------------
	// Calculate the Lorenz attractor vertices
	dt = 0.01;
	dx = (a * (y - x)) * dt;
	dy = (x * (b - z) - y) * dt;
	dz = (x * y - c * z) * dt;
			
	x = x + dx;
	y = y + dy;
	z = z + dz;

	var vect = new THREE.Vector3(x, y, z); // Create three.js vector
	geometry.vertices.push(vect); // Add vertice to geometry
	// ------------------------------------
	**/

	renderer.render(scene, camera); // Render scene and camera

	// Rotate the attractor
	line.rotation.x += 0.001;
	line.rotation.y += 0.001;

	requestAnimationFrame(render); // Call animation loop recursively 
}
render(); // Initial call to loop
&#13;
body {
  margin: 0;
  overflow: hidden;
  background-color: #ccc;
}
  canvas {
    width: 100%;
    height: 100%;
}
&#13;
  <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r79/three.js"></script>
  <script src="https://s3-eu-west-1.amazonaws.com/code-pen/OrbitControls.js"></script>
&#13;
&#13;
&#13;

正如您所看到的,我能够成功地绘制Lorenz吸引子,然后再添加场景。

但是,我不能通过将新顶点推到渲染循环中的几何体上来为吸引子的绘制设置动画。这样做会导致线条在屏幕上不可见。您可以在第73行开始的JavaScript注释部分中看到我尝试使用此方法的位置。

有些搜索提出了使用Three.js的BufferGeometry类的想法。但是,我不清楚该类究竟是做什么的,或者在这个例子中如何应用它。

任何指导都将不胜感激。

1 个答案:

答案 0 :(得分:4)

查看this SO answer,您可以将此答案与您的jsbin代码结合使用。您所要做的就是将全局变量标记用吸引子首字母

var MAX_POINTS = 50000;

var x = -12.1;
var y = -22;
var z = 0;

var a = 10; // sigma
var b = 28; // beta
var c = 8/3; // rho

var dt, dx, dy, dz; 

并对updatePositions()函数进行细微更改,如何设置添加线段的坐标

var index = 0;
...
dt = 0.01;
dx = (a * (y - x)) * dt;
dy = (x * (b - z) - y) * dt;
dz = (x * y - c * z) * dt;

x = x + dx;
y = y + dy;
z = z + dz;

jsfiddle示例