Статья в Википедии также смутила меня, когда я прочитал ее некоторое время назад. Вот моя попытка объяснить это по-другому:
Ситуация
Давайте упрощать ситуацию. Мы имеем:
- Наша проецируется точка D (х, у, г) - то, что вы называете relativePositionX | Y | Z
- Изображение плоскости размера ш * ч
- A half-angle of viewα
... и мы хотим:
- координаты B в плоскости изображения (назовем их X и Y)
Схема для X-экранных координат:
E это позиция нашего «глаза» в этой конфигурации, которую я выбрал как источник для упрощения.
Фокусное расстояние е можно оценить, зная, что:
Немного геометрии
Вы можете увидеть на рисунке t шляпа треугольники ECD и EBM являются похожи, поэтому с помощью Side-Splitter Theorem, мы получаем:
MB/CD = EM/EC
< =>X/x = f/z
(2)
С обоими (1) и (2), мы теперь имеем:
X = (x/z) * ((w/2)/tan(α))
Если мы вернемся к обозначениям в статье Википедии, наше уравнение эквивалентно:
Вы можете заметить, что мы пропустили умножения на s_x/r_x
. Это потому, что в нашем случае «размер дисплея» и «поверхность записи» одинаковы, поэтому s_x/r_x = 1
.
Примечание: То же соображение для Y.
Практическое использование
Некоторые замечания:
- Обычно α = 45deg используется, что означает
tan(α) = 1
. Вот почему этот термин не появляется во многих реализациях.
Если вы хотите сохранить соотношение элементов Вы показываете, держать F константу как X и Y, т.е. вместо вычисления:
X = (x/z) * ((w/2)/tan(α))
и Y = (y/z) * ((h/2)/tan(α))
... do:
X = (x/z) * ((min(w,h)/2)/tan(α))
и Y = (y/z) * ((min(w,h)/2)/tan(α))
Примечание: когда я сказал, что «„размер дисплея“и„записи поверхность“одни и те же», что не совсем верно, и мин операция здесь, чтобы компенсировать это приближение, адаптируя площади поверхности г к потенциально прямоугольной поверхности ами.
Примечание 2: Вместо использования мин (w, h)/2, Appunta использует screenRatio= (getWidth()+getHeight())/2
, как вы заметили. Оба решения сохраняют соотношение . Фокус и, следовательно, угол обзора, будут просто немного отличаться, в зависимости от собственного соотношения экрана. Вы можете использовать любую функцию, которую вы хотите, определить f.
Как вы уже заметили на картинке выше, координаты экрана здесь, образованной между [-w/2; w/2] для X и [-h/2; ч/2] для Y, но вы, вероятно, хотите [0; w] и [0; h]. X += w/2
и Y += h/2
- Проблема решена.
Заключение
Я надеюсь, что это будет отвечать на ваши вопросы. Я останусь рядом, если ему нужны издания.
До свидания!
< Самореклама оповещения> я на самом деле сделал некоторое время назад в article о 3D проекции и рендеринга. Реализация находится в Javascript, но ее нужно довольно легко перевести.
Привет! Спасибо за этот действительно информативный ответ! Я попробую :) И спасибо за вашу статью о 3D-проекции! Это действительно полезно для меня;) – Frame91
Можете ли вы объяснить мне, что под углом зрения вы имеете в виду?У меня горизонтальный и вертикальный угол обзора (не проверял, равны ли они), а в статье в википедии также упоминается угол зрения по диагонали (: – Frame91
В представленном мной методе * 2α * является горизонтальным и вертикальным угол обзора (так как я использую меньшую эффективную ** квадратную плоскость изображения размеров * min (h, w) * x * min (h, w) *). Но вы можете настроить его, чтобы использовать ваши 2 значения и весь эффективный экран * w * x * h * вместо этого, если хотите. – Aldream