2008/10/07

画角と解像度の緻密な関係

リアクション: 
今回はメモ的なログで。

元の画像をキープしたまま、画像の見える範囲を広げたい。
と思ったことはありませんか?

ズームアウトで外側の枠だけを広げて2倍の解像度にしたい場合
カメラの画角をどうやって設定したらいいか分かりますか?



『画角を2倍、解像度2倍でいいんじゃね?』

最初は誰もがそう考えるはずです。
ワタクシも疑いませんでした。
だけど、実際は違うのです。

角度を2倍にしたら、見える範囲は2倍になるのは正しいのですが・・・。
なんでかは、あんまり証明できないけれど、実際は違うみたいです。

Mayaには、カメラスケールというものが存在していて、簡単に結果を出すことが出来たりしますが
残念ながら、XSIには、標準でそんなものは用意されていません。

なので、ピッタリ来る計算式を出してExpressionを組んで見ましょう。

中学校でおなじみの懐かしの三角定理を使います。

下図は、トップビューからの図です。



緑の角度 x は、三角定理を使うので元の画角の1/2を示しています。
求めたい赤の角度は x' として、これまた1/2とします。

aは、仮想のプレーンを想像して、そこまでの距離の長さ
bは、解像度の1/2の長さと仮定します。

最終目的はbがn倍になったときに、x' がどのように変化するかです。

まずタンジェントを使います。

tan(x)=b/a ...①

が成り立ちます。

xを出すには、arctanを使います。
アークタンジェントとは、タンジェントの逆関数で、角度とか座標を求めるときに良く使ったりします。かなり便利なので、覚えて置くと◎です。

tan(x) = y のときに、arctan(y) = xになります。

これを利用して

arctan(tan(x))=x

①の式を使って

arctan(b/a)=x

です。
bをn倍したら x' になるので

arctan(nb/a)=x'

になります。なので、また式を戻してみます。

arctan(n・tan(x))=x'

になります。これで、角度の半分が求まります。

結果が求まりました!
XSIのExpressionは、こんな感じでしょうか。

atan(n*tan(Camera.camera.fov/2))*2

ちなみにですが、ソフトによって、tan()は、radianしか入らなかったりするんですが
XSIは、degreeで入ってくれますね。
pythonでコレをやる場合は、radianをdegreeに変換して使いましょう。

import math as m
x=40
n=1.1
m.degrees(m.atan(n*m.tan(m.radians(x/2))))*2

こんな感じですね。
話がそれましたが・・・。

数学って、こんな感じで使うんですよねー。
美しいものです。

こうやって、数学を覚えたりしたら、もうちょっと勉強したんだけどなぁ。
数学って楽しいものなんですよね。

2 件のコメント:

junki さんのコメント...

げげっ。 もうすぐブログに書こうと思ってたネタを先に書かれたっ。 ううむ、うちのマシンをハックしてデスクトップに置いてある Blog_NetaMemo.txt をこっそり読んでませんか garu さんw


ところでさすが garu さん、しっかり数学するんですね。すごく勉強になりますマジで。
俺は数学できません。代数幾何のテストで100点満点中5点をマークしたことがあるのが自慢です。


俺の場合ですが、カメラの Projection Plane をオンにして、Film Aperture の数字に *2 って入力しちゃいます。 すると、勝手に FOV も正しい数字になってません? これを、元の2倍の解像度でレンダリングすればいいと思います。 間違ってたら指摘してください。 たぶん合ってるとは思うんですが・・・。 その方式で「余白作成スクリプト」も書きましたし。

どこで覚えたんだっけな。リンク探しておこう。そのうち自分のブログにも書くでしょう。



皆様お変わりありませぬか。最近寒いっすね。今度日本酒と鍋なんかどうですか。

garu さんのコメント...

あっ。どうも。ハッキングバレマシタカ。
Pythonはこういう使い方も(ry

ハッカーになるならPythonを覚えろが、合言葉らしいです。
ハッカーには興味ありませんがω

なるほどー。Film Apertureを2倍かー。
それ、たぶん合ってます。

すごいなぁ。簡単に出来るんだなぁ。

どうもガチでやってしまう癖がありますねぇ。
時代に取り残されて居ます。

日本酒と鍋いいですね!
やりましょうやりましょう!