Javascript 依赖于参数的Three.js场景
我对html/javascript不是很流利,我从Javascript 依赖于参数的Three.js场景,javascript,three.js,Javascript,Three.js,我对html/javascript不是很流利,我从three.js开始。我做了一个场景,它依赖于一个可以由用户控制的参数 下面的代码是这种场景的一个完整的最小示例。它呈现一个参数化曲面,该曲面取决于用户可以使用输入type=“number”更改的参数a 显然,这不是一个好的继续方式:场景是动画的,当一个人玩参数时,动画会加速,我不知道为什么。编写这样一个场景的好方法是什么 <html> <head> <title>Dupin cyclide</ti
three.js
开始。我做了一个场景,它依赖于一个可以由用户控制的参数
下面的代码是这种场景的一个完整的最小示例。它呈现一个参数化曲面,该曲面取决于用户可以使用输入type=“number”
更改的参数a
显然,这不是一个好的继续方式:场景是动画的,当一个人玩参数时,动画会加速,我不知道为什么。编写这样一个场景的好方法是什么
<html>
<head>
<title>Dupin cyclide</title>
<style>
canvas {
width: 100%;
height: 100%
}
</style>
</head>
<body>
<script src="http://threejs.org/build/three.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<label for="a">a: </label>
<input id="a" type="number" step="0.1" min="0.5" value="0.9"/>
<script> // change event -----------------------------------------------------
$("#a").on("change", function(){
Rendering(this.value);
})
</script>
<script> // cyclide parametrization ------------------------------------------
function fcyclide(a, c, mu) {
var b = Math.sqrt(a * a - c * c);
return function (u, v, vector) {
var uu = 2 * u * Math.PI; var vv = 2 * v * Math.PI;
var cosu = Math.cos(uu); var cosv = Math.cos(vv);
var h = a - c * cosu * cosv;
var x = (mu * (c - a * cosu * cosv) + b * b * cosu) / h;
var y = (b * Math.sin(uu) * (a - mu * cosv)) / h;
var z = b * Math.sin(vv) * (c * cosu - mu) / h;
vector.x = x; vector.y = y; vector.z = z;
}
}
</script>
<script> // add cyclide to object --------------------------------------------
function addCyclide(object, a) {
var geom = new THREE.ParametricGeometry(
fcyclide(a, 0.34, 0.56), 40, 40);
var material = new THREE.MeshNormalMaterial();
var mesh = new THREE.Mesh(geom, material);
object.add(mesh);
}
</script>
<script> // three.js ---------------------------------------------------------
var scene = new THREE.Scene();
var aspect = window.innerWidth / window.innerHeight;
var camera = new THREE.PerspectiveCamera(70, aspect, 1, 10000);
camera.position.z = 4;
scene.add(camera);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var object = new THREE.Object3D()
scene.add(object);
window.requestAnimFrame = (function () {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function (callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
function render() {
renderer.render(scene, camera);
object.rotation.x += 0.001; object.rotation.y += 0.001;
requestAnimFrame(render);
}
</script>
<script> // Rendering function -----------------------------------------------
function Rendering(a) {
object.children.splice(0); // clear scene
addCyclide(object, a);
render();
}
</script>
<script> // Render the scene -------------------------------------------------
Rendering(0.9);
</script>
</body>
</html>
杜平环化物
帆布{
宽度:100%;
身高:100%
}
a:
//变更事件-----------------------------------------------------
$(“#a”)。关于(“更改”,函数(){
渲染(此值);
})
//环化参数化------------------------------------------
函数fcyclide(a、c、mu){
VarB=Math.sqrt(a*a-c*c);
返回函数(u、v、向量){
var uu=2*u*Math.PI;var vv=2*v*Math.PI;
var cosu=Math.cos(uu);var cosv=Math.cos(vv);
var h=a-c*cosu*cosv;
var x=(mu*(c-a*cosu*cosv)+b*b*cosu)/h;
变量y=(b*Math.sin(uu)*(a-mu*cosv))/h;
var z=b*数学sin(vv)*(c*cosu-mu)/h;
向量x=x;向量y=y;向量z=z;
}
}
//将循环添加到对象--------------------------------------------
函数addCyclide(对象,a){
var geom=新的三参数几何图形(
环磷酰胺(a,0.34,0.56),40,40);
var material=新的三个.MeshNormalMaterial();
var网格=新的三个网格(几何、材料);
对象。添加(网格);
}
//three.js------------------------------------------
var scene=new THREE.scene();
var aspect=window.innerWidth/window.innerHeight;
var摄像机=新的三个透视摄像机(70,纵横比,11000);
摄像机位置z=4;
场景。添加(摄影机);
var renderer=new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth、window.innerHeight);
document.body.appendChild(renderer.doElement);
var object=new THREE.Object3D()
场景。添加(对象);
window.requestAnimFrame=(函数(){
return window.requestAnimationFrame||
window.webkitRequestAnimationFrame||
window.mozRequestAnimationFrame||
函数(回调){
设置超时(回调,1000/60);
};
})();
函数render(){
渲染器。渲染(场景、摄影机);
object.rotation.x+=0.001;object.rotation.y+=0.001;
请求帧(渲染);
}
//渲染功能-----------------------------------------------
函数渲染(a){
object.children.splice(0);//清除场景
addCyclide(对象,a);
render();
}
//渲染场景-------------------------------------------------
渲染(0.9);
显然,这不是一个好的继续方式:场景是动画的,当一个人玩参数时,动画会加速,我不知道为什么
每次调用requestAnimFrame
时,计时器都会由setTimeout
启动。计时器调用render
,再次启动计时器并重复该过程。
首先,函数render
由Rendering(a)
调用但是由于
Rendering(a)
也是由change
事件调用的,因此每次更改输入时都会启动一个新的计时器。您更改输入的频率越高,同时运行的计时器就越多。这会导致速度加快
要解决此问题,必须从渲染(a)
中删除渲染
调用
但在启动时调用requestAnimFrame
一次:
Rendering(0.9);
requestAnimFrame(render);
参见示例,其中答案的建议应用于问题的原始代码:
$(“#a”)。关于(“更改”,函数(){
渲染(此值);
})
函数fcyclide(a、c、mu){
VarB=Math.sqrt(a*a-c*c);
返回函数(u、v、向量){
var uu=2*u*Math.PI;var vv=2*v*Math.PI;
var cosu=Math.cos(uu);var cosv=Math.cos(vv);
var h=a-c*cosu*cosv;
var x=(mu*(c-a*cosu*cosv)+b*b*cosu)/h;
变量y=(b*Math.sin(uu)*(a-mu*cosv))/h;
var z=b*数学sin(vv)*(c*cosu-mu)/h;
向量x=x;向量y=y;向量z=z;
}
}
函数addCyclide(对象,a){
var geom=新的三参数几何(fcyclide(a,0.34,0.56),40,40);
var material=新的三个.MeshNormalMaterial();
var网格=新的三个网格(几何、材料);
对象。添加(网格);
}
var scene=new THREE.scene();
var aspect=window.innerWidth/window.innerHeight;
var摄像机=新的三个透视摄像机(70,纵横比,11000);
摄像机位置z=4;
场景。添加(摄影机);
var renderer=new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth、window.innerHeight);
document.body.appendChild(renderer.doElement);
var object=new THREE.Object3D()
场景。添加(对象);
window.onresize=调整大小;
window.requestAnimFrame=(函数(){
return window.requestAnimationFrame||
window.webkitRequestAnimationFrame||
window.mozRequestAnimationFrame||
函数(回调){
设置超时(回调,1000/60);
};
})();
函数render(){
渲染器。渲染(场景、摄影机);
object.rotation.x+=0.001;object.rotation.y+=0.001;
请求帧(渲染);
}
函数resize(){
var aspect=window.innerWidth/window.innerHeight;
renderer.setSize(window.innerWidth、window.innerHeight);
camera.aspect=aspect;
camera.updateProjectMatrix();
}
函数渲染(a){
object.children.splice(0);//清除场景
addCyclide(对象,a);
}
渲染(0.9);
请求动画帧(渲染)
Rendering(0.9);
requestAnimFrame(render);