Какое лицо дальше в параллельных проекциях?

Я работаю с JavaScript (React) над программа геометрии, который создает аксонометрия (лучше параллельные проекции), указанный объект, определенный по вершинам и граням (лицо может иметь разное количество вершин).

Какое лицо дальше в параллельных проекциях?

Он отлично работает, если вы не используете нужно, чтобы лица были непрозрачными, иначе есть грани выше других, которые должны быть ниже.

Итак, я хочу упорядочить свой список лиц от дальнего до ближайшего:

[
[[100, 0, 100], [50, 50, 50], [120, 170, 120], [10, 200, 150]],
[[10, 20, 30], [10, 200, 250], [50, 50, 50], [100, 30, 30]],...
]

Я буду использовать faces.sort(sortingFunction).

Меня не волнуют пересекающиеся лица

(он возьмет грани всех объектов вместе)

Каким должен быть sortingFunction?

Вы должны учитывать как определяется аксонометрия. Он определяется Вращение по осям X, Y (Xrotation может быть как больше, так и меньше, чем Yrotation), Вращение по оси Z составляет π / 4 (90 °).

Вот старая версия приложения, который дает вам понять, что я имею в виду: http://dev_proiezioni.surge.sh/

Простите за мой ужасный английский. Спасибо

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
0
67
4

Ответы 4

Сортировать по расстоянию от камеры.

function distanceBetweenTwoPoints (p1, p2) {
  return Math.hypot(p1.x - p2.x, p1.y - p2.y, p1.z - p2.z)
}

function sortFunction (p1, p2) {
  return distanceBetweenTwoPoints(camera, p1) > distanceBetweenTwoPoints(camera,p2) ? -1 : 1
}

Измените знак > в зависимости от того, какой порядок вы хотите.

Спасибо, а как мне найти положение камеры в параллельной проекции? А как мне приблизить лицо к точке? Средний?

strategaD 02.10.2018 18:02

Ах, конечно. Не продумала, извините. Я думаю, вам больше повезет с ответами на каком-нибудь сайте Stack Exchange, посвященном математике.

Lazar Ljubenović 02.10.2018 18:05

I don't care about intersecting faces

Это означает, что мы можем уменьшить равнины до точек, взяв точку посередине:

const vecOp = op => (a, b) => a.map((c, i) => op(c,  b[i] || b));

const add = vecOp((a, b) => a + b);
const sub = vecOp((a, b) => a - b);
const mul = vecOp((a, b) => a * b);
const div = vecOp((a, b) => a / b);
 const sum = v => v.reduce((a, b) => a + b, 0);

const middle = (a, b) =>  div(add(a, b), 2);

 const planeToPoint = ([a, b, c, d]) => middle(
   middle(a, b),
   middle(c, d)
 );

Теперь, чтобы отсортировать по «ближе к камере», можно провести линию между центрами двух плоскостей, в результате получится направление:

 const aToB = (a, b) => 
   sub(
    planeToPoint(b),
    planeToPoint(a)
  );

Теперь мы могли превратить поворот камеры в вид камеры:

 const rotToVec = (yaw, pitch) => ([
   Math.cos(yaw) * Math.cos(pitch),
   Math.sin(yaw) * Math.cos(pitch),
   Math.sin(pitch)
 ]);

и это направление можно сравнить с направлением камер, что дает угол между ними:

 const angle = (a, b) => sum(mul(a, b)) / sum(a) * sum(b)

Теперь давайте перевернем это все вместе:

 const camVec = rotToVec(cam.yaw, cam.pitch);

 planes.sort((a, b) =>
  Math.abs(angle(aToB(a, b), camVec)) < Math.PI / 4 /*90°*/ ? 1 : -1
 );

Отказ от ответственности: я не пробовал приведенный выше код, не работал с параллельными проекциями и плохо разбираюсь в математике, поэтому примите мои слова осторожно, я понятия не имею, о чем говорю.

Большое спасибо, но вы заметили, что моя проекция определяется двумерным вращением осей, так как я могу получить cam.jaw и cam.pitch?

strategaD 03.10.2018 14:36

@strategaD, то есть рыскание и тангаж

Jonas Wilms 03.10.2018 18:56

Для приблизительного решения используйте преобразование из 3D в 3D и учитывайте координату Z. Для каждого лица сохраните ближайшую Z и отсортируйте лица по этой Z.

Для более точного решения рассмотрим https://en.wikipedia.org/wiki/Newell%27s_algorithm.

То, что вы пытаетесь сделать, называется "отбраковкой обратной стороны". Один из распространенных методов - определить, находится ли список точек в представлении многоугольника по часовой стрелке или против часовой стрелки с точки зрения камеры. Для этого необходимо, чтобы вы очень внимательно относитесь к тому, как вы создаете список вершин. Подробнее читайте в статье в Википедии: https://en.wikipedia.org/wiki/Back-face_culling. В разделе «Реализация» описываются задействованные математические аспекты, которые вам придется перевести в JavaScript. Обратите внимание, что этот метод быстрее, чем сортировка список лиц, потому что он требует проверки каждого лица только один раз, а не сравнения каждого лица с другими лицами.

Другие вопросы по теме