問題描述
目前我正在編寫一個(gè)增強(qiáng)現(xiàn)實(shí)應(yīng)用程序,但在將對(duì)象顯示在屏幕上時(shí)遇到了一些問題.令我非常沮喪的是,我無法將 gps 點(diǎn)轉(zhuǎn)換為我的 android 設(shè)備上的相應(yīng)屏幕點(diǎn).我已經(jīng)閱讀了很多關(guān)于 stackoverflow 的文章和許多其他帖子(我已經(jīng)問過類似的問題),但我仍然需要你的幫助.
我做了維基百科中解釋的透視投影.
我要如何處理透視投影的結(jié)果才能獲得最終的屏幕點(diǎn)?
前段時(shí)間看維基百科的文章也讓我很困惑.這是我嘗試以不同的方式解釋它:
<小時(shí)>情況
讓我們簡(jiǎn)化一下情況.我們有:
- 我們的投影點(diǎn) D(x,y,z) - 你所說的 relativePositionX|Y|Z
- 大小為 w * h 的圖像平面
- ,我們得到:
MB/CD = EM/EC
<=>X/x = f/z
(2)強(qiáng)>
同時(shí)使用 (1) 和 (2),我們現(xiàn)在有:
X = (x/z) * ( (w/2)/tan(α) )
如果我們回到維基百科文章中使用的符號(hào),我們的等式相當(dāng)于:
b_x = (d_x/d_z) * r_z
您會(huì)注意到我們?nèi)鄙?
<塊引用>s_x/r_x
的乘法.這是因?yàn)?strong>在我們的例子中,顯示尺寸"和記錄面"是相同的,所以s_x/r_x = 1
.注意:Y 的推理相同.
<小時(shí)>
實(shí)際使用
一些備注:
- 通常使用α = 45deg,即
tan(α) = 1
.這就是為什么這個(gè)術(shù)語(yǔ)沒有出現(xiàn)在許多實(shí)現(xiàn)中的原因. 如果你想保持你顯示的元素的比例,保持f對(duì)于X和Y都保持不變,即而不是計(jì)算:
X = (x/z) * ( (w/2)/tan(α) )
和Y = (y/z) * ( (h/2)/tan(α))
...做:
X = (x/z) * ( (min(w,h)/2)/tan(α) )
和Y = (y/z) * ( (min(w,h)/2)/tan(α) )
注意:當(dāng)我說顯示尺寸"和記錄表面"是相同的",這不太正確,min操作是為了補(bǔ)償這個(gè)近似值,適應(yīng)方形表面 r 到潛在矩形表面 s.
注意 2:Appunta 不使用 min(w,h)/2,而是使用
screenRatio=(getWidth()+getHeight())/2
如您所見.兩種解決方案都保留了元素比率.焦點(diǎn),因此視角,只會(huì)有點(diǎn)不同,取決于屏幕本身的比例.您實(shí)際上可以使用任何您想要的功能定義 f.您可能已經(jīng)在上圖中注意到,屏幕坐標(biāo)在這里定義在 [-w/2 ;w/2] 用于 X 和 [-h/2 ;h/2] 表示 Y,但您可能想要 [0 ;w] 和 [0 ;h] 代替.
X += w/2
和Y += h/2
- 問題已解決.
結(jié)論
我希望這將回答您的問題.如果需要版本,我會(huì)留在附近.
再見!
<塊引用><自我推銷警報(bào) > 其實(shí)我前段時(shí)間做了一個(gè) 文章關(guān)于 3D 投影和渲染.實(shí)施在Javascript,但應(yīng)該很容易翻譯.
Currently I'm writing an augmented reality app and I have some problems to get the objects on my screen. It's very frustrating for me that I'm not able to transform gps-points to the correspending screen-points on my android device. I've read many articles and many other posts on stackoverflow (I've already asked similar questions) but I still need your help.
I did the perspective projection which is explained in wikipedia.
What do I have to do with the result of the perspective projection to get the resulting screenpoint?
解決方案The Wikipedia article also confused me when I read it some time ago. Here is my attempt to explain it differently:
The Situation
Let's simplify the situation. We have:
- Our projected point D(x,y,z) - what you call relativePositionX|Y|Z
- An image plane of size w * h
- A half-angle of view α
... and we want:
- The coordinates of B in the image plane (let's call them X and Y)
A schema for the X-screen-coordinates:
E is the position of our "eye" in this configuration, which I chose as origin to simplify.
The focal length f can be estimated knowing that:
tan(α) = (w/2) / f
(1)
A bit of Geometry
You can see on the picture that the triangles ECD and EBM are similar, so using the Side-Splitter Theorem, we get:
MB / CD = EM / EC
<=>X / x = f / z
(2)
With both (1) and (2), we now have:
X = (x / z) * ( (w / 2) / tan(α) )
If we go back to the notation used in the Wikipedia article, our equation is equivalent to:
b_x = (d_x / d_z) * r_z
You can notice we are missing the multiplication by
s_x / r_x
. This is because in our case, the "display size" and the "recording surface" are the same, sos_x / r_x = 1
.Note: Same reasoning for Y.
Practical Use
Some remarks:
- Usually, α = 45deg is used, which means
tan(α) = 1
. That's why this term doesn't appear in many implementations. If you want to preserve the ratio of the elements you display, keep f constant for both X and Y, ie instead of calculating:
X = (x / z) * ( (w / 2) / tan(α) )
andY = (y / z) * ( (h / 2) / tan(α) )
... do:
X = (x / z) * ( (min(w,h) / 2) / tan(α) )
andY = (y / z) * ( (min(w,h) / 2) / tan(α) )
Note: when I said that "the "display size" and the "recording surface" are the same", that wasn't quite true, and the min operation is here to compensate this approximation, adapting the square surface r to the potentially-rectangular surface s.
Note 2: Instead of using min(w,h) / 2, Appunta uses
screenRatio= (getWidth()+getHeight())/2
as you noticed. Both solutions preserve the elements ratio. The focal, and thus the angle of view, will simply be a bit different, depending on the screen's own ratio. You can actually use any function you want to define f.As you may have noticed on the picture above, the screen coordinates are here defined between [-w/2 ; w/2] for X and [-h/2 ; h/2] for Y, but you probably want [0 ; w] and [0 ; h] instead.
X += w/2
andY += h/2
- Problem solved.
Conclusion
I hope this will answer your questions. I'll stay near if it needs editions.
Bye!
< Self-promotion Alert > I actually made some time ago an article about 3D projection and rendering. The implementation is in Javascript, but it should be quite easy to translate.
這篇關(guān)于Android 中的透視投影在增強(qiáng)現(xiàn)實(shí)應(yīng)用程序中的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!
【網(wǎng)站聲明】本站部分內(nèi)容來源于互聯(lián)網(wǎng),旨在幫助大家更快的解決問題,如果有圖片或者內(nèi)容侵犯了您的權(quán)益,請(qǐng)聯(lián)系我們刪除處理,感謝您的支持!