アニメーションCAD

Page 1

U8712 早稲 田 大 学 理 工 学 部建 築学 科 卒 業論 文 指 導教授 渡 辺仁 史

ア ニ メー シ ョ ンCAD 荒木和彦

Department of Architecture,School of Science and Engineering, Waseda University



昭和52年 度卒業論文

アニ メ ー シ ョン CAD

早 稲 田 大 学 理工 学 部 建 築 学 科 指導

62,10131

綿ガ 薇

渡辺

仁史

G4D006 荒本和彦

教授


目次

はじめに・

000・ ●●●●¨●●●●●●●0●

研究目的・・・・ 研究概要・・・・ 研究背景・・・・

0●

●●●● ・ 000・

0000000・ 0・

0●

●●●●o2 00・ 3

0・ ・・・・・・

0・ ・・・ ・・・

00・ 00・ ・ 00・

0・

●●●●●o4

00・ ・・・・・ 5

「動 く平面図」の製作 建築における可動部・ 000・ ・・・

0000・ ・・ 0・ ・・・6

ドアの分析・・ 0,0° °°°°0・ ・・・・・

00000000

「周辺」の分析・ 00・ ・ O o● ●●●●●●●●●…

0●

r動 く平面図」のプログラムについて・ 00・ ・・・ 00・

『動く平面図 Jの 評価・ 00・ ・・

0000・

00‐ ・

o O●

・12

0・

13

●●16

0AMヨ 闘日・ ・・・ 0 ・ 0 0 ・ 0 ●●●●●●●●o ●o ●o ●●17 あとがき 0・ 0,00● ●●●●●●●●●●●●●O o● ●●●1ロ 確 プログラム・ リス ト・・・・・・・ ・ ●0● ●●00●

0●

・・ 19


は囃 の分野におttて もコンピューターの利用―

である。これは主にドラフティングの自動

―いう目的が大きい.無論、これも重要なコンピューターの仕事である。が、同時に の 化と 最近 状況からす れば、コンピューターはより高度な面において設計作業の補助を行ないうるのではなかろうか。また、仮 にそうだとして具体的にはどのような形でだろうか。 このような点に興味を持つたのが、そもそもこの研究を始めたきっかけである。

“4


研究目的 実際の建築の中には 、さまざまな部分に可勁部 ―

して いる。しかし、従来の設計作業にお いて、そ

れら¬ 覗剛拙ま他の動かない部分と同様に、僣止した形としてしか平面上に表現されえなかつた。 そこで本研究では、建築の設計を支援させるべく、コンビューター・アニメーションを利用して、可動 部分の使いやすさ、安全性などの評価・チェッタを行なえるような「動く平回凶」を作つてみるのが目的 である。

3


… 建築のなかで、可動である部分は、ドア、窓など、開口部を仕切るものにその多くを見い出すことがで きる。 不動の物体である建築のなかで、「可動であるJと いう性質は一体どういう意味を持つているのだろう か.つ まり、可動部の存在意義とはなにかということについて、特にドアに目を向けつつ、考察してみる。

″ 開き戸・引き戸、片開き・両開きなど、ドアにはいろいろな種類があ り、それらについて分類を行なつ てみる。 また、特にそれらが人間によつて操作される状況を考え、可動であるがゆえのさまざまな動的特性につ いてみても考察 してみる。

‐ 騒

■タ

「周辺」とは、壁であるとか家具であるとかの、ドアのまわりに配置されるさまざまな構成部材である. これ らの配置によつては、ドアまわ りの使いやすさや安全性に悪い影響が出てくる。 これらの構成部材をリス トアップし、また ドアの動的使いやすさ・動的安全性との関わ りについて考察 してみる.

/2/7 Z″ 「 ドアの分析 Jと 「『周辺 Jの分析 Jに よつて得られた知識を基に「動く平面図」プログラムを作成し、 評価・肺

る。

4


¨ 運染准

リ コン と

"〃

'づ

現在、建築の計画を ―

舛 4動 財 /_― /― ション タ

"η

魏筈

る上においては、コンピューターの利用が、特にコンピューター・エイデッ

ド・デザインという形によって広まっている.こ れは、コンピューターの力を利用 し、主にドラフティン グやパースの作図などにおける単純・正確かつ大量な作業を代替させることに、その主眼をおいたもので ある。 しかしながら、シミュレーションを利用 した空間設計であるとか、パラメトリック・デザインによる建 築計画などによって、新 しい形のコンピューターの利用の方法が開かれつつある.こ れらは、労力の軽減 という従来のコンピューターの利用法を越えて、より人間の知的な面に関しての作業の補助を行なうこと を目的としている。つ まり、従来の物言わぬコンピューターから、物を言 う、さまざまな提案をしてくれ るコンピューターヘ とその利用法を移そうとしている. そのようなコンピューターの利用法の新たな一つ として、コンピューター・ アニメーションの利用が考 えられる。 写真と映画の比較を持ち出すまでもなく、動的映像の持つ訴求力には大きなものがある。それは無論、 単純な動的映像の優位性につながるものではない。動的映像は、さまざまな面で静的映像と異なつた特質 を持つてお り、その特質を活かした利用を行なうことによつて初めて、静的映像にない魅力を持ちうる。 建築は静的な物体であ り、動的映像をその表現に活用することは難 しいという主張は、それな りに論理 的整合性を保持 していると考えられる。しかしながら、不動の建築といえどもそれを利用するのが動的た る人間である以上、その建築と人間の動的な関わりに焦点を当てるならば、動的映像の利用価値は充分に 考えられる. あるいは、現在も依然として残つているコンピューターとユーザーの間の障壁というものを取 り除く試 みにも、動的映像の有用性は認識されてしかるべ きであろう。 つまるところコンピューター・アニメーションとは、コンピューターの新 しい物の言い方である。新し い表現力を得たコンピューターは、従来表現 しえなかつた新 しい提案を行なうことが可能になるはずであ る。では、実際に何が可能になるのだろうか。当研究はその部分を追及 しているわけである. しかし同時に、これは単なる一例に過ぎないという点 も明記する必要がある.も つと斬新なコンピュー ター・ アニメーションの応用が、全く別の視点から開かれる可能性は充分に考えられる。その際に必要に なるのは、むしろコンピューターとい うものに全く拘泥されない、自由な視点であろうことも記 しておか なければならない.

