缩放对象时的行为很怪异

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了缩放对象时的行为很怪异相关的知识,希望对你有一定的参考价值。

我正在尝试通过GUI框上的参数缩放对象

这是代码:

    window.onload = init();
    animate();

    var scene, camera, renderer;
    var cube;
    var raycaster, mouse;
    var INTERSECTED;

    var isClicked = false;


params = 
  yAxis: "0.00001"

var gui = new dat.GUI();
gui.add(params, "yAxis").onFinishChange(val => 
  cube.scale.y = parseFloat(val);
); 


 let vis = gui.domElement.style.visibility;
 gui.domElement.style.visibility = vis == "" ? "hidden" : "";


    function init() 

        scene = new THREE.Scene();


        camera = new THREE.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000)
        camera.position.z = 5;


        renderer = new THREE.WebGLRenderer(antialias: true);
        renderer.setClearColor("#e5e5e5"); //background color
        renderer.setSize(window.innerWidth,window.innerHeight); //size of renderer


        document.getElementById("WebGL-output").appendChild(renderer.domElement);  

        raycaster = new THREE.Raycaster();
        mouse = new THREE.Vector2(1,1);

        var cubeGeometry = new THREE.BoxGeometry(20, 0.00001, 20);
        var cubeMaterial = new THREE.MeshLambertMaterial(color: 0xffff00 ); //0xF7F7F7 = gray
        cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
        cube.userData.originalColor = 0xffff00;


        cube.position.x = 0;
        cube.position.y = 3;
        cube.position.z = 0;

        scene.add(cube);

        var ambientLight = new THREE.AmbientLight(0x0c0c0c);
        scene.add(ambientLight);
        var spotLight = new THREE.SpotLight(0xffffff);
        spotLight.position.set(-40, 60, -10);
        spotLight.castShadow = true;
        scene.add(spotLight);


        camera.position.x = -30;
        camera.position.y = 40;
        camera.position.z = 30;
        camera.lookAt(scene.position);

        document.addEventListener('mousemove', onDocumentMouseMove, false);

        document.addEventListener('click', onDocumentMouseClick, false);
    

    function onDocumentMouseMove(event)
    

      event.preventDefault();
      mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
      mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;

        var intersects = raycaster.intersectObjects( scene.children );

        if ( intersects.length > 0 && intersects[ 0 ].object === cube && isClicked === false)
        
            cube.material.color.set( 0xff0000 );
         
        else if (isClicked === false)
        
            cube.material.color.set( cube.userData.originalColor );
        

    

    function onDocumentMouseClick(event) 
    

        event.preventDefault();


        mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
        mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;


        var intersects = raycaster.intersectObjects( scene.children );

        if ( intersects.length > 0 && intersects[ 0 ].object === cube && isClicked === false)
        
            isClicked = true;
            cube.material.color.set( 0xF7F7F7 );

            vis = gui.domElement.style.visibility;
            gui.domElement.style.visibility = vis == "" ? "hidden" : "";


         
        else if ( intersects.length > 0 && intersects[ 0 ].object === cube && isClicked === true)
        
            isClicked = false;
            cube.material.color.set( cube.userData.originalColor );

            vis = gui.domElement.style.visibility;
            gui.domElement.style.visibility = vis == "" ? "hidden" : "";
        


    


    function render() 
    

        raycaster.setFromCamera( mouse, camera );
        renderer.render(scene, camera); 
    


    function animate()
    
        requestAnimationFrame( animate ); 
        render();
    
<!DOCTYPE html>

<html>

<head>
    <title>Example 01.02 - First Scene</title>
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/three.js/110/three.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.6/dat.gui.min.js"></script>
    <style>
        body 
            margin: 0;
            overflow: hidden;
        
    </style>
</head>
<body>

<!-- Div which will hold the Output -->
<div id="WebGL-output">
</div>

</body>
</html>

有一种非常奇怪的行为,我无法理解为什么会发生:

更具体地说:

如果我将多维数据集保留为代码(20,0.00001,20)然后,无法从GUI更改y参数。X和z会发生变化,但是,例如,如果我给定值2,则它们的网格会变大。从20到2,网格怎么可能变大?

我尝试更改多维数据集构造函数,并使用了(20,20,20)现在y改变了,但它也总是变大。...

总结,我的问题:

1)将值初始化为20 ...为什么小于20的新值会使网格看起来更大?

2)当y参数的初始值为0.00001 ...为什么不能从GUI完全更改它?

答案

这是因为cube.scale充当几何的乘法,但它乘以非常小的数字。

以这种方式考虑,您拥有GeometryMesh,并且Mesh.scale乘以几何值。让我们看一下Y值:

