Roy
Roy

Reputation: 11

Aligning a Cylinder to a vector

I'm having a hard time trying to get a cylinder aligned to a particular vector. I've seen and tried a number of possible solutions, but to no avail. My understanding is that all I should need to do is to position the cylinder at the center of the vector and use LookAt() to align it. Below I've attached a simple example of this where I add a line, then am attempting to align the cylinder to this line. Would anyone be able to tell me what I'm doing wrong? TIA

Roy

<!DOCTYPE html>
<html lang="en">
<head>
    <title></title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
    <style>
        body {
            font-family: Monospace;
            background-color: #000000;
            margin: 0px;
            overflow: hidden;
        }

        #info {
            color: #fff;
            position: absolute;
            top: 10px;
            width: 100%;
            text-align: center;
            z-index: 100;
            display: block;
        }

        a {
            color: skyblue;
        }

        .button {
            background: #999;
            color: #eee;
            padding: 0.2em 0.5em;
            cursor: pointer;
        }

        .highlight {
            background: orange;
            color: #fff;
        }

        span {
            display: inline-block;
            width: 60px;
            float: left;
            text-align: center;
        }
        .left-panel{
            position: absolute; 
            top:0px; 
            left: 0px; 
            height:100%; 
            width:220px; 
            background-color:white;
        }
        .right-panel{
            position: absolute; 
            top:0px; 
            right: 0px; 
            height:100%; 
            width:220px; 
            background-color:white;
        }
    </style>
</head>
<body>
    <script src="https://ajax.googleapis.com/ajax/libs/threejs/r76/three.min.js"></script>
    <script src="http://threejs.org/examples/js/Detector.js"></script>
    <script src="http://threejs.org/examples/js/controls/OrbitControls.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
    <script>
            if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
            var camera, scene, raycaster, renderer, model, cylinder;
            var raycaster = new THREE.Raycaster();
            var mouse = new THREE.Vector2();
            var reader;
            init();
            function init() {
                scene = new THREE.Scene();
                scene.add(new THREE.AmbientLight(0x999999));

                addLine();
                addCylinder();

                camera = new THREE.PerspectiveCamera( 35, window.innerWidth / window.innerHeight, 1, 500 );
                // Z is up for objects intended to be 3D printed.
                camera.up.set(0, 0, 1);
                camera.position.set(8, -72, 20);
                camera.rotateOnAxis('X', 25);
                camera.rotateOnAxis('Z', 0.0025);
                camera.add(new THREE.PointLight(0xffffff, 0.8));
                scene.add(camera);

                var grid = new THREE.GridHelper(200, 100, 0x229922, 0x222222);//grid
                grid.rotateOnAxis(new THREE.Vector3(1, 0, 0), 90 * (Math.PI / 180));
                grid.receiveShadow = true;
                scene.add(grid);


                renderer = new THREE.WebGLRenderer( { antialias: true } );
                renderer.setClearColor( 0x333399 );// scene background color
                renderer.setPixelRatio( window.devicePixelRatio );
                renderer.setSize( window.innerWidth, window.innerHeight );
                document.body.appendChild(renderer.domElement);

                raycaster = new THREE.Raycaster();
                raycaster.linePrecision = .05;

                var controls = new THREE.OrbitControls( camera, renderer.domElement );
                controls.addEventListener( 'change', render );
                controls.target.set( 0, 1.2, 2 );
                controls.update();
                window.addEventListener('resize', onWindowResize, false);
                document.addEventListener('mousemove', onDocumentMouseMove, false);
                render();
            }
            function onWindowResize() {
                camera.aspect = window.innerWidth / window.innerHeight;
                camera.updateProjectionMatrix();
                renderer.setSize( window.innerWidth, window.innerHeight );
                render();
            }
            function render() {
               raycaster.setFromCamera(mouse, camera);
               // calculate objects intersecting the picking ray
               var intersects = raycaster.intersectObjects(scene.children);
                renderer.render( scene, camera );
            }

            function addCylinder() {
               //Mesh to align
               var material = new THREE.MeshLambertMaterial({ color: 0x666666 });

               cylinder = new THREE.Mesh(new THREE.CylinderGeometry(.2, .2, 7.5,8), material);
               var vector = new THREE.Vector3(10, 0, 10); 
               cylinder.position.set(5, 0, 5);

               //create a point to lookAt
               var focalPoint = new THREE.Vector3(
                    cylinder.position.x + vector.x,
                    cylinder.position.y + vector.y,
                    cylinder.position.z + vector.z
                );

               //all that remains is setting the up vector (if needed) and use lookAt
               //cylinder.up = new THREE.Vector3(0, 0, 1);//Z axis up
               cylinder.lookAt(focalPoint);

               scene.add(cylinder);
            }
            function addLine() {
               var material = material = new THREE.LineBasicMaterial({ color: 0xff0000, linewidth: 1, fog: false });

               var geometry = new THREE.Geometry();
                   geometry.vertices.push(
                   new THREE.Vector3(0,0,0),
                   new THREE.Vector3(10,0,10)
                    );

               var line = new THREE.Line(geometry, material);
               line.castShadow = true;
               scene.add(line);
            }
            function onDocumentMouseMove(event) {
               event.preventDefault();
               mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
               mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
               render();
            }
    </script>
</body>
</html>

Upvotes: 1

Views: 1141

Answers (1)

WestLangley
WestLangley

Reputation: 104833

All you need to do is rotate the cylinder so it aligns with the z-axis instead of the y-axis.

cylinder = new THREE.Mesh( new THREE.CylinderGeometry( .2, .2, 7.5, 8 ), material );
cylinder.geometry.rotateX( Math.PI / 2 );
cylinder.geometry.translate( 0, 0, - 7.5 / 2 ); // optional

When you call object.lookAt( target ), the oject's local positive z-axis is oriented toward the target.

three.js r.82

Upvotes: 6

Related Questions