Статията в Уикипедия също ме обърка, когато я прочетох преди време. Ето моя опит да го обясня по различен начин:
Положението
Нека опростим ситуацията. Ние имаме:
- Нашата проектирана точка D(x,y,z) - това, което наричате относителна позицияX|Y|Z
- Равнина на изображение с размер w * h
- половин зрителен ъгъл α
...и ние искаме:
- Координатите на B в равнината на изображението (нека ги наречем X и Y)
Схема за X-екранните координати:
![](https://aldream.net/various/images/projection.jpg)
E е позицията на нашето "око" в тази конфигурация, която избрах като начало за опростяване.
Фокусното разстояние f може да се оцени, като се знае, че:
Малко геометрия
Можете да видите на снимката, че триъгълниците ECD и EBM са подобни, така че използването на теорема за страничен разделител, получаваме:
MB / CD = EM / EC
‹=> X / x = f / z
(2)
И с (1), и с (2) вече имаме:
X = (x / z) * ( (w / 2) / tan(α) )
Ако се върнем към нотацията, използвана в статията в Wikipedia, нашето уравнение е еквивалентно на:
Можете да забележите, че пропускаме умножението с s_x / r_x
. Това е така, защото в нашия случай "размерът на дисплея" и "повърхността на запис" са еднакви, така че s_x / r_x = 1
.
Забележка: Същата аргументация за Y.
Практическа употреба
Някои забележки:
- Обикновено се използва α = 45deg, което означава
tan(α) = 1
. Ето защо този термин не се появява в много реализации.
Ако искате да запазите съотношението на елементите, които показвате, дръжте f постоянно за X и Y, т.е. вместо да изчислявате:
X = (x / z) * ( (w / 2) / tan(α) )
and Y = (y / z) * ( (h / 2) / tan(α) )
... do:
X = (x / z) * ( (min(w,h) / 2) / tan(α) )
и Y = (y / z) * ( (min(w,h) / 2) / tan(α) )
Забележка: когато казах, че „„размерът на дисплея“ и „записващата повърхност“ са еднакви“, това не беше съвсем вярно и мин е тук, за да компенсира това приближение, адаптирайки квадратната повърхност r към потенциално правоъгълната повърхност s.
Бележка 2: Вместо да използва min(w,h) / 2, Appunta използва screenRatio=
(getWidth()+getHeight())/2
, както забелязахте. И двете решения запазват съотношението на елементите. Фокусът и следователно зрителният ъгъл просто ще бъдат малко по-различни в зависимост от съотношението на екрана. Всъщност можете да използвате всяка функция, която искате, за да дефинирате f.
Както може би сте забелязали на снимката по-горе, координатите на екрана тук са определени между [-w/2 ; w/2] за X и [-h/2 ; h/2] за Y, но вероятно искате [0 ; w] и [0 ; h] вместо това. X += w/2
и Y += h/2
- Проблемът е разрешен.
Заключение
Надявам се това да отговори на вашите въпроси. Ще остана наблизо, ако има нужда от издания.
Чао!
‹ Сигнал за самореклама > Всъщност направих преди известно време статия за 3D проекция и изобразяване. Изпълнението е в Javascript, но трябва да е доста лесно за превод.
person
benjaminplanche
schedule
23.05.2013