Geometry.y = 0.00001
Mesh.scale.y = 1
Visible height = 0.00001 * 1 = 0.00001;

// Now if you change the scale of y to 20
Geometry.y = 0.00001
Mesh.scale.y = 20
Visible height = 0.00001 * 20 = 0.0002;

问题是您要初始化的几何图形非常小。您应该更改几何形状以从更大的值开始,然后将缩放比例应用于“网格”:

var cubeGeometry = new THREE.BoxGeometry(20, 20, 20);
cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
cube.scale.y = 0.00001;

window.onload = init();
    animate();

    var scene, camera, renderer;
    var cube;
    var raycaster, mouse;
    var INTERSECTED;

    var isClicked = false;


params = 
  yAxis: "0.00001"

var gui = new dat.GUI();
gui.add(params, "yAxis").onFinishChange(val => 
  cube.scale.y = parseFloat(val);
); 


 let vis = gui.domElement.style.visibility;
 gui.domElement.style.visibility = vis == "" ? "hidden" : "";


    function init() 

        scene = new THREE.Scene();


        camera = new THREE.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000)
        camera.position.z = 5;


        renderer = new THREE.WebGLRenderer(antialias: true);
        renderer.setClearColor("#e5e5e5"); //background color
        renderer.setSize(window.innerWidth,window.innerHeight); //size of renderer


        document.getElementById("WebGL-output").appendChild(renderer.domElement);  

        raycaster = new THREE.Raycaster();
        mouse = new THREE.Vector2(1,1);

        var cubeGeometry = new THREE.BoxGeometry(20, 20, 20);
        var cubeMaterial = new THREE.MeshLambertMaterial(color: 0xffff00 ); //0xF7F7F7 = gray
        cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
        cube.scale.y = 0.00001;
        cube.userData.originalColor = 0xffff00;


        cube.position.x = 0;
        cube.position.y = 3;
        cube.position.z = 0;

        scene.add(cube);

        var ambientLight = new THREE.AmbientLight(0x0c0c0c);
        scene.add(ambientLight);
        var spotLight = new THREE.SpotLight(0xffffff);
        spotLight.position.set(-40, 60, -10);
        spotLight.castShadow = true;
        scene.add(spotLight);


        camera.position.x = -30;
        camera.position.y = 40;
        camera.position.z = 30;
        camera.lookAt(scene.position);

        document.addEventListener('mousemove', onDocumentMouseMove, false);

        document.addEventListener('click', onDocumentMouseClick, false);
    

    function onDocumentMouseMove(event)
    

      event.preventDefault();
      mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
      mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;

        var intersects = raycaster.intersectObjects( scene.children );

        if ( intersects.length > 0 && intersects[ 0 ].object === cube && isClicked === false)
        
            cube.material.color.set( 0xff0000 );
         
        else if (isClicked === false)
        
            cube.material.color.set( cube.userData.originalColor );
        

    

    function onDocumentMouseClick(event) 
    

        event.preventDefault();


        mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
        mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;


        var intersects = raycaster.intersectObjects( scene.children );

        if ( intersects.length > 0 && intersects[ 0 ].object === cube && isClicked === false)
        
            isClicked = true;
            cube.material.color.set( 0xF7F7F7 );

            vis = gui.domElement.style.visibility;
            gui.domElement.style.visibility = vis == "" ? "hidden" : "";


         
        else if ( intersects.length > 0 && intersects[ 0 ].object === cube && isClicked === true)
        
            isClicked = false;
            cube.material.color.set( cube.userData.originalColor );

            vis = gui.domElement.style.visibility;
            gui.domElement.style.visibility = vis == "" ? "hidden" : "";
        


    


    function render() 
    

        raycaster.setFromCamera( mouse, camera );
        renderer.render(scene, camera); 
    


    function animate()
    
        requestAnimationFrame( animate ); 
        render();
    
<!DOCTYPE html>

<html>

<head>
    <title>Example 01.02 - First Scene</title>
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/three.js/110/three.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.6/dat.gui.min.js"></script>
    <style>
        body 
            margin: 0;
            overflow: hidden;
        
    </style>
</head>
<body>

<!-- Div which will hold the Output -->
<div id="WebGL-output">
</div>

</body>
</html>

以上是关于缩放对象时的行为很怪异的主要内容,如果未能解决你的问题,请参考以下文章

TabView 中的奇怪图像行为:图像无法缩放

使用 Numpy 进行逐行缩放

Angular JS 缩放和性能

D3:如何在单个图表中处理缩放和工具提示?

tkinter使用grid布局时的缩放问题

pyqtgraph 自定义缩放问题