5


「動 く平醐

」α凝 作

鰈 における 覆 笏 建築において可動である部分 とい うのはかな り見受けられ るものであつて 、例えば ドア・窓は言 うに及 ぼず、エ レベー ター・エスカ レーター 、種 々の小物、それに設備系統の可動物を含めれば、実際主だつて 用 いられるものだ けでも、相 当な種類のものがあるのではなかろうか。 その上一部の建築家によつては、床や階段などを可動にする例 もあ り、意外に可動部は大きな意味を持 つているということが知 られ る。 建築計画にお いて、それ ら可動部の中でも特に ドアの果たす役割には大きなものがある.な んとなれば、 窓 とドアが計画上において占め る割合は、他の可動部に比 して も大きなものがあ り、また ドアの重要性は 窓におけるそれ と比べても、そこを人が通るとい う点 を考えれば、よ り大 きいとも考えられるか らである. そこで、当研究では主にドアについて焦点を当て、調査 してみることとした.

ドアが可動であるというときに、可動とはどういうことなのかを考える。少なくともドアは、それ 自身 が動くことによつて何らかの働きをするものではない。 (扇 がそれ自身の動きによって「風を送るJと い う働きを行なうことと対比される)。 では、なぜ ドアが可動でなければな らないかというと、それは開い ているという状態と閉しているという状態との二種類の状態を、一つの物体が採 りうる必要があるからで ある。 そこで、可動であるということは即ち、数種の状態を採 りうる物体であるということが知れる。そして、 ドアといえども空間構成要素の一部分である以上、ドアの状態が二種類あるということは、そのドアが属 する空間自身が二種類あるということにもなる。 例えば、ドアが閉していることにより心理的囲まれ感のある閉空間が現出し、開いていれば開放的空間 となる.あ るいは、ドアが閉していれば空気や日射の流通しにくい空間とな り、開いていれば外気・ 日射 の豊かな空間となる.こ れらは ドアに限らず、窓などについても言えることである. 逆な形で言えば、このような二面性を持つ空間を同一空間内に併存させるために、ドアのような可動部 が必要になるとも考えられる。 また ドア特有の要件として、それが閉じられていれば人間の流通を遺断し、開かれればスムースな流通 が可能になるという点が挙げられる。無論、遺断といつても一時的なものであり (固 定的に閉鎖されてい なければの話だが )、 ある種の障壁として作用すると考えられよう。 この点に関して言えば、ドアの状態の二面性が空間全部の性質を変節させるとは考えられないわけであ る。つ まリドアに関して言うならば、人間の流通路近辺を中心とした空間においてのみ、通 りやすい 。通 りにくいという性質の変化が起きるわけである。

6


従 つて、可動暉の状態の変化に伴 つて影暮をこうむる空間の範囲は、どういう点において影響をこうむ るかという、そのどういう点の種類によつて、さまざまであると考えられる.ど の性質がどの範囲の空間 ま―

を与えるかということは、可職部を研究する上で重要であると思われる。


まず、 ドアはその開閉方法か ら大きく二種に分類 される。開き戸 と引き戸である.開 き戸は■点を中

,hL

