カテゴリー: 未分類

SICP

SICP を読んでみる #6 第一章 pp.22-23

本文

反復アルゴリズムに慣れるために両替が例に上がっている。ただ、ここで書かれている日本語がよくわからない(汗。
しかたないので原文もあわせて読みつつ何を言っているのか解釈(実際には不安に思ったところに曖昧さはなかった)。

註33の内容を試しにやってみる。両替を cc 、d を使用する硬貨とすると

(cc d 10)
(cc 1 10) + (cc 5 5)
(cc 1 9) + (cc 5 5) → (cc 1 n) は (cc 1 0) になり、条件より 1 に置きかわる
1 + (cc 5 5)
1 + (cc 1 5) + (cc 5 0) → (cc 1 5) は先の計算の途中にも出て、1 に置きかわる。また、(cc 5 0) は条件より 1
1 + 1+ 1 = 3

という感じ。硬貨の額面金額を取得するために配列が使えないと、それだけで問題が難しくなるような気がする。

問題解答

問題1.11
再帰は簡単。

(define (f n)
	(if (< n 3) n (+ (f (- n 1)) (f (- n 2)) (f (- n 3)))))

反復でやっぱりハマるものの、うっすらといつも使っているループとの対応が取れてきた気がする。
自分の解答は以下の通り。

(define (f n)
    (define (f-iter i v0 v1 v2)
        (cond ((< n 3) n)
                 ((= i (- n 3)) (+ v0 v1 v2))
                 (else (f-iter (+ i 1) v1 v2 ))))
    (f-iter 0 0 1 2))

。。。と思って回答を見たら全然違う(そもそも問題を間違えていた)

(define (fi n)
    (f-iter 2 1 0 n))

(define (f-iter a b c n)
    (cond ((= n 0) c)
            ((= n 1) b)
            ((= n 2) a)
            (else (f-iter (+ a b b c c c) a b (- n 1)))))

ループだとカウントアップしていくのに、反復だとカウントダウンしていく感覚が何だかなじめない。
ただ、確かに数学的にはこっちの方がそれっぽい気はする。
頭の中に値が変化するモデルが組み立てられれば、反復の方が簡潔かつ柔軟に記述できそうな気はする。

SICP

SICP を読んでみる #5 第一章 pp.20-22

問題解答

問題1.9

前者は (+ a b) が (inc (+ (a-1) b)) と展開できるので、a が 0 になるまで繰り返し展開された後で集約されていきます。そのため再帰的。後者は (+ a b) が (+ (a-1) (b+1)) と置き換えられ、a が 0 になるまで繰り返し置き換えられるので反復的。

問題1.10
(A 1 10) は手で何とか展開できたものの、 (A 2 4) は大変すぎるので実行して動作確認しました。
回答っぽいのには辿り着いたけど、2^..^n の計算の仕方が。。。。 f の時って 2n なので、その時でも一般化された (A m n) って成り立つのかがわからない。ざっくりした流れはつかめたので置いておくことにします。

本文

1.1.2 木構造再帰
再帰版の fib は一瞬で書けたものの、反復版でつまづく(というか、今もモヤッとしている)。反復の書き方がどうも慣れない。
明日、反復の復習をします。

SICP, 未分類

SICP を読んでみる #4 第一章 pp.14-20

問題解答

問1.8

これは手を動かすだけ。 improve を式のままに置き換えて終了です。

ちなみに確認用に pow も定義してみました。

(define (pow x y)
	(if (= 1 y)
			x
			(* x (pow x (- y 1)))))

本文

1.1.8 ブラックボックス抽象としての手続き
変数のスコープの話。内部定義とブロック構造で、問1.6の回答で出てきた記法の解説。このようなやり方を静的有効範囲(lexical scoping)という。

1.2 手続きとその生成するプロセス
線形再帰プロセスと線形反復プロセス。最初、二つの例がどう違うのかよくわからなかったものの、if は条件を評価した結果を評価してるだけだから、スタックに積まれるというわけではないという解釈でいいんでしょうかね?普通のプログラミング言語だとどちらも再帰になりそうな気がするんだけど。

P.20 まで本文を読み進めるとまさにそのあたりのことが記述されている。再帰的プロセスと再帰的手続きの違い。

SICP

SICP を読んでみる #3 第一章 p.14 (オマケで環境構築)

問題解答

問1.6

昨日わからなかった問1.6を考えるところから再開。いろいろ考えたもののわからないので、ギブアップして回答を参考にすることにしました。

述語(good-enough? guess x)が真になっても, new-ifは代替部
(sqrt-iter (impreve guess x) x)
を評価しようとするので, 停止しない.

これを読んで納得。

(new-if good-enough? guess sqrt-iter)

ということになるので、 new-if が評価される前に good-enough? と sqrt-iter 両方が評価されてしまうのか。蓋を開けてみれば何てことはなかったです。

問1.7

計算精度の問題。値が小さいときは許容値が相対的に大きくなりすぎて十分計算がされなくなってしまって、値が大きい時は大きな数値間の差を取ることで有効桁数が落ちて許容値以下にならなくなってしまうため、無限ループになってしまう。

プログラムの改良は一応自前でできたものの、解答と照らし合わせると全く知らない記法がされていて目が点。
これは追々やるだろうし、今のところはこんな感じなのねということで写経しながら流れを掴むだけにとどめておきます。

環境構築

そろそろコードをコンソールで打つ(そして無限ループに入って死ぬw)のも辛いので、今日は Gauche+Meadow で動作確認できるように環境構築をすることにしました。

環境構築は”Meadow + Gauche セットアップメモ“を参考。。。というか、そのまま実行。M-x run-scheme で gosh プロンプトが出るところまですんなり行きました。

もうちょっと詳しい使い方も知りたかったので、ひげぽんさんの”関数型言語の勉強にSICPを読もう – (4) 1章 – 小休止 Schemeの環境整備“も参考にいろいろお試し。

.scm は自動で Sceme モードと紐づいているようなので、ファイルを編集し始めた時点でモードが切り替わります。
操作として覚えないといけないのは

  • M-x run-scheme で gauch インタプリタ起動
  • ウィンドウを分割して、一方にソースコード、一方で gauche インタプリタを起動した状態で式の末尾で C-x C-eするとその式を実行

さしあたってこの二つくらい。最初勘違いしていたのが、C-x C-e するとファイル全体が評価されるのかと思っていた点。これは式だけなので気をつける必要があります。ファイル全体を評価する方法も知りたかったですがすぐに見つからず。Meadow を使ってるのに Lisp 周りは全然使ってないのがバレバレですね orz→問1.7の回答を見たら、そもそも一つの式にまとめてしまっているのでファイル全体を評価するという必要がないのかも?うーん。。。それだけじゃ足りないような気もするんですが。

SICP

SICP を読んでみる #2 第一章 pp.12-14

何だかんだ作業していたら夜中になってしまって SICP を読む時間がほとんど取れず。
作業の進捗も大事だけど、うまいこと切り替えないと時間の捻出ができなくなってしまうので、今後対策を考えていかないと。

今回は Newton 法の解説を読みつつコードを写経して動作確認と、問1.6に着手。

問1.6は実際に動かしてプログラムが返ってこなくなることは確認できたものの、なぜそうなるか説明ができないところでタイムアウト。明日また考える。

SICP

SICP を読んでみる #1 第一章 pp.1-12

今日は新幹線の中で読んだ内容のおさらいとして 1-12P を、メモをとりながら読み込み。内容はプログラムの基礎や Lisp の文法、Lisp インタプリタ内での式の評価順序について。

演習問題を確かめようと実行すると無限ループになって帰ってこなくなるような罠が潜んでたり、さっそく Lisp の面白い書き方例が出てきたり。

(define (a-plus-abs-b a b)
((if (> b 0) + -) a b))

なんてのは、実行して理解したら”おおっ!!”という感じがする。

SICP

SICPを読み始めてみた

ずっと昔から読もう読もうと思いつつほったらかしにしていた SICP を今年は読んでみることにしてみました。
#正月、帰省帰りの新幹線内でたまたま読み始めたってのがきっかけなんですが

1.1.6 まで読んだ感じだと、まあ一人で読むこともできそうだなーって感触はあるものの、多分一人で読んだら体力切れで途中で挫折するなーって感じもしているのでちょっと計画を立てつつ完走できるようにしたいなとおもっています。

計算機プログラムの構造と解釈[第2版]は書籍も出ていますが、Web でも公開されています。Web 版は書籍で載っていない問題の解答もあるのでとても助かります。

そんなこんなで動作確認をするために Scheme を実行するための環境構築をしなければいけないんですが、Scheme って言っても結構いろいろあるものなんですね。どれにするかなーとググっていたら正にこの正月から SICP を読み始めたという同志(こっちが勝手に言ってるだけw)を発見。

SICP を読むために Emacs で Scheme 環境を構築

環境構築の内容がものすごく詳細に書かれていて参考になりそうなのでこちらを参考にさせていただきつつ、処理系も Gauche を使うことに。 Gauche は SICP で使われているものとは細かいところで違いがあるようなので、 “SICPを読むためにやっておくと便利かもしれないこと” あたりに目を通しておくといいかも?

ひとまずコードを実行して動作確認をしたいだけなら Gauche を起動すればできるので今日のところはこれで確認するとして、ボチボチ Emacs の連携とかの環境を整えつつ本を読み進めていこうかとおもっています。

未分類

モデリング時の注意点について考察してみた

最近、公私共にモデルデータの綺麗さということについて考えさせられることが結構あったので、自分の勉強のためにモデリングを行う際に注意する点をまとめてみました。自分で検証と考察を繰り返している段階な上に、自分自身は業務としてモデリングを行ったことはないのでこれが正しいとは全く思っていません。むしろおかしいところがあったら教えてください。

ここでは主にムービー用の高精度のモデルを作成することを想定していて、 リアルタイムやローポリゴンのモデルを作成する場合は事情が変わってきます。

※そのため、ここ数日話題になっているシドニアモデルに関してはこの内容は当てはまらないと考えています。トゥーンレンダリングにはそれに合ったモデリング手法があり、それに沿った解釈を行う必要があると私は思います。

Transform ノードの数

Transform ノードの数が多いとシーンファイルのサイズが大きくなったりビューポート上の処理が重くなったりするので、可能な限りモデルはコンバイン(アタッチ)して一まとめにします。

Transform ノードの数による違い

Transform ノードの数が違うとどれくらい影響があるのかを検証するために、Maya で 10000 個の Cube を別々に作成したものと、一つのオブジェクトとしてまとめたものを比較しました。 どちらも Cube を作成後ヒストリーの削除をおこない、ただのメッシュとしたものを 10000 個用意し、上位のグループで回転アニメーションをつけています。ThinkPad T530(Corei7-3720QM/16GB/NVIDIA NVS 5400M) での計測結果です。

タイプ fps メモリ使用量 ファイルサイズ(ma) ファイルサイズ(mb) ファイル読み込み時間(mb) オブジェクトの選択にかかる時間
別々に作成 3.8fps 686.7MB 14MB 11.2MB 15秒 15秒
Combine 130fps 456.9MB 9.3MB 6.1MB 体感上ゼロ 体感上ゼロ

数値化すると激的な違いがあることがわかります。

メッシュ構成

基本

基礎は北田さんの Blog を見るのがいいです

四角形ポリゴン化

モデルは極力四角形ポリゴン化します。

四角形ポリゴンでモデリングする際の参考画像があります。

http://www.pixelandpoly.com/graphics/referenceimages/step-down-guide.png

試しに自分でも同様のモデルの作成をおこなってみました。

三角形ポリゴンがダメというわけではないですが、五角形以上のポリゴンは使用してはいけません。五角形以上のポリゴンは必ず三角形と四角形で構成できるので適切に分割します。

三角形ポリゴンを使用して一番影響があるのは、メッシュにスムースをかけた場合です。

四角形ポリゴンのみで構成されている場合、メッシュにスムースをかけても元のメッシュの形はそのままで間が綺麗に補間されるだけですが、三角形ポリゴンが含まれているとその周りのメッシュがゆがんで補間されてしまいます。

このゆがみが平面上にある場合は大きな影響を及ぼさないですが、曲面上にある場合はメッシュの皺やゆがみとしてレンダリングされてしまいます。

※これは本当?前述の参考画像でもメッシュのゆがみは発生しているので、これをもってNGな原因とするのは根拠が弱くないか?

ポリゴンは平面に

三角形ポリゴンの場合は必ず平面になりますが、四角形ポリゴンの場合は四つの頂点がずれると平面にならなくなってしまいます。誤差が小さい場合は気にならないですが、ずれが大きくなると問題が大きくなってきます。

ポリゴンのシェーディングは法線の情報を使用して行われます。法線はノーマルマップやディスプレイマップのようなものを使用しない限りポリゴン上のどの位置でも同じ値が使用されるため、ポリゴンが歪んでいるとその影響が大きくなります。

※これはちょっと根拠が弱い気がする。面の法線方向が正しくならないほうが問題としては大きい?

面の解釈が曖昧という方が根拠になりそう?

多分、これが問題になるかどうかはレンダラーに依存する。 例えば、Renderman の場合はレンダリング時にマイクロポリゴンにされるので問題にならない。それに対し、レイトレーサーの場合はポリゴンを三角形分割するので、面の状態によって割り方が変わってアーティファクトが発生するかもしれない。

まとめ

私の知識の範囲内でモデリングをする時に気をつける必要がある内容を考察・検証してみました。直観的にこれはマズそうだなーとか、一般的にダメと言われている内容でもキッチリと理論付けしようとすると意外とアレアレッ?と思うことがあります。特に面の解釈についてはレンダラ依存ですしね。

ぜひ、この記事を読んでおかしいところやご自分で検証した内容があれば教えてください。よろしくおねがいします。

未分類

Py3dsMax で undo

Py3dsMax で undo の登録をする方法が以外とどこにも書いてなかったのでメモ。
Py3dsMax モジュールには普段使う mxs モジュール以外にもいくつか登録されているものがあって、そのひとつに undo を管理するための関数があります。

import Py3dsMax
from Py3dsMax import mxs

Py3dsMax.undoOn()
n = mxs.selection[0]
c = mxs.prs()
print n.controller
n.controller = c
print n.controller
Py3dsMax.undoOff(u'test')

結論だけ見てしまえば何てことはない、これだけです。ただ、undoOn/undoOff の使い方はコードを見ないとわからないんですよね(汗

未分類

パノラマ雲台製作中

IBL 素材作成のためにパノラマ機材を購入してパノラマ野郎化した勢いで自動雲台まで作りたくなって、ここ数カ月、細々と設計やら部品調達やらを進めていたモロモロが少しづつ形になってきたのでお披露目。一番のネックだったフレーム部分ができて仮組みしてみました。

制御制御部分は Raspberry Pi を使って、パノラマ撮影+多段撮影による HDR パノラマ撮影まで対応する予定です。サーボとカメラを制御するためのソフトウェア側も大体メドはついているので、あとはパッケージングをどうするかというところです。