three.js: поиск ближайшей точки меша к курсору мыши

Представьте себе эту сцену three.js, созданную с помощью OrthographicCamera и OrbitControls:

Изображение земного шара three.js

Когда пользователь перетаскивает желтый диск (обозначающий Солнце), диск должен перемещаться по желтому кругу в ответ на это действие. Вот сцена с другого ракурса, чтобы вы могли видеть полный желтый круг:

Другой ракурс сцены three.js

Итак, мой обработчик событий должен определить, какая точка на этом круге ближе всего к текущей позиции курсора. Между прочим, этот желтый кружок - ТРИ.

Я использую THREE.Raycaster для определения некоторых событий наведения курсора мыши. , используя свою intersectObjects() функцию, но мне непонятно, как найти ближайшую точку отдельного объекта с помощью этого Raycaster. Я предполагаю, что есть простая математика, которую я могу сделать после перевода положения мыши в мировые координаты. Может кто-то помочь мне с этим? Полезен ли здесь Raycaster от Three.js? Если нет, как мне определить ближайшую точку этой сетки?

Полный исходный код здесь, если он полезен: https://github.com/ccnmtl/astro-interactives/blob/master/sun-motion-simulator/src/HorizonView.jsx Найдите this.sunDeclination, который соответствует объекту Mesh желтого круга.

Для рабочей демонстрации перейдите сюда: https://ccnmtl.github.io/astro-interactives/sun-motion-simulator/

Для справки, солнце должно вести себя так: https://cse.unl.edu/~astrodev/flashdev2/sunMotions/sunMotions068.html (требуется Flash)


person nnyby    schedule 17.09.2018    source источник
comment
Взгляните на этот пример.   -  person prisoner849    schedule 18.09.2018


Ответы (2)


Самый простой вариант:

  • получить точку на диске
  • сделать проекцию в плоскости круга
  • зная радиус круга, вычислим множитель для умножения вектора на скаляр

var point = res.point.clone();
point.z = 0; // Project on circle plane
var scale = circleRadius / point.length();
point.multiplyScalar(circleRadius / point.length())

[https://jsfiddle.net/c4m3o7ht/]

person stdob--    schedule 18.09.2018
comment
О да, я могу представить себе круг орбиты как сплошной диск. Спасибо, буду реализовывать это и посмотрю, как это работает. - person nnyby; 18.09.2018

Raycaster возвращает все объекты, попавшие под луч ... все точки попадания в мировом пространстве ... (которые вы можете преобразовать в / из пространства модели с помощью object3d.worldToLocal и localToWorld)

Он возвращает расстояния попадания ... которые вы можете отсортировать по любой эвристике, которая вам нужна ...

Обычно я использую mouseDown ... записываю объект и точку ... затем на mouseMove получаю те же точки попадания объектов и применяю операцию редактирования, используя разницу между этими двумя точками.

Ты об этом говоришь?

person manthrax    schedule 18.09.2018
comment
Хорошо, я знаю об этой процедуре. Но в моем случае, в mouseMove, как мне получить точку на желтом круге, ближайшую к положению мыши? - person nnyby; 18.09.2018