L(Fa ElkatS :

L

03

\

J D, Fofrtrfra> 引 きF

を行なうものである.ま た引き戸は、戸を水平移動 させることによつて、戸の開け閉め を行なうものである。この二種以外 のものは、実用上ほとんど使われて いないものと考えられる。 開き戸・引き戸は、更に細かい種 類にそれぞれ分類できる。ここに示 したのはその一例である.

ところで、これらのドアはそこの ソ

人間の通行にどのような影響を及ぼ

π 葛FF][『

:り 出し

しているのだろうか。あるいは逆に、 人間の通行によつてどのような影響 をこうむつているのだろうか. おこ│き ドアの状態には、「 開いている」と「閉 している」の二種類あ

る晴 つた。従つてその状態の遷移には、順列組み合わせから 「開いている」まま 「開いている」→「 用 している」

3撻 い

「閉して いる」→「 開いている」 「閉して いる」まま の四種類あることになる。 「開いているまま」・「閉しているまま」といつた場合には、無論人間の操作が行なわれな いことを示 しているのだから、動的な意味での人間とドアの関わ りはな い ものと仮定される.そ こで、ドアが開く場 合 とドアが閉 じる場合 との二つの場面を考えればよいとい うことが知れる。

まず、引き戸、それも最も明解な形である片引き戸について考えることにする.

8


引き戸に関しては開け方・閉め 方についてあまリバ リエーション

― ―

聞める とき

開 け るとき 一

があるわけではない。基本的には まず扉の前に接近 し、取 つ手に手を掛けて開 けたり閉めた りを行なうわけである。 この場合、例えば扉を開ける場合には開け る方向の反対側の端に体の同じ側の端がそろ うように、また閉める場合には閉める方向側 FlaHlち ぃ、

の端に体の反対側の端がそろうような形に扉

五誠劇 、4t′ 僣ヽ。

に接近 していくのが、多いパターンである. これは、扉を動かす方向と反対側にある手を使 うことによつて、 動かせる距離を最大限に取ることを意図していると思われる。 ただ結果的に、引き戸に開閉操作を行なうエ リアは扉の全幅以 内におさまることになる。

次に、開き戸について、特に片目き戸を取 り挙げて考えてみる。 開き戸は引き戸と違 い、押 しながらの開閉操作と引きながらの開閉操作の二種のバ リエーションが存在 する.開 く 。閉じるの場面の違いから、順列組み合わせによって 押 しながら開ける 引きながら閉める 押 しながら閉める 引きながら開ける という四種のパターンを示すことができる。 次に、それぞれのノヽターンについてより詳しく考察 してみる。 ◆押しながら開ける場合 まず人間は扉前面のエ リアに接近 し、取 つ手を掴んだ後、静止 しながらかあるいは前進 しながら扉を向 手側に回転させて開扉状態を得るわけである. この場合扉前面のどのあたりに接近する かというと、回転軸の反対側の端に体の同 じ側の端がそろうような感じとなる.こ れ は、ちょうど引き戸と同じ理由が考えられ


る。つまり、最大限の可動範囲を得るためである. また、これがゆえに押しながら開ける場合の人間の操作エ リアは、扉の回転軸の反対側の端からちょう ど曲げた手が届く範囲 (扉 が操作可能な範囲)に なる。 ◆引きながら閉める場合 これはち ょうど押 しなが ら開ける場合 と反対の形で ある。人間は扉の前面を通 ―

り、取 つ手を掴んで引きな が ら戸の閉る方向へ と回転 させるわけである。

:取 つ手却 む

2扉 鰯

師 │き ながリ

に出 乙 ト

3取 っ手狙

この場合 、取 つ手を掴む ことので きるエ リアが操作領域に入るのは勿論であるが、閉めを行な つて いる最中に多 くの場合人間は動 いていて、閉め終わつた時点ですでに扉の外側に大きく出ているケースが多い。 また、引く動作をする場合には押す場合 と違 つて腕を伸ばしきつていて いいわけであるから、最終的な 操作エ リアは 取 つ手を掴むエ リア十掴みながら動 くエ リア十取 つ手から伸ば した腕が届 く範囲

となり、かな り大きなものになる。 ◆押しながら閉め る場合

___

これはさらに扉の正面で操作をす

´

´

る場合と扉の横で操作を行なう場合 との二種に分類される。 まず正面の場合だが、取 つ手を綱 み、静止ない しは動きながら扉を押 して閉扉状態を得るわけである。こ

業ふ3聞 ぃ3

の操作を行なうエ リアは扉の正面付 近に限られる。 次に横で操作する場合だが、まず 扉の回転範囲の外側に立ち、取 つ手

付 硫

相R訥 留Tす る胎

ないしは扉の端を直接持つて水平移 動 させ、扉を開めるわけである。無論扉の回転範囲の中に入 つては操作に支障が出るのでこの部分は操作 範囲から除去 される。

lC


どちらの場合 も押け動作なので、曲げた手の届 く範囲が操作エ リアと考えられる。 ◆引きながら開ける場合 この場合はまず、扉の回転範囲の外側

に立ち、次に取 つ手を引いて扉 を開ける わけである。前項同様に扉の回転範囲の 中に入 つては操作に支障が出るのでこの

1… 2日 肘る

部分は操作領域か ら除去され る。

結局の ところ、扉の開目の前提としてその扉固有の操作領域に入 つてから開け閉めを行なうということ になるわけである。従い、この操作領域を狭めるような何らかの作用 というのは即ち、扉の使い勝手・安 全性などに悪い影響を与えるものと考えられる。

■1

■日


「畔

」嚇

『周辺 Jと は、主に ドア近辺に置かれるであろうさまざまな物体である.主 だ つたところで壁・柱など の建築構造材、衛生陶器・流 しなどの作 り付けの設備、移動可能な家具などが挙げられる.ま た、階段や 他の ドアの操作領域 とい うもの も「 周辺 Jの 中に含まれる。 「周辺 」が直接 ドアの操作領域の 中に配置されることは、かな りの使い勝手の悪化を招 くものと思われ る。従 つて、例えばコンピュー ターで平面計画をチェックする場合でも、このような配置についてはいき な り警告を出しても許容 されると考 える。 しか し、直接 ドアの操作領域の中に配置されなくて も、使 い勝手のよくな い場合は考えられ る. 例えば便器など、心理 的にある程度の距離を保 つて行動 した い物体とい うものがある。こうい うものに ついては平面上で ドアとの間に距離があつても実際には圧迫感を感 じるとい うことも考えられ る。 あるいは扉の付 いた家具など他の物体とある程度の距離を置 きたい ものも、ドアとの相互の関連におい て使いづ らさを出して くることが考えられる. 人間にはパーソナル・スペース とい うものがあ り、人間相互の距離からそれぞれの空間的 興 力珊造 ら れているわけである.し かし物にも同様にそれぞれのパーソナル・ スペース とい うものがあって、そのお 互 いの関連の中から空間の性質が形造 られるとは考えられないだろうか。 無論この点について正確を期すな らば、今後の研究を待たなければならない。

12


「動く平面図」のプログラムについて

現在完成 しているプ ログラムは、前記の研究を基に決定された「 アニメーションCAD」 の仕様の、一 部 の機能を実現 したプ ロ トタイノ Cあ る. 「 アニメー ションCAD」 においては基本的に三つの機能が備わ つている。

1.CAD機 能 2.ロ ールプレイング機能

3.エ ラーチ ェッキング機能

CAD機 能とは、コンピューター上に建築計画を設定する機能であ り、ぃわゆる他の CADの 機能とそ んなに異なるものではな い。 ロールプレイング機能 とは仮設的な名前であるが、コンピューターの画面上に、平面図と共に人間を表 わす図形を投射 し、その図形をいろいろに動か してみることによつて、仮想的ではあるが空間内部を疑似 体験 してみる機能である。 エ ラーチェッキング機能とは、平面計画について何 らかの不都合な状況 を発見 した時に、警告 と提案を 行な う機能である。

Ed:t

Rn:rrlation cnD

圏圏

13


Rnirrlation cnD

圏 菫翻

CAD機 能

AnirTlation CAD

ローJL7レ イング機能

14


nnirrtatiOn CnD

Human is feeling uneosg.

It is recommended to change an

arrangement.

エ ラーチェック機能

15


『動く平面図」α用栖

プロ トタイアであるので完全な評価はできないが、実現された機能を見る限りでは当初の意図に沿つた ものとなつた。つまり可動部たるドアについて、それがリアルかどうかは別としても従来にない消化しや すい形でプレゼンテーション・ 検討することができている。 また予想外な点として、平面計画そのものについても新しい手法のプレゼンテーション手段となつてい る点が挙げられる。これは、ロールプレイング機能に負うところが大きい。 考えてみると、従来のアレゼンテーション手法というのは平面図にしろパースにしろ、情報としては向 こうからこちらヘー方通行で流れてくるだけであつた。しかし、こちら側から向こう側へ何らかの形で働 きかけをしうるプレゼンテーシ ョン手法は、その有効性が以前から訴えられているにもかかわらず、なか なか実用化されていない。はからずもこのような形でその有効性が実証されたのは思わぬ収穫であつた。

■日


… まずエ ラーメッセージ機能だが、単に悪い計画に対して警告するだけでなく、その時点その時点での人 間の心理的状態が細かく分かるようになれば、より人闘 心理に沿つた設計ができるようになるはずである。 この機能を実現するためには、空間内における人間心理を定量・数値化できる理論が解明されていること 燿 ましい. また、現在ではロールプレイング機能によつて人間一人が建築内空間をうろつ くことができるが、実際 の建築同様複数の人間が同時に内部にいればより正確なシミュレーションとなる。この場合、他の人間を コンピューターがコントロールするならば、コンピューターが正確な人間行動の規定法則を保持している ことが必要である。 さらに、平面のみならず立面や透視図においてロールプレイング機能が実現されれば、もつと別のシミ ュレーション世界が展開されるであろう。 このようにして、まず第‐には従来捉えづ らかつた建築の動的特性を最適化するシステムに展開され、 第二に建築内空間の疑似体験システムヘ と展開され得る。

一J ■日


あとがき

この論文を書 くに当たつて研究室の ドクター・ マスター 。そして他の卒論生の皆 さん、それか ら渡辺先 生、さらに他の大勢の方のご協力を頂きました。本当に感謝 しています。あ りが とうございました.

CC ■ロ


個 プログラム・ リス ト

■︰


AnimationCAD.Rsrc

Type DM01=STR ,0

Demo Program

Version

Type BNDL ,1100

E)M01 0

1CN# 0 1100

REF

0 1100 Type FREF ,1100

APPL O

Type ICN#=GNRL ,1100

H

1「 FFFFFF

80000001 80000001 80000001 FFFFFFF 「

80000001 80000001 80000001

80000001 80000001 80000001

80000001 80000001 80000001

FFFF世

‖H躍 士Tリ

1「 FFFFFF

80000001 80000001 80000001 rⅢ

80000001 80000001 80000001 …

Ш

0.11‐ ‐ 25

0ct 87


80000001 80000001 80000001 FFFFFFF

80000001 80000001 80000001

* below is the mask FFШ F 「 FFFFFFF 「 FFFFFFF 「 I「 FFFFFF FFFFFFF 「 FFFFFIF 「 FFFFFFF 「 I「 FFFFFF I「 FFFFFF FFFFFFF 「 FFFFFFF 「 FFFFFFF 「 FFFFFFF 「 FFFFFFF 「 II「FFFFF I「 FFFFFF IFFFFFF 「 FFFFFFF 「 I「 FFFFFF Щ FFFF 「 I「 FFFFFF FЩ Ⅲ 「呻 ‖ F 「 FFFFFFF 「 FFFFFFF 「

則 中

…」幽 「

FFFFFFF FFFFFFF 「 I「 FFFFFF I「 FFFF‖ FFFFFFF 「

Type WIND ,1000

Animation CAD 44 7 335 505 Visible GoAway


4 0

Type DLOG ,1000“ )

About AnimationCAD 90 50 180 460 Visible NoGoAway 16 0

1000

Type DITL ,1000

2 Btnltelm Enabled

60 167 81 244 ∝

StatText

Disabled

5 10 60 400 AnimationCAD Prototype Na・ughtyright

n

by KoARAKI

Version D++ 1987 \D++

Type MBAR=GNRL ,1000 ・

I

2

1000 1001

Type MENU ,1000

ヽ14

