Three.js在球体半径上旋转对象

时间:2014-07-30 15:25:29

标签: javascript three.js geometry

我想基于object.position.set(x,y,z)在球体半径的末端设置对象

在球体上点坐标的典型数学公式中,我们有:

var x = radius * Math.cos(phi) * Math.cos(theta);
var y = radius * Math.cos(phi) * Math.sin(theta);
var z = radius * Math.cos(phi);

我用

var x = radius * Math.cos(angleZ) * Math.cos(angleX);
var y = radius * Math.cos(angleZ) * Math.sin(angleX);
var z = radius * Math.cos(angleZ);

我知道这是错误的,因为thete和phi不是这个角度 如何连接这3个角度angleX,angleY,angleZ以将其转换为phi和theta

在三个j中我有:

cylinderX.rotation.x = degToRad(angleX); 
cylinderX.rotation.y = degToRad(angleY);                    
cylinderX.rotation.z = degToRad(angleZ);
  • degToRad - 将deg更改为弧度的函数

,其中

angleX is angle between y plane and z plane
angleY is angle between z plane and x plane
angleZ is angle between x plane and y plane 

phi和θ是不同的角度,因为θ是半径和平面之间的角度

我运行动画和对象(x,y,z)的位置,并且球体平面上的itts位置错误

我如何解决这个问题?

更具体地说,下面是我的代码和示例:

http://newdesignlive.neomedia.info/index.html

当汽车在所有轴x,y,z上以所有角度旋转时,我想在这个红色长方体的末端设置这个绿色立方体

在数组中:x [...],y [...],z [...]你有汽车(物体)在所有轴(X,Y,Z)上旋转的角度值; < / p>

我不知道如何将angleX,angleZ,angleY连接到“phi”和“theta”以在正确位置x,y,z上设置“绿色立方体”,例如取决于radius = 100;

