【问题标题】:Sine wave animation not occurring at expected origin正弦波动画未出现在预期的原点
【发布时间】:2016-03-21 23:56:07
【问题描述】:

我正在使用three.js 并尝试创建一个正弦波动画,该动画从用鼠标单击平面的点发出。问题是波纹的起源并不是你点击它的确切位置——它似乎总是来自平面的中间,尽管点击平面的最远范围似乎确实会以某种方式改变波浪。

数学从来不是我的强项,所以我确定这是某种逻辑问题!

代码:

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html" charset="utf-8" />
    </head>
    <body>
    </body>
    <script src="three.min.js"></script>
    <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
    <script>
        var scene = new THREE.Scene();
        var camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 10000);
        var renderer = new THREE.WebGLRenderer();
        renderer.setClearColor(0x17293a);
        renderer.setSize(window.innerWidth, window.innerHeight);
        document.body.appendChild(renderer.domElement);
        var mouse = new THREE.Vector3();

        var planeGeometry = new THREE.PlaneGeometry(200, 100, 50, 50);
        var planeMaterial = new THREE.MeshLambertMaterial({color: 0xEF3523, wireframe: true});
        var plane = new THREE.Mesh(planeGeometry, planeMaterial);
        plane.geometry.dynamic = true;
        plane.position.set(0, 0, 0);
        plane.rotation.x = -0.5 * Math.PI;
        scene.add(plane);
        camera.position.set(0, 90, 100);
        camera.lookAt(scene.position);

        var raycaster = new THREE.Raycaster();

        var checkMousePos = function() {
            mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
            mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
            raycaster.setFromCamera( mouse, camera );   
            var intersects = raycaster.intersectObjects( scene.children );
                console.log(intersects.length);
                if (intersects.length > 0) {
                    var wave = {};
                    wave.x = intersects[0].point.x;
                    wave.y = intersects[0].point.y;
                    wave.z = intersects[0].point.z;
                    drawWave(wave);
                }
        };

        drawWave = function(wave){
            var center = new THREE.Vector3(wave.x, wave.y, wave.z);
            var anim = function(ts) {
                requestAnimationFrame(anim);
                var vLength = plane.geometry.vertices.length;
                for (var i = 0; i < vLength; i++) {
                    var v = plane.geometry.vertices[i];
                    var dist = new THREE.Vector3(v.x, v.y, v.z).sub(center);
                    var size = 5.0;
                    var magnitude = 4;
                    v.z = Math.sin(dist.length()/-size + (ts/500)) * magnitude;
                }
                plane.geometry.verticesNeedUpdate = true;
                renderer.render(scene, camera);             
            }
            anim();
        };

        $(document).on('click', function(e) {
            checkMousePos();
        });


        var render = function() {
            requestAnimationFrame(render);
            renderer.render(scene, camera);
        };
        render();
    </script>
</html>

JSfiddle:https://jsfiddle.net/dwo3kvLp/

【问题讨论】:

    标签: javascript animation math three.js logic


    【解决方案1】:

    在创建中心向量的时候好像y轴和z轴需要调换一下:

    var center = new THREE.Vector3(wave.x, -wave.z, wave.y);
    

    好像是因为这里的平面是旋转的:

    plane.rotation.x = -0.5 * Math.PI;
    

    https://jsfiddle.net/dwo3kvLp/3/

    【讨论】:

      【解决方案2】:

      如果您删除旋转平面的线 (plane.rotation.x = -0.5 * Math.PI;),您会发现它工作得很好。

      因此,旋转后的 x、y 和 z 坐标并不一定意味着您会直观地认为这些方向只是通过查看它(并且它们绝对不指与您从用户单击中捕获的 x 和 y 方向相同)。发生的事情是您的 y 和 z 坐标被实施以引用旧方向。

      如果您添加一个console.log 语句来打印您的wave.xwave.ywave.z 值,就在它们被分配之后和调用drawWave(wave) 之前,然后打开控制台并单击周围的位,你应该看到问题。 (您可以在 JSFiddle 页面上直接执行此操作)

      事实证明,当您将点分配给checkMousePos 底部的波浪时,看起来像“y”(“向前-向后”)的方向由“z”控制“并且在波浪的高度上下基本保持不变。这就是为什么波原点总是在中心(向前向后)但左右移动得很好。

      所以,你需要做的就是修改这些行:

      wave.y = intersects[0].point.y;
      wave.z = intersects[0].point.z;
      

      wave.y = intersects[0].point.z * -1;
      wave.z = intersects[0].point.y;
      

      它应该可以工作。

      完整更新代码:

      var scene = new THREE.Scene();
      var camera = new THREE.PerspectiveCamera(75,
          window.innerWidth/window.innerHeight, 0.1, 10000);
      var renderer = new THREE.WebGLRenderer();
      renderer.setClearColor(0x17293a);
      renderer.setSize(window.innerWidth, window.innerHeight);
      document.body.appendChild(renderer.domElement);
      var mouse = new THREE.Vector3();
      
      var planeGeometry = new THREE.PlaneGeometry(200, 100, 50, 50);
      var planeMaterial = new THREE.MeshLambertMaterial({color: 0xEF3523, wireframe: true});
      var plane = new THREE.Mesh(planeGeometry, planeMaterial);
      plane.geometry.dynamic = true;
      plane.position.set(0, 0, 0);
      plane.rotation.x = -0.5 * Math.PI;
      scene.add(plane);
      camera.position.set(0, 90, 100);
      camera.lookAt(scene.position);
      
      var raycaster = new THREE.Raycaster();
      
      var checkMousePos = function() {
        mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
        mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
        raycaster.setFromCamera( mouse, camera ); 
        var intersects = raycaster.intersectObjects( scene.children );
        console.log(intersects.length);
        if (intersects.length > 0) {
          var wave = {};
          wave.x = intersects[0].point.x;
          wave.y = intersects[0].point.z * -1;
          wave.z = intersects[0].point.y;
          drawWave(wave);
        }
      };
      
      drawWave = function(wave){
        var center = new THREE.Vector3(wave.x, wave.y, wave.z);
        var anim = function(ts) {
          requestAnimationFrame(anim);
          var vLength = plane.geometry.vertices.length;
          for (var i = 0; i < vLength; i++) {
            var v = plane.geometry.vertices[i];
            var dist = new THREE.Vector3(v.x, v.y, v.z).sub(center);
            var size = 5.0;
            var magnitude = 4;
            v.z = Math.sin(dist.length()/-size + (ts/500)) * magnitude;
          }
          plane.geometry.verticesNeedUpdate = true;
          renderer.render(scene, camera);             
        }
        anim();
      };
      
      $(document).on('click', function(e) {
        checkMousePos();
      });
      
      
      var render = function() {
        requestAnimationFrame(render);
        renderer.render(scene, camera);
      };
      render();
      

      【讨论】:

      • 你和下面的奥斯汀是对的!我完全忘记了我旋转了飞机!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-18
      • 2014-03-29
      • 1970-01-01
      相关资源
      最近更新 更多