three.js rotate mesh by two points

by sthag

HTML

<script src="http://threejs.org/build/three.min.js"></script>
<div id="ctn"></div>

CSS

#ctn {
    margin: auto auto;
    width: 640px;
    height: 480px;
}

JavaScript

var ctnEl = document.getElementById('ctn');
var camera, scene, renderer;

var init = function init() {
    scene = new THREE.Scene();

    camera = new THREE.PerspectiveCamera(70, ctnEl.offsetWidth / ctnEl.offsetHeight, 1, 8000);

    camera.position.y = 350;

    camera.position.z = 300;

    scene.add(camera);

    var geometry = new THREE.Geometry();

    geometry.vertices.push(new THREE.Vector3(0, 0, 0));
    geometry.vertices.push(new THREE.Vector3(250, 300, 0));

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

    var line = new THREE.Line(geometry, material);

    scene.add(line);

    var compLine = new THREE.Line3(geometry.vertices[0], geometry.vertices[1]);

    var marker = getCube(compLine.distance());

    scene.add(marker);

    var compCent = compLine.center();

    camera.lookAt(compCent);

    marker.position.set(compCent.x, compCent.y, compCent.z);

    rotateTwoPoint(marker, compLine.start, compLine.end);

    renderer = new THREE.WebGLRenderer();

    renderer.setSize(ctnEl.offsetWidth, ctnEl.offsetHeight);

    ctnEl.appendChild(renderer.domElement);
    
    animate();
}();

function rotateTwoPoint(rotatemesh, pt1, pt2) {

    var axis = new THREE.Vector3();

    var vec = pt1.clone().sub(pt2);

    var up = new THREE.Vector3(0, 1, 0);

    var tangent = vec.normalize();

    axis.crossVectors(up, tangent).normalize();

    var radians = Math.acos(up.dot(tangent));

    rotatemesh.quaternion.setFromAxisAngle(axis, radians);
};

function getCube(hgt) {

    var mats = [];
    for (var i = 0; i < 6; i++) {
        mats.push(new THREE.MeshBasicMaterial({
            color: Math.random() * 0xffffff,
            wireframe: true
        }));
    }

    var cube = new THREE.Mesh(
    new THREE.CubeGeometry(100, hgt, 100, 1, 1, 1),
    new THREE.MeshFaceMaterial(mats));

    return cube
}

function animate() {
    requestAnimationFrame(animate);

    renderer.render(scene, camera);
    
}