About AnimationCAD:.. (‐

,1001

Edit

Quit/Q

Tpe m=GNRL ,1000


* hereOs the data

07EO 1818 300C 6006

4422

8421 8421 8001 8001 9819 8C31 47E2 6006 300C 1818 07EO

* here's the mask

0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000

* hereos the hot spot

0008 0008

Type CURS=GNRL H

,1001

* here's the data

07E0 1818 300C 6006


4422

8421 8421 8001 8001 9819 8C31 47E2 6006 300C 1818 07E0

* here.s the mask

0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000

* heE.s the hot spot

0008 0008

t肝

,10010o 50 50 150 450 1001

5555

type D職 2

,1001

staText Disabled

10 10090 300 Ilunrn io foeling nncasyAD++


It is recommended to to change an arrangment

Button 20 300 40 350 �


program AnimationCAD; { purpose

prototyping AnimationCAD

}

︲ ︲

{$I‐ }

{ Turn offrange checking { Turn off VO error checking

{$R‐ }

{$B+} { Set bundle bit (for icon, etc.) {$R AnimationCAD.Rsrc} { Identify resource file {$T APPLDM01} { Set application ID {SU‐ } { Turn off auto link to runtime units

uses

PasInOut, Memtypes, QuickDraw,O

S

Intf,ToolIntf, Packlntf,FixMath

const

ApplMenu = 1000; { resource ID of Apple Menu EditMenu = 1001; { resource ID of Edit Menu ACADMBaT =

}

{ resource ID of Menu Bar

1000;

MainID = 1000; AboutID = 1000; MouseID = 1000; MouseCursor = 5; HumanID = 1001; HumanCursor = 6; UneasylD = 1000; bax )

}

}

MainWindow box }

resource ID for resource ID for dialog

{ {

}

ID for Mouse Cursor } aray index for Mouse Cursor }

{

resource

{

{

{

resource ID for Human array index for Human

{

resource

Cursor Cursor

ID for "feeling uneasy"

} } alart

type

= array[iBeamCursor..HumanCursor] of = ^integori = ^str255;

Cursorl-ist Ptrlnteger PtrString

var :

Finished

program ) Ticks theEvent system )

:

Boolean;

CursHandle;

{ used to terminate

the

Iongint;

{ keeps track of time } : EventRecord; { event passed from

operating

;


{ Screen stuff}

DragArea : Rect; { in )

defines area where window can be

dragged

GrowArea

: Rect;

size can change ) ScreenArea : Rect;

Curslist

{

{

{

defines area

to which a window's

defines screen dimensions } { used to hold cursor handles }

: Cursorlist;

Menu stuff}

Menulist : Handle; { holds menubar info } DAMenu : MenuHandle; { holds applemenu's position } {

Window stuff } MainPtr : WindowRr;

l

MainRec

{

: WindowRecord;

pointer to main window } { holds data for main window

MainPeek : WindowPeek; { pointer to MainRec

} ScreenPort : Grafftr; { pointer to entire screen } FrontWindow : WindowRr; { pointer to active window }

{ 'r****

declaration

for

AnimationCAD contents

*****

const

hWallMax = 3; { total # of holizontd walls } vWallMax = 3; { total # of vertical walls }

2i { total # of funitures } DoorPat = 23i { total # of door pattarns FunitureMax =

}

inSpace = 1; { function results } inhWall - 2; { function results } invWall = 3; { function results }

inFuniture = 4i { function results } inGrowHW = 5; { function results } inGrowVW = 6i { function results }

7t { function results } inDoor = 8; { function results } inGrowF radian =

=

3754936; {

57.2958

degree }

type

Doorlist

= Record

area

: Rect; oparating : Rgnllandle; now : Integer; inbetween i anay [0..DoorPat] of PicHandle;

}


from,

angle

: Integer;

End;

var

hWdl

walls )

vWall

: arrayfl..hWallMax] of Rect;

{

holds position of h

: array[l..vWallMax] of Rect;

{

holds position of v

walls )

)

Funiture : arrayfl..FunitureMax] of Rect; {

Door

ditto of funitures

Doorlist; { holds data of door } function WhatObject(MousePoint : Point) :INTEGER; t purpose get kind of object (wall, funiture, ect...) :

on which mouse is pointing

) var LoopCount : INTEGER;

DragBody : Rect; begin WhatObject := inSpace; for LoopCount := I to hWalMax do if PtlnRect(MousePoint, hWall[LoopCount]) then begin DragBody := hWallfl.oopCount] ; InsetRect(DragBody, 10, 0); if ftInRect(MousePoint, DragBody) then WhatObject := inhWall else

WhatObject := inGrowHW; end;

for LoopCount :=

if

I

to vWallMax do

PtlnRect(MousePoint, vWall[LoopCount]) then begin DragBody := vWall[.oopCount]; InsetRect(DragBody, 0, 10); if PtlnRect(MousePoint, DragBody) then WhatObject r= invWall

else

WhatObject != inGrowVW; end;

I to FunitureMax do PtlnRect(MousePoint, FuniturepoopCountl) then begin DragBody := FuniturelloopCount]; InsetRect(DragBody, 3, 3)i

for LoopCount :=

if


if

RlnRect(MousePoint, DragBody) then WhatObject := inFunitrue

else

WhatObject := inGrowF; end;

if

PtlnRect(MousePoint, Door.area) then WhatObject := inDoor; end; { of function WhatObject }

function WhichObject(MousePoint :

Point;

What : INTEGER)

INTEGER;

{

purpose

get index # of object (wall, funiture, ect...) on which mouse is pointing

) var LoopCount : INTEGER;

begin IrcopCount := 0i case What of inhWall,

inGrowHW : rcpeat

LoopCount := LoopCount + 1; until PtlnRect(MousePoint, hWdl [LoopCount] invWall, inGrowVW : rcpeat LoopCount := LoopCount + l; until RlnRect(MousePoint, vWall lloopCount] inFuniture,

inGrowF

:

);

);

repeat

LoopCount t= LoopCount + 1; until ft InRect(MousePoint, Funiture [LoopCount]

end;

{ ofcase }

WhichObject := LoopCount; end; { of function whichobject }

function AGL2IBW(Angle: Integer): Integer; begin AGL2IBW := Angle end;

*

(DoorPat

procedure DrawWContents(WPtr

{ )

purpose

+ l) div 360;

:

WindowPtr);

clears window.

);

:


var

TRect

: Rect;

LoopCount : INTEGER;

begin if (WPtr = MainPtr) and (Wptr

:

FrontWindow ) then begin clear rect area of window }

EraseRect(WPtr^.portRect); { for LoopCount :=

I

to hWalMax do

FillRect(hWalllLoopCount], Black); { draw virtical walls } for LoopCount := 1 to vWalMax do FillRect(vWall[LoopCount], Black); { draw holizontal walls } for LoopCount := I to FunitureMax do FillRect(Funiture[LoopCount], Gray); { draw funiture } DrawPicture(Door.inbetween[Door.now], Door.area); end

end;

{

of proc DrawWContents }

procedure DragObject(Whafi INTEGER; Which: INTEGER; WRr: WindowPtr; MLoc: Point);

{

pu{pose

drag a object

) var ObjectRr

:

^Rect;

WorkRgn : RgnHandle; LimitRect, SlopRect : Rect; Distance : LONGINT; hDistance, vDistance : INTEGER;

begin WorkRgn := NewRgni LimitRect := WPtr^.portRect; SlopRect := DragArea; case What of inhWdl : ObjectPtl ;= @hWall[Which]; invWall : ObjectRr ;= @vWalllWhichl; inFuniture : ObjectPtr ;= @Funiture[Which]; end; { of case } RectRgn(WorkRgn, ObjectRr^) ; Distance := DragGrayRgn(WorkRgn, MLoc, LimitRect, SlopRect, noConstraint,

NrL); vDistance := HiWord@istance); hDistance := LoWord(Distance); if (vDistance <> -32768) and (hDistance <> -32768) then begin


EraseRect (Obj ectPtr ; ^)

OffsetRect(ObjectPtr^, hDistance, vDistance) ; DrawWContents(WPtr); end; { of if clause } DisposeRgn(WorkRgn); end; { of procedure DragObject }

procedure GrowObject(What,Which: INTEGER; WPrr: Windowptr; MOridinal: Point);

t

purpose

resize object size

) const

inIJft

inRight

= 1;

= 2; inTop = 3; inBottom = 4i inCorner = 5;

var

MNow

: Point;

ResultBody, DragBody,

GrowBody : Rect; WhichCorner, dh, dv : INTEGER;

ObjectRr : ^Rect;

begin case What

of

inGrowHW : begin ObjectRr ;= @hWalllWhichl DragBody := ObjectRr^;

;

InsetRect@ragBody, 10, 0); if Moridinal.h < DragBody.left then WhichCorner := inleft; if MOridinal.h > DragBody.right then WhichCorner :=

