簡體   English   中英

ThreeJS:在鼠標單擊坐標處繪制線條

[英]ThreeJS: Draw lines at mouse click coordinates

我正在與ThreeJS合作創建一個太陽系。 我的中央有太陽,周圍有8個軌道。 現在,我想在用戶單擊地圖上的任何位置時獲得最近的響鈴位置!

這是一張形象地描述我的意思的圖片

箭頭代表用戶的“點擊”,然后應該有一個函數來獲取最近的軌道及其坐標(白點),其中單擊點和中間點之間的線發生碰撞。

我嘗試了在這里找到的許多不同功能,但沒有一個給我想要的結果。

謝謝你的幫助!

該代碼當前看起來像這樣:

            var container, stats, parent, pivots, domEvents, twins, planets, sun, fleets, raycaster, mouse;
            var camera, controls, scene, renderer;
            var cross;
            planets = new Array();

            init();
            animate();
            function init()
            {


                raycaster = new THREE.Raycaster();
                mouse = new THREE.Vector2();

                //init
                camera = new THREE.PerspectiveCamera(10, 1, 1, 4000);
                camera.position.z = 200;
                camera.position.x = 200;
                camera.position.y = 200;
                controls = new THREE.OrbitControls(camera);
                controls.addEventListener('change', render);
                scene = new THREE.Scene();
                scene.fog = new THREE.FogExp2(0x000000, 0);

                // renderer
                renderer = new THREE.WebGLRenderer({antialias: false, alpha: true});
                renderer.setSize(document.getElementById('canvasreference').offsetWidth, document.getElementById('canvasreference').offsetWidth);
                renderer.setClearColor(0x787878, 0.5); // the default

                container = document.getElementById('canvasreference');
                container.appendChild(renderer.domElement);
                window.addEventListener('resize', onWindowResize, false);
                domEvents = new THREEx.DomEvents(camera, renderer.domElement);

                //axihelper
                scene.add(new THREE.AxisHelper(130));

                // parent
                parent = new THREE.Object3D();
                scene.add(parent);

                //arrays
                orbits = new Array();



                addOrbit();

                window.addEventListener('click', onMouseMove, false);

            }


            function onMouseMove(event) {
                    canvas = renderer.domElement;
                raycaster = new THREE.Raycaster();
                mousePosition = new THREE.Vector2();
                canvasPosition = $("#canvasreference canvas").position();
                console.log(canvasPosition);
                mousePosition.x = ((event.clientX - canvasPosition.left) / canvas.width) * 2 - 1;
                mousePosition.y = -((event.clientY - canvasPosition.top) / canvas.height) * 2 + 1;

                raycaster.setFromCamera(mousePosition, camera);



                 var geometry = new THREE.Geometry();
                 var origin = new THREE.Vector3(raycaster.ray.origin.x, 0, raycaster.ray.origin.y);
                 geometry.vertices.push(origin);

                 var vektor = new THREE.Vector3(raycaster.ray.direction.x, 0, raycaster.ray.direction.y);

                 for (var i = 0; i < 1000; i++)
                 {
                 origin.add(vektor);
                 geometry.vertices.push(vektor);

                 }


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

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

                 scene.add(line);
                 renderer.render(scene, camera);




            }

            function onWindowResize() {

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

            function animate() {

                requestAnimationFrame(animate);
                controls.update();

                renderer.render(scene, camera);
            }

            function render() {
                renderer.render(scene, camera);
            }



            /**
             * add Orbit line
             * @param {type} orbit
             * @returns {undefined}
             */
            function addOrbit(orbit)
            {
                for (var i = 0; i < 8; i++)
                {
                    //make orbit line
                    var orbit = new THREE.EllipseCurve(
                            0, 0, // ax, aY
                            i * 10 + 30, i * 10 + 30, // xRadius, yRadius
                            0, 2 * Math.PI, // aStartAngle, aEndAngle
                            false, // aClockwise
                            0                 // aRotation 
                            );
                    var path = new THREE.Path(orbit.getPoints(100));
                    var geometry = path.createPointsGeometry(100);
                    var material = new THREE.LineBasicMaterial({color: 0xffffff});

                    var ellipse = new THREE.Line(geometry, material);
                    ellipse.rotation.x = 1.5708;
                    scene.add(ellipse);
                }

            }


        </script>

將光線從相機投射到鼠標所在的位置。 然后使用distanceToPoint函數檢查從該射線到太陽系中部的最近距離。 輸出矢量的長度將是射線與之相切的球體的半徑。 使用此長度,您可以確定與軌道球體的距離以及是否應該選擇該球體。 這是該檢查的一些偽代碼:

var length = getDistanceToCenter(...);
var closestSphere = _(orbits).min(function(orbit) { return Math.abs(length - orbit.radius); });
if (Math.abs(closestSphere.radius - length) < EPSILON) { 
    selectOrbit(closestSphere);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM