ThreeJS - 线和球的交点

时间:2014-08-01 17:00:54

标签: javascript three.js

我的场景中有两个物体:红线和球体。

当相机旋转/变焦/移动时,我需要检查以下内容:

  • 线条是否与相机当前位置的球体相交(请参见下图)?请使用在图像上创建场景的this JS fiddle

我知道如何找到当前鼠标位置与场景中对象之间的交集(仅like this example显示)。

但在我的情况下如何做到这一点?

does not intersect

intersect

JS小提琴代码:

    /**
     * PREPARE SCENE
     */
    var mouse = {
        x : 0,
        y : 0
    };

    var projector = new THREE.Projector();

    var scene = new THREE.Scene();
    var camera = new THREE.PerspectiveCamera(75,
            window.innerWidth / window.innerHeight, 0.1, 1000);

    camera.position.x = -5;
    camera.position.y = 5;
    camera.position.z = 30;

    var renderer = new THREE.WebGLRenderer({ alpha: true });
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.body.appendChild(renderer.domElement);

    var controls = new THREE.TrackballControls(camera,
            renderer.domElement);

    controls.rotateSpeed = 3.0;
    controls.zoomSpeed = 1.5;
    controls.panSpeed = 1.0;

    controls.staticMoving = true;

    var grid = new THREE.GridHelper(20, 5);
    scene.add(grid);

    /**
     * CREATE SPHERE
     */
    var sphere = new THREE.Mesh(
            new THREE.SphereGeometry(5, 10, 10),
            new THREE.MeshNormalMaterial());
    sphere.overdraw = true;
    scene.add(sphere);

    /**
     * CREATE LINE
     */
    var lineMaterial = new THREE.LineBasicMaterial({
        color : 0xFF0000
    });
    var lineGeometry = new THREE.Geometry();
    lineGeometry.vertices.push(new THREE.Vector3(8, 8, 8));
    lineGeometry.vertices.push(new THREE.Vector3(8, 8, 20));
    var line = new THREE.Line(lineGeometry, lineMaterial);
     scene.add(line);


    renderer.domElement.addEventListener('mousemove', render, false);
    render();

    function render(event) {

        var mouse = {};

        /*
         * INTERSECTION
         */
        if (event != null) {
            //intersection job???
        }
        controls.update();
        renderer.render(scene, camera);
    }

1 个答案:

答案 0 :(得分:1)

所以,我发现解决方案非常简单(当然)。请参阅检查线和球体交叉点的new JS Fiddle,并将光线可视化以进行调试。

enter image description here

JS小提琴代码:

    var camera, controls, scene, renderer;

init();
animate();
render();

function init() {

    camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 10000);
    camera.position.z = 800;

    controls = new THREE.TrackballControls(camera);
    controls.rotateSpeed = 5.0;
    controls.zoomSpeed = 1.2;
    controls.panSpeed = 4;
    controls.noZoom = false;
    controls.noPan = false;
    controls.staticMoving = true;

    controls.addEventListener('change', render);

    // world

    scene = new THREE.Scene();
    sceneTarget = new THREE.Scene();

    var grid = new THREE.GridHelper(500, 50);
        scene.add(grid);

     /**
     * CREATE LINE
     */
    var lineMaterial = new THREE.LineBasicMaterial({
        color : 0xFF0000
    });
    var lineGeometry = new THREE.Geometry();
    lineGeometry.vertices.push(new THREE.Vector3(100, 200, 100));
    lineGeometry.vertices.push(new THREE.Vector3(300, 200, 200));
    var line = new THREE.Line(lineGeometry, lineMaterial);
     sceneTarget.add(line);

    /*
    * CREARE SPHERE
    */
    var sphere = new THREE.Mesh(new THREE.SphereGeometry(150, 100, 100), new THREE.MeshNormalMaterial());
  sphere.overdraw = true;
  scene.add(sphere);

    // renderer

    renderer = new THREE.WebGLRenderer({
        alpha: true 
    });
    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.autoClear = false;
    renderer.setClearColor(0xffffff, 1);

     document.body.appendChild(renderer.domElement);
}

function animate() {

    requestAnimationFrame(animate);
    controls.update();

}

function render() {

    renderer.render(scene, camera);
    renderer.render(sceneTarget, camera);
    intersect();

}

function intersect() {

    var direction = new THREE.Vector3(100, 200, 100);

    var startPoint = camera.position.clone();

    var directionVector = direction.sub( startPoint );

    var ray = new THREE.Raycaster(startPoint, directionVector.clone(). normalize());

    scene.updateMatrixWorld(); // required, since you haven't rendered yet

    var rayIntersects = ray.intersectObjects(scene.children, true);

    if (rayIntersects[0]) {
        //inersection is found
        console.log(rayIntersects[0]);

        //visualize the ray for debugging
        var material = new THREE.LineBasicMaterial({
          color: 0x0000ff
        });
        var geometry = new THREE.Geometry();
        geometry.vertices.push(new THREE.Vector3(ray.ray.origin.x, ray.ray.origin.y, ray.ray.origin.z));
        geometry.vertices.push(new THREE.Vector3(100, 200, 100));
        var line = new THREE.Line(geometry, material);
        sceneTarget.add( line );

    }

}