inRight; end;

inGrowVW : begin ObjectRr ;= @vWalllWhich] DragBody := ObjecrRr^;

;

InsetRect@ragBody, 0, 10); if Moridinal.v < DragBodyJop then WhichCorner := inTopi if Moridinal.v > DragBody.bottom then WhichCorner :=

inBottom;


end;

inGrowF

: begin ObjectPr ;= @FuniturelWhichl; DragBody := ObjectRr^; InsetRect@ragBody, 3, 3); if MOridinal.h < DragBody.left then WhichCorner := inkft; if MOridinal.h > DragBody.right then WhichCorner :=

inRight;

if Moridinal.v < DragBody.top then V/hichCorner := inTopi if Moridinal.v > DragBody.bottom then WhichCorner := inBottom; end;

end; { of case } repeat PenPat(gray);

GeMouse(MNow); dh := MNow.h - MOridinal.h; dv := MNow.v - MOridinal.v; with ObjectPtr^ do case WhichCorner of inleft : begin SetRect(ResultBody, left + dh, top, right, bottom); FrameRect(ResultB ody) ; end;

inright

: begin SetRect@esultBody, left, top, right + dh, bottom);

FrameRect(Re sultB ody) ; end; : begin

inTop

SetRect(ResultBody, left, top + dv, right, bottom); FrameRec(ResultB ody) ; end;

inBottom

: begin SetRect(ResultBody, left, top, right, bottom + dv); FrameRec(ResultB ody) ;

end;

end; { of case } EraseRect(ResultB ody) ;

until not StillDown; PenNormal; if not EmptyRect(ResultBody) then ObjectRr^ := ResultBody; DrawWContents(WPtr); end; { of procedure GrowObject }

procedure MoveDoor(MOridinal: Point; DoorOridinal: Integer);

{


purpose to open/close door ) var

MNow

: Point; MNAngle, MOAngle, DifAngle: Integer; FromNo, ToNo, DoorNo : Integer;

begin PtToAngle(Door.area, MOridinal, MOAngle); FromNo i= AGI2IBW(Door.from); ToNo := AGL2IBW((Door.from + Door.angle)); repeat EraseArc (Door. area, Do or.from, Door. angle) ;

GeMouse(MNow); ftToAngle(Door.area, MNow, MNAngle) ; DifAngle := MNAngle - MOAngle; DoorNo := Doororidinal + AGI2IBW(DifAngle); if DoorNo < FromNo then DoorNo := FromNo; if DoorNo > ToNo then DoorNo := ToNo; while DoorNo < 0 do DoorNo := DoorNo + (DoorPat + 1); DrawPicture(Door.inbetween[(DoorNo mod (DoorPat + 1))], Door.area); until (not PtInRgn(MNow, Door.oparating) or not StillDown); Door.now := DoorNo mod (DoorPat + 1); end;

procedure CheckHuman; { purpose to check how human feeling )

vat

PersonalSpace : Rgnllandle;

HumanPosition : Point;

WorkRect

: Rect;

ObjectCount, LoopCount,

Result

: Integer;

begin PersonalSpace := NewRgn; ObjectCount := 0t GetMouse(HumanPosition)

;


SetRect(WorkRect, HumanPosition.h-5, HumanPo sition. v-5, Humanposition.h+5,

HumanPosition.v+5); OpeoRgn;

FrameOval(WortRect); Cl o seRgn(Pers onalSpace) ;

I to hWalMax do if RectlnRgn(hWall [LoopCount],

for LoopCount :=

Personalspace) then ObjectCount := ObjectCount + l; for LoopCount := I to vWallMax do if RectlnRgn(vWall[LoopCount], PersonalSpace) then ObjectCount := ObjectCount + 1; for LoopCount := 1 to FunitureMax do if RectlnRgn(Funiture [LoopCount], Personalspace) then ObjectCount := ObjectCount + l;

if ObjectCount >= 2 then Result := CautionAlert(UneasylD, NIL);

end; { of procedure Checklluman

}

procedure DoHuman;

{

purpose

to handle human operating door

) YAt MousePt : Point;

begin repeat

GeMouse(MouseR); if RInRgn(MouseR, Door.oparating) then MoveDoor(MouseR, Door.now) ; CheckHuman;

until not StillDown; end;

{ *********

items in Apple

Menu **********'tc }

procedure DoAbout;

{

purpose

bring up 'About...' box using a dialog box

)

var

theltem AboutPtr

:

Integer;

: DialogRr;

begin

SetCursor(Curslist[lrdouseCursor]^^); )

{ set to Mouse cursor


ShowCursor;

it back on AboutPtr ;= getNewDialog(AboutlD,Nll,PointerGl));

{

and turn

box)

}

{

get dialog

ModalDialog(Nll,theltem); { put dialog box up; get result ) DisposDialog(AboutPtr); { get rid of dialog box }

SetCursor(Arrow); end; { of proc DoAbout }

procedure DoDeskAcc(Item

{

pu{pose

:

Integer);

start up desk accessory from Apple menu

) var

SavePort RefNum DName

: GrafPtr; : Integer; : String;

begin

GetPort(SavePort);

{ save port before starting it } DAMenu := GetMenu(ApplMenu); { get a position of DA

menu

)

Getltem(DAlvlenu,Item,DName); {

accessory )

openDeskAcc(DName); {

refNum :=

)

SetPort(SavePort);

end;

{

purpose

) var

Menu Item B

:

Item :=

)

Longlnt);

