ThreeJS - Intersection of a line and sphere

不打扰是莪最后的温柔 提交于 2019-12-24 05:40:19

问题


I have two objects on my scene: a red line and a sphere.

While camera rotating/zooming/moving, I need to check the following:

  • Does the line intersects with the sphere looking from the current position of the camera (please see images below)? Please use this JS fiddle that creates the scene on the images.

I know how to find the intersection between the current mouse position and objects on the scene (just like this example shows).

But how to do this in my case?

JS Fiddle Code:

    /**
     * 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:


So, I found the solution that is pretty simple (of course). See new JS Fiddle that checks intersection of the line and sphere and visualizes the ray for debugging.

The JS Fiddle code:

    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 );

    }

}


来源:https://stackoverflow.com/questions/25085224/threejs-intersection-of-a-line-and-sphere

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!