在animate.js中,这里是我在下面添加它的所有代码

    var container, stats, camera, scene, renderer, object;          
    var mouseX = 0, mouseY = 0;

    var windowHalfX = window.innerWidth / 2;
    var windowHalfY = window.innerHeight / 2;

    var angleX=0, angleY=0, angleZ=0, G=0;
    var x;  var y; var z; 
    var times = [];

    x = ["0", "10", "20","30", "40", "50" ];                                
    y = ["0", "20", "40","60", "70", "80" ];    
    z = ["0", "30", "60","90", "120", "150"  ];     
    gX = ["1", "1.4", "0.7", "0.4", "1", "1.2", "0.5", "1.2", "1.4", "1.3", "1", "0.7" ];
    gY = ["1", "2", "1", "2", "1", "2", "3", "1.2", "1.4", "1.3", "1", "2" ];
    gZ = ["1", "2", "1", "2", "1", "2", "3", "1.2", "1.4", "1.3", "1", "2" ];   


    generateTimesForAngles();
    generateTimesForG();

    var currentTransform = 0;
    var currentStep = 0;
    var intervalTime = 20;
    var intervalTimeG = 50

    setInterval(transformAngleX,intervalTime);
    setInterval(transformAngleY,intervalTime);
    setInterval(transformAngleZ,intervalTime);
    setInterval(transformGX,intervalTimeG);
    setInterval(transformGY,intervalTimeG); 
    setInterval(transformGZ,intervalTimeG);             

    init();
    animate();          

    function setVectorDirection (position, gValue)
    {
        var gValue = document.getElementById('g').value;
        gValue = gValue*10;

        var direction = document.getElementById("VectorDirection");
        var position = direction.options[direction.selectedIndex].value;

        var darkMaterial = new THREE.MeshBasicMaterial( { color: 0x222222 } );
        var wireframeMaterial = new THREE.MeshBasicMaterial( { color: 0x222222, wireframe: true, transparent: true } );                 var multiMaterial = [ darkMaterial, wireframeMaterial ];


        var x;
        var y;              
        x = 120 + gValue - gValue/2; 
        y = 110;
    }

    function init(objectfilename, materialfilename) {

        renderer = new THREE.WebGLRenderer();
        renderer.setSize( window.innerWidth, window.innerHeight );
        renderer.setClearColor( 0xDEDEDE, 1 );

        container = document.createElement('div');
        document.body.appendChild(container);   
        container.appendChild( renderer.domElement )                    

        camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000 );
        camera.position.y = 200;
        camera.position.z = 0;
        camera.position.x = 400;


        controls = new THREE.OrbitControls( camera );
        controls.addEventListener( 'change', render );

        scene = new THREE.Scene();

        var gridHelper = new THREE.GridHelper( 500, 100 );      
        gridHelper.setColors(0xFFFFFF, 0xFFFFFF);               
        scene.add(gridHelper);


        var material = new THREE.LineBasicMaterial({
            color: 0x0000ff
            });

        var initColor = new THREE.Color( 0xFFFFFF );
        var initTexture = THREE.ImageUtils.generateDataTexture( 1, 1, initColor );

        var groundMaterial = new THREE.MeshPhongMaterial
        ( 
            { 
            color: 0xEDEDED, 
            specular: 0xEDEDED, 
            map: initTexture }
            );

        var groundTexture = THREE.ImageUtils.loadTexture
            ( 
                "red.jpg", 
                undefined, 
                function()
                { 
                    groundMaterial.map = groundTexture 
                } 
            );

        groundTexture.wrapS = groundTexture.wrapT = THREE.RepeatWrapping;
        groundTexture.repeat.set( 25, 25 );
        groundTexture.anisotropy = 16;

        var backgroundmesh = new THREE.Mesh( new THREE.PlaneGeometry( 20000, 20000 ), groundMaterial );
        backgroundmesh.position.y = -200;
        backgroundmesh.rotation.x = - Math.PI / 2;
        backgroundmesh.receiveShadow = true;
        scene.add( backgroundmesh );

        setVectorDirection();

        light = new THREE.DirectionalLight(0xffffff);

        light.position.set(0, 100, 60);
        light.castShadow = true;
        light.shadowCameraLeft = -60;
        light.shadowCameraTop = -60;
        light.shadowCameraRight = 60;
        light.shadowCameraBottom = 60;
        light.shadowCameraNear = 1;
        light.shadowCameraFar = 10000;
        light.shadowBias = -.0001
        light.shadowMapWidth = light.shadowMapHeight = 1024;
        light.shadowDarkness = .7;
            scene.add(light);


        mesh1 = new THREE.Mesh( geometry, material );
        mesh1.position.set(100,100,100);
        scene.add( mesh1 );


        var geometry;

        loader = new THREE.JSONLoader();

        var material = new THREE.MeshLambertMaterial({
        map: THREE.ImageUtils.loadTexture('gtare.jpg'),   
        colorAmbient: [0.480000026226044, 0.480000026226044, 0.480000026226044],
        colorDiffuse: [0.480000026226044, 0.480000026226044, 0.480000026226044],
        colorSpecular: [0.8999999761581421, 0.8999999761581421, 0.8999999761581421]
            });

        mesh = new THREE.Mesh( geometry, material );
        scene.add( mesh );


        grotX = new THREE.Mesh( new THREE.CylinderGeometry( 0.4, 8, 8, 40, 1 ),new THREE.MeshBasicMaterial( { color: 0x458B00 } ));

        cylinderX = new THREE.Mesh(new THREE.BoxGeometry(10,10,10)/*THREE.CylinderGeometry(4, 4, 300, 50, 50, false)*/,new THREE.MeshBasicMaterial( { color: 0x458B00 } )); 

        cylinderY = new THREE.Mesh(new THREE.BoxGeometry(10,10,10/*4, 4, 300, 50, 50, false*/),new THREE.MeshBasicMaterial( { color: 0x01C5BB } )); 
        cylinderZ = new THREE.Mesh(new THREE.BoxGeometry(10,200,10/*4, 4, 300, 50, 50, false*/),new THREE.MeshBasicMaterial( { color: 0xFF0000 } ));


        scene.add(cylinderX);
        scene.add(cylinderY);
        scene.add(cylinderZ);

        loader.load('car.js', function (geometry, materials) {
            var material = new THREE.MeshLambertMaterial({
        map: THREE.ImageUtils.loadTexture('gtare.jpg'),   
        colorAmbient: [0.480000026226044, 0.480000026226044, 0.480000026226044],
        colorDiffuse: [0.480000026226044, 0.480000026226044, 0.480000026226044],
        colorSpecular: [0.8999999761581421, 0.8999999761581421, 0.8999999761581421]
            });

          mesh = new THREE.Mesh( geometry, material );

          mesh.receiveShadow = true;
          scene.add(mesh);
          render(); 
        });



    }


    function degToRad(degrees) {
        return degrees * Math.PI / 180.0;
    }

        function radToDeg(radians) {
        return parseInt(radians * 180.0 / Math.PI);
    }

    function onWindowResize() {

        camera.aspect = window.innerWidth / window.innerHeight;
        camera.updateProjectionMatrix();
        renderer.setSize( window.innerWidth, window.innerHeight );
        render();
    }

    function generateTimesForAngles() {
        var baseTime360 = 10000;
        for(i=0;i<z.length-1;i++) {
            var timeMiddle = 10000;
            times.push(timeMiddle);
        }
    }

    function generateTimesForG() {
        var baseTimeallG = 5000;
        for(i=0;i<g.length-1;i++) {
            var timeMiddleG = 240;
            times.push(timeMiddleG);
        }

    }

    function transformGX() {
        var steps = times[currentTransform] / intervalTime;
        var singleStepGX = (gX[currentTransform+1]-gX[currentTransform]) / steps;


        if(currentStep<steps) {
            currentStep++;
            GX = +gX[currentTransform] + (+currentStep * +singleStepGX); 

        } else if(currentTransform<times.length){
            currentStep = 0;
            currentTransform++;
            GX = gX[currentTransform];
        } else {
        }
    }

    function transformGY() {
        var steps = times[currentTransform] / intervalTime;
        var singleStepGY = (gY[currentTransform+1]-gY[currentTransform]) / steps;


        if(currentStep<steps) {
            currentStep++;
            GY = +gY[currentTransform] + (+currentStep * +singleStepGY);

        } else if(currentTransform<times.length){
            currentStep = 0;
            currentTransform++;
            GY = gY[currentTransform];
        } else {

        }
    }

    function transformGZ() {
        var steps = times[currentTransform] / intervalTime;
        var singleStepGZ = (gZ[currentTransform+1]-gZ[currentTransform]) / steps;

        if(currentStep<steps) {
            currentStep++;
            GZ = +gZ[currentTransform] + (+currentStep * +singleStepGZ); // Pamiętaj o plusach!!!
        } else if(currentTransform<times.length){
            currentStep = 0;
            currentTransform++;
            GZ = gZ[currentTransform];
        } else {
        }
    }

    function transformAngleX() {
        var steps = times[currentTransform] / intervalTime;
        var singleStepAngle = (x[currentTransform+1]-x[currentTransform]) / steps;

        if(currentStep<steps) {
            currentStep++;
            angleX = +x[currentTransform] + (+currentStep * +singleStepAngle); 

        } else if(currentTransform<times.length){
            currentStep = 0;
            currentTransform++;
            angleX = x[currentTransform];
        } else {

        }
    }

    function transformAngleY() {
        var steps = times[currentTransform] / intervalTime;
        var singleStepAngle = (y[currentTransform+1]-y[currentTransform]) / steps;

        if(currentStep<steps) {
            currentStep++;
            angleY = +y[currentTransform] + (+currentStep * +singleStepAngle); 
        } else if(currentTransform<times.length){
            currentStep = 0;
            currentTransform++;
            angleY = y[currentTransform];
        } else {

        }
    }

    function transformAngleZ() {
        var steps = times[currentTransform] / intervalTime;
        var singleStepAngle = (z[currentTransform+1]-z[currentTransform]) / steps;

        if(currentStep<steps) {
            currentStep++;
            angleZ = +z[currentTransform] + (+currentStep * +singleStepAngle); // Pamiętaj o plusach!!!

        } else if(currentTransform<times.length){
            currentStep = 0;
            currentTransform++;
            angleZ = z[currentTransform];
        } else {

        }
    }

    var i = 0;

    function animate() {

        i++;
        requestAnimationFrame( animate );

        var x = 100 * Math.sin(degToRad(angleX))* Math.cos(degToRad(angleY)); 
        var y = 100 * Math.sin(degToRad(angleX))* Math.sin(degToRad(angleY));
        var z = 100 * Math.cos(degToRad(angleX));   

        z = -z;
        cylinderX.position.set(x,y,z);  
        cylinderY.position.set(0, 0, 0);
        cylinderX.rotation.x = degToRad(angleX);
        cylinderX.rotation.y = degToRad(angleY);                    
        cylinderX.rotation.z = degToRad(angleZ);
        cylinderZ.rotation.x = degToRad(angleX);
        cylinderZ.rotation.y = degToRad(angleY);                    
        cylinderZ.rotation.z = degToRad(angleZ-90);     

        mesh.rotation.x = degToRad(angleX);     
        mesh.rotation.y = degToRad(angleY);
        mesh.rotation.z = degToRad(angleZ);
        render();
    }

    //renderowanie obiektów
    function render() {

        renderer.render( scene, camera );
    }           

1 个答案:

答案 0 :(得分:0)

我认为最简单的方法是将对象添加到父Object3D,并将对象移动到一个 xyz轴。将父项添加到场景中并将其放置在要匹配的球体的中心上(子对象现在应该落在与您使用的轴相交的球体上)。通过这样的设置,您可以旋转父对象以将对象放在球体上。