{ item in menu that was selected }

Boolean; { dummy flag for SystemEdit call

in )

{

LoWord(Menulnfo); {

case Menu

of

}

{ menu number that was selected }

begin if Menulnfo <> 0 then begin Menu := HiWord(Menulnfo); command is

and continue

decode Menulnfo and carry out command

: Integer; : Integer; :

and start that sucker up!

{ restore grafport

of proc DoDeskAcc }

procedure HandleMenu(Menulnfo

t

get name of desk

ApplMenu : if Item = I

{

}

find which menu the get the command number

and carry

it

out

}

then DoAbout { bring up "About..." window} else DoDeskAcc(Item); { start desk accessory }


EdidMenu :if ltem=1 then Hnished:=Tme;{Quit COI― end;{case of Menu} HiliteMenu(o); end end; {of proc HandleMenu}

procedure HandleContents(WPtr

t

purpose

{

:

reset menu

nd

}

bar

WindowPtr; MLoc

}

: Point);

handle mouse click within window

)

var

WhAt

: INTEGER; Which : INTEGER;

begin

if WPtr = Mainhr then if WPtr = FrontWindow

{ if this is our window... } then begin { and if it's in front... } GlobalTolocal(Mloc); set { mouse position to local

)

WhatObject(Mloc); { get what object mouse is Which := WhichObject(Mloc, What); { get which object

What :=

pointing ) mouse is

pointing )

case What

of

inhWall, invWall,

:

DragObject(What, Which, WPtr, MLoc);

inGrowF :

GrowObject(What, Which, WPtr, MLoc);

inFuniture inGrowHW, inGrowVW, inSpace,

inDoor :

DoHuman;

end; { of case } end

else make it

end;

{

SelectV/indow(WHr) active )

and it's not in front, then

of proc HandleContents }

procedure HandleGoAway(WPtr

{

{

purpose

handle mouse click

) var

WPeek

: WindowPtr; MLoc : Point);

:

in go-away box

\VindowPeek; { for looking at windows

}


begin if WPtr = FrontWindow then begin window ) WPeek := WindowPeek(WRr);

)

if

TrackGoAway(WRr,Mloc) then

clicked )

if

)

WPeek^.WindowKind =

{ if it's the active { peek at the window

begin {

usâ‚ŹrKind {

True

and the box is

if it's our window

{

then Finished := then time to stop } else CloseDeskAcc(WPeek^.WindowKindX else close

DeskAcc ) end end else

SelectWindow(WPtr) { of proc HandleGoAway }

end;

{

else make

it

active

}

procedure DoMouseDown(theEvent:EventRecord); { purpose identify where mouse was clicked and handle it )

var

Location

: Integer;

theWindow : WindowPtr;

MLoc WLoc

: :

Point;

Integer;

begin

MLoc := theEvent.Where; {

get mouse

WLoc := FindWindow(Mloc,theWindow);

window )

{

position

get window, loc in

}

of

{ handle window locations } kMenuBar : HandleMenu(MenuSelect(Mloc)); { in the menu

case WLoc

)

InContent : HandleContents(theV/indow,Mloc); window )

{

inside the

InGoAway : HandleGoAway(theWindow,Mloc); { in the go

away box)

InDrag

drag bar)

: DragWindow(theWindow,Mloc,DragArea); { in

InSysWindow

window )

:

SystemClick(theEvent,theWindow)

end

end;

{ of proc DoMouseDown }

procedure DoKeypress(theEvent

{

:

EventRecord);

the

{ in a DA


purpose

handles keypress (keyDown, autoKey) event

)

var

KeyCh

: Char;

begin

if

(theEvent.modifiers and cmdKey) <> 0 then begin { menu key command ) KeyCh := Chr(theEvent.Message and charCodeMask); { decode

character )

HandleMenu(MenuKey(KeyCh)) { get menu and

item) end else

SysBeep(l) end; { of proc DoKeypress } procedure DoUpdate(theEvent

{

purpose

{ do *something* }

:

EventRecord);

handles window update event

) var SavePort,theWindow : WindowRr;

begin

theWindow != WindowRr(theEvent.Message);

window ) if

)

theWindow = MainPtr then

begin

{

find which

{ only update ours

SetCursor(Curslist[watchCursor]^^); { set cursor to watch } GetPort(SavePort); { save current grafport } SetPort(theWindow); { set as crurent port }

BeginUpdate(theWindow);

{

signal srart of update}

{ and here's the update stuff! } DrawWContents(theWindow); { do update stuff } { now, back to our program...} EndUpdate(theWindow); { signal end of update } SetPort(SavePort); { restore grafport } SetCursor(Arrow) { restore cunior } end

end;

{

of proc DoUpdate }

procedure DoActivate(theEvent

{ )

var

purpose

:

EventRecord);

handles window activation event


AFlag

: Boolean; theWindow : WindowPtr; begin with theEvent do begin theWindow != WindowPtr(Message);

)

AFlag := Odd(Modifiers); AFlag then begin

if

SetPort(theWindow); FrontWindow := theWindow;

end

{ if

{

{ get the window

{

get activate/deactive } it's activated... } make it the port } { know it's in front }

else begin

SetPort(ScreenPort); { else reassign port } if theWindow = FrontWindow { if it's in front then FrontWindow l= NIL { ...then forget that

end; end

{ of proc DoActivate }

end;

procedure InitPlCTure;

t

purpose

to initialize door inbetweening picture

) var LoopCount,

Angle

Degree

: Integer; : Fixed;

X,

Y

: Fixed;

WorkRect : Rect;

begin SetRect(WorkRect, 0, 0, 100, 100); for LoopCount := 0 to DoorPat do begin Angle := LoopCount * (360 div (DoorPat + 1)); Degree := FixRatio(Angle, 1); Degree := FixDiv(Degree, radian); X := Frac2Fix(FracSin(Degree)); Y := Frac2Fix(FracCos@egree)); X := FixMul(X,3276800); { X := X * 50 } Y := FixMul(Y, -327680fl-); { Y := Y * -50 } Door.inbetween[LoopCount] := OpenPicture(WorkRect); MoveTo(SO, 50); Line(FixRound(X), FixRound(Y)) ; ClosePicture;

end; { of for }

} }


end; { of procedure InitPICTure

}

procedure Initialize; { purpose initialize everything for the program )

var

Indx Result

: Integer; : Real;

begin { initialize all the different managers

Initcraf(@thePort); { create a grafport for the screen } InitFonts; { start up the font manager } InitWindows; { start up the window manager } IniMenus; { start up the menu manager } InitDialogs(Nll); { start up the dialog manager } FlushEvents(everyEvent,0); { clear events from previous

state )

l )

{

get four standard system cursors, plus two custom one

for Indx := iBeamCursor to watchCursor do begin Curslist[Indx]:=GetCursor(Indx); { read in from system Hlock(Handle(Curslistllndxl))

)

{

resource

lock the handle down

end;

CurslistMouseCursorl := GetCursor(MouselD); resources l

)

Hlock(Handle(Curslist$ouseCursorl)); {

Curslist[tlumanCursor] := GetCursor(HumanlD); from resources )

Hlock(Handle(CurslistlHumanCursor])); {

)

{ get cursor from and lock

{

it

down

get cursor

and lock

it

down

SetCursor(Curslist[watchCursor]n");{ bring up watch cursor

)

{ set up menus }

MentrList := GetNewMBar(ACADMBaT); from resource) DAIVIenu

menu )

l

:= GetMenu(ApplMenu);

{

{

read menu definition

set DA's position at Apple

AddResMenu@Alvfenu,l)RVR); { pull in all DAs SetMenuBar(Menulist); { set menubar to Menulist'

}


E)rawMenuBar;

{Set up window stuff}

{ draw updated menu bar to screen

GetWMgrPort(ScreenPOrt);

{get grnort for an windows

}

SetPort(ScreenPortl;

{and keep hand just in case

}

MainPtr:=GetNewWindow(MainID,@MainRec,Pointer(‐ 1)); {make WindOw as MainD. } SetPorto頭 ainPtrp; {set Window to cttnt graf port } SelectWindowo肛 ainPtr); {and make window act市 e } }

FrontWindow:=MainPtr;

{remember that■

's in front

MainPeek:=WindowPeek(MainPt⇒ ;{get pointer to window

r∝ ord

}

MainPcekAowindowKind:=UserKind;{Set window type=user kind(ID=8)} ScreenArea := screenBits.Bounds; { get SiZe of screen (dOn't

assume)} with ScreenArea do begin SetRect(DragArea,5,25,Right‐ 5,Bottom‐ 10); {set drag region }

SetRect(GrowArea,50,20,Right‐ 5,Bottom‐ 10)

{set grOw region

}

end;

Finished:=False;

{set prOgram te― nator to false }

{ *****initializaion for AnimationCAD Contents ***** } {Set initial position of wa11,initure,cct。

SetRect(vWan[1],450, 10, 454, 100); SetRect(vWall[2],460, 10, 464, 100); SetRect(vWall[3],470, 10, 474, 100); SetRect(hWall[1], 440, 110, 480, 114);

SetRect(hWall[2],440,120,480,124); SetRect(hWan[3], 440, 130, 480, 134); SetRect(Funiture[11, 440, 150, 450, 170); SetRect(Funiture[2], 460, 150, 470, 170); InitPICTure; SetRectODoor.area, 200, 100, 240, 140);

Door.oparating:=NewRgn;

.. }


SetRectRgn(Door. oparating, Door.area.left+20, Door.area.top, Door.area.right,

Door.area.bottom); Door.from := 90; Door.angle := 90; Door.now := AGL2IBW@oor.from); end;

{

of proc Initialize }

procedure CursorAdjust; {

purpose

change cursors depending upon location

) var

MouseR

: Point;

ObjectCode: INTEGER;

begin

if Mainftr = FrontWindow then with MainPeek^ do begin GetMouse(MousePt); { find where mouse is } if PtlnRect(MouseR,port.portRect) then { if over window

then )

begin ObjectCode := WhatObject(MouseR); case ObjectCode of inSpace,

inDoor : if Button then

inhWall,

{ if button down in space }

SetCursor(Curslist[humanCursor] ^^) { ...then make human, } else SetCursor(Arrow); { ...else make arrow

invWall,

inFuniture :

{ if in wall or funiture...

SetCursor(Arrow); {

}

}

..then make an iurrow

) inGrowHW, inGrowVW,

inGrowF : if Button then

axea )

{ if button down in grow

SetCursor(Curslist[crossCursor] ^^) else SetCwsor(Arrow);

end; { of case } end end

end;

{

of proc CursorAdjust }

procedure HandleEvent(theEvent

:

EventRecord);


{

purpose

decodes event and handles

it

)

begin case theEvent.What of

mouseDown : DoMouseDown(theEvent); {

pushed )

keyDown

)

autoKey

: DoKeyPress(theEvent);

mouse button

{ key pressed down

DoKeyPress(theEvent); { key held down updateEvt : DoUpdate(theEvent); { window need updating ) activateEvt : DoActivate(theEvent) { window made actlinact ) :

end

end;

{

of proc HandleEvent }

procedure CleanUp;

{

purpose

to do whatever's

needed before returning to

Finder ) begin

DisposeWindow(MainPtr) { get rid of the main window

) end;

{

of proc CleanUp }

{ main body of program MyDemo } Initialize; { set everything up } repeat { keep doing the following } SystemTask; { update desk accessories } CursorAdjust; { update which cursor } if GetNextEvent(everyEvent,theEvent) t if there's an event... ) ...then handle it then HandleEvent(theEvent) { } until user is done until Finished; } { Cleanup { clean everything up } end. { of program AnimationCAD } begin

}



.

″ ′}

´  ■ 一 .

■で,■●. II

、   一 ﹁一 , ■一

′ ヽ

,

,1(

:

子 │・


Turn static files into dynamic content formats.

Create a flipbook
Issuu converts static files into: digital portfolios, online yearbooks, online catalogs, digital photo albums and more. Sign up and create your flipbook.