昔の最近の出来事(2004.11)

2004/11/30

日付け越え。

RIB出力プラグインいじり。というかErlangいじり(^^;
メモ。

  1. if文は全ての条件を記述しなくてはならないらしい。例えば、
    count_down(F,N) ->
      if
        N > 0 ->
          io:format(F, "~p ", [N]),
          count_down(F,N-1);
        N =< 0 ->
          N
      end.
        
    てな感じで書くとうまく動くけど、

    count_down(F,N) ->
      if
        N > 0 ->
          io:format(F, "~p ", [N]),
          count_down(F,N-1);
      end,
      N.
        
    だと何故かダメ。でもコンパイルが通るのが謎。
  2. [...]はリストを表す。[値|[リスト]]で値をリストの先頭に繋げる。 「[CAR|CDR]=リスト変数」で、リストの先頭をCARに、残りをCDRに入れる。 length(リスト)でリストの長さを検査できる。
  3. 「#」はrecord型(構造体)を示す。「式#レコード名.メンバ名」でメンバを 参照できる。
  4. Wingsのmeshや頂点リストはe3d/e3d.hrlで定義されるrecord形式で格納される。 e3d_meshとe3d_faceというレコードがあり、e3d_meshは頂点などのリストが 格納され、e3d_faceはe3d_mesh内の頂点等へのインデックスリストが格納 されているらしい。

なんとなくデータの構造が判ってきた気分。でも取り出し方がまだよく判らず。

2004/11/29

日付け越え。

RIB出力プラグインいじり。ところが、Erlangの難解な仕様につっかかって死亡。
Erlangでは、一度しか変数に値を代入できず、一度値がセットされた変数は 内容を更新する事ができません。つまり「x=x+1」のようなプログラム言語の 特徴とも言える代入ができないのです。さて、この条件の下、1からnまでの 合計を求めるプログラムはどう書けば良いでしょうか? 答えは10秒後(ぉぃ










TANEも判らなかったので(^^; Webを探ってみた所、 このような参考ページを見つけてみたり。
えーと、関数の再帰呼び出しを使えば良いらしい........................ .................................................................... .................................................................... はぇ? マジっすか?! そんな感じ(笑 あまりにひねりが効きすぎていて、 よく判りませんでしたが、確かに関数の戻り値を「一度だけ代入」して 1からnまでの合計が求められます。という訳で、確かにWingsのソースとか 見てても、再帰呼び出しされているものとかあって、何がなんだか判らない 感じになっていましたが、良く見るとそういう事をしているのかも。 それにしても、こういった基本的な事でもひねりを効かせて書く必要が ある為、前にも述べましたが 可読性が非常に悪いプログラム言語という 印象を受けるのかも知れません。
ところで、再帰呼び出しを行なうと、普通に考えるとスタックを消費 するのではないかと思うのですが、例えば 入力ファイルに行番号を振りながら 出力する「cat -n」っぽいプログラムを書こうとした時、再帰で番号付け してしまうと、例えば1000000行のファイルを食わせるとスタックが オーバーフローして死ぬのでは?という疑問を抱いたり。
で、実験。D言語で以下のようなプログラムを書いてみました。ただし、 何故かgdcでコンパイルすると、標準入力がうまく使えない様で、引数に ファイル指定した時しかうまく動作しませんでした。

import std.stream;

int main(char[][] args)
{
  FileMode fmd ;
  if( args.length==1 ){
    stdin.open(0,fmd.In) ;
    catn(stdin,1) ;
  }else{
    File infile ;
    for( int i=1 ; i<args.length ; i++ ){
      infile = new File() ;
      infile.open(args[i],fmd.In) ;
      catn(infile,1) ;
      infile.close() ;
    }
  }
  return(0) ;
}
  
void catn(File infile, int no)
{
  char[] line ;

  line=infile.readLine() ;
  if( infile.eof()==true ) return ;
  if( line is null ) line="" ; /*** Dのstrema.readLine()の空行に対する謎な振るまい ***/
  stdout.printf("%8d : %s\n",no,cast(char*)(line)) ;
  catn(infile,no+1) ;
}

ファイルは次のような一行awkプログラムで生成してみました。

gawk 'BEGIN{for(i=0;i<1000000;i++){print("testlines");}}' > xxx.lst

で、実際に食わせてみると、赤○白×で落っこちたり(^^; 43281行目までしか出力できないもよう。まぁ、D言語で書くとそうなると いうだけの事なので、そんなの重々承知の上なErlangだと、どんなにやっても 死なないのかも知れませんが。多分死ぬと思うけど(ぉぃ;

2004/11/28

昼前に起床。

Wings出力のRIBを観察してみたり。
マテリアルの読み込みがうまくできていなかったのを修正したり。 ReadArchive文に食わせるファイル名をダブルクオートで括っていなかったので、 エラーしてました。これで一応テクスチャマップもExportできるように なりました。
Pixieで赤○白×でずっこかすには、透明属性である_hole_をマテリアル に指定し、Subdivisionメッシュとして出力したRIBファイルを食わせると 良いらしい。ただ、何故それでずっこけるのかがイマイチ不明。というのも Subdivision文の正しさが良く判っていないので、文法チェックをすり抜ける 文法間違いなのか、文法は合っているがPixieの対応がまずいのかが 区別できないというのがその理由です。むー。
RIB出力オプションとして、PointsPolygonsで出力してみた所、 法線を一緒に出力するとPixieで文法エラーになるみたい。PointsPolygons出力で 且つ、法線無しだとうまくレンダリングできるRIBファイルが出力されるよう です。で、法線あり出力が何故文法エラーになるか調べてみたところ、 どうやら頂点リストと頂点法線リストのサイズは同じでなくてはならないようですが、 そうならない場合があり、それを食ったPixieが期待する頂点法線リストのサイズと 異なるといってエラーしているようです。頂点リストと頂点法線リストのサイズが 異なる場合ですが、例えば直方体のようなモデルの場合、頂点数は8個ですが、 頂点法線数はシェーディングの条件によって異なります。スムーズシェーディング ならば、頂点法線数は頂点数と同じ8個になりますが、フラットシェーディング の場合は、一つの頂点について共有する面ごとに法線の向きが異なるので、 合計24個必要な事になります。POVでは、頂点も法線も別々にインデックス配列を持って いるので、頂点と法線の数が異なる場合でもうまく表現できます。RIBでは そうではないようなので、面が参照する頂点を共有しているかどうかに関係 無く全て展開して、展開した頂点にくくりつけるように法線を並べる必要が ありそうです。むーん。

ぐうたらTVを見ていたら、いきなりTVが映らなくなったり。いきなりというと ウソですが、前から少し兆候があって、少し暖めないと画面が出ない状態に なってました。それが昨日から画面が時々揺れる様になり、今日になって プツリと音がして切れちゃいました(^^; ブラウン管に全く電気が通っていない という映らなさかげんで、通電に問題があるだけっぽいので、コネクタとか 接点部分をちょっと触れば直りそうな予感はしなくもありませんが、 もう12年くらい使っているX68kのディスプレイテレビ(ここ4年くらいは TVとしてのみ活躍)なので、買いかえ時かなぁと思ったりしています。 因みに音だけは出るのですが、絵が出ないTVがこれほど退屈なものだとは 思いませんでした(^^;

Pixieでのレンダリングを実験してみたり。 レイトレースの設定などは手で書きたす必要がありますが、適当に設定して 次のような感じ。法線無しのPointsPolygonなので、よく見るとポリポリしています (<なんだそれ?)。因みにシェーダーは使用してませんので、RenderManの 特徴を活かしていない使い方になってます(^^;

Pixieレンダリングテスト1 Pixieレンダリングテスト2

PointsPolygonを使用すれば、メモリの消費もレンダリング時間もそんなにかから ないようで、POVのmesh2出力したそれと同じレベルなのかも。これで法線を うまく出力できれば、POVのそれと同じレベルの変換ができる事になるので、 どうにかしたいなぁと思ったり思わなかったり。因みに、髪の毛は テクスチャで貼ってみたのですが、透明がうまく透けてくれませんでした。 形状から見ても影ではないので、 以前POVで問題になった、 透明なテクスチャを貼っているのに影はテクスチャを貼ったポリゴンの 形状で出るという問題とは違う模様。

2004/11/27

午後もいい時間に起床。

ビルドしたWingsのプラグインソースを眺めてみたり。POV出力のカメラ は何故かWingsの作業画面の絵よりもカメラが近寄ったアングルでレンダリング されているような気がする (以前作画した例) ので、どのようにカメラ設定を行なっているかを 見てみました。結構面倒な変換を行なっていますが、極座標系の全体座標 変換パラメータを入力として、カメラと注目点の二点に変換しているようです。 しかしながら、これといった不審な点を見つけられず。因みに、RIB変換プラグイン では、前述の極座標系変換をそのままTranslateやRotateといったモデルビュー 変換につっこんでいるだけという感じ。
そういやPOV変換でlight_source文のライト位置の座標記述で','コンマが 抜けていて、Wingsで変換したPOVファイルのパーサーをうまく書けなかった 点を修正してみたり。
あと、RIB出力プラグインも再コンパイルしてみたり。こちらは特にエラーする 事はありませんでしたが、新しいPixieを使ってのレンダリングができるかどうか を試してみました。結果、赤○白×でPixieがずっこけてみたり。そもそも 出力しているファイルが正しいのか、Pixieがダメなのかを切り分ける為、 簡単なモデルで試した所、それはうまくレンダリングできる模様。更に調べて みると、レンダリングできるモデルと赤○白×でずっこけるモデルが存在 する事が判ってみたり。どうやらなにかしらの変換不具合がありそうで、 それを食ったPixieが腹を下してcoredumpという流れにありそうな予感。 ただ、Pixieのコンパイルはうまくいった事が無いのでgdbなどで具体的に死んでいる 場所まで特定できない訳ですが。以前も同じ理由で原因追求は断念したのですが、 Wingsの方で少しモデルを変化させてみて コケる/コケないの境界を見つけ出せば何かわかるかも。 プラグインをいじってみるという選択肢ができたので、モデル変換でどうにか 対処できるならそれもアリかと。でも、実際のところレンダリングできない モデルがあるという事よりも、レンダリングにかかる時間の方が問題かも。 レンダリングできるモデルをPixieでレンダリングさせてみたのですが、 驚くほどメモリを食うみたいで、POVのそれに比べると最終的な絵を得るまでの 手番が長くなりそうです。

ハタと思いついて、POVの教科書を眺めてみたり。POVのカメラのパラメータ である所のangleですが、これはいわゆるfov(field of view)に相当する ものです。気になったのが、OpenGLでもRIBでも、fovと言えばfovYの事を 指していて、画像の高さに対して働く要素になっています (以前描いたイメージ図)。所が、 POVの教科書の図では、画像の幅に対して働く要素になっています。POV出力プラグインでは Fovという変数値をそのままPOVのcameraのangleに指定しています。 fovXのつもりでfovYを入れてしまうと、横長画像では「fovX>fovY」の関係が 必ず成り立ちますので、思ったよりも画面に入る幅が狭くなると推測されます。 という訳で、もしやこれがWingsでPOV出力した時に思ったよりも近寄っている 原因でないかと考えました。
そんな訳で、fovYからfovXを計算する式を立ててプラグインをいじってみたり。 次のような感じ。元のFovがdegreeなので、radianに変換して計算する必要が あります。

254,255c254
<   FovX=(math:atan((math:tan((Fov/2.0)*Ro))*(Width/Height)))*180.0*2.0/math:pi(),
<   io:format(F, "  angle ~p~n",[FovX]),
---
>   io:format(F, "  angle ~p~n",[Fov]),

で、レンダリング結果は以下の通りで、オブジェクトが同じ位置に来るように なりました。

Pixieレンダリング POVレンダリング

そういう事でしたかという感じ。

2004/11/26

少し早めに帰着。今日は風が強くて、自転車置き場の自転車がほとんど 全て倒れていたり。

蛍光灯交換。うーん明るい。

以前惨敗したWings3Dのソースからのビルドに再挑戦してみたり。 以下Cygwinは基本的に開発系ツール一式が問題無く使える状態にあるとします。

まずは Erlangのパッケージダウンロード。 ダウンロードページ から、WindowsBinary のパッケージアーカイブをダウンロードして、 インストール。この時、「c:/Program Files」の下にインストールしたとき、 Cygwinのbashのパスに/cygdrive/c/Program Files/erl5.4.2.1/binを追加しても 何故か反応しなかったため、/usr/local の下にerl5.4.2.1ディレクトリの シンボリックリンクを張って/usr/local/erl5.4.2.1/bin にパスを通しました。
次に ESDLのダウンロードとインストール。 前回惨敗したのは、このESDLというSDLのErlangのラッパーをどうしてもうまく 認識できなかったのが原因でした。で、ESDLのテストなどを実行していて、 以下の様にするとうまく反応しました。

  1. ダウンロードページより、ZIP形式のWindowsバイナリ入りアーカイブを ダウンロードする。
  2. 展開すると(今回のバージョンでは)esdl-0.94.1025ディレクトリの下に 内容物一式が展開される。
  3. このesdl-0.94.1025ディレクトリをErlangのインストールパス下のlib ディレクトリの下にesdlというディレクトリ名でコピーする。
    ex) cp -r esdl-0.94.1025 /usr/local/erl5.4.2.1/lib/esdl
    本当は用事のあるファイルだけコピーされれば良さそうですが面倒なので(^^;
  4. esdl-0.94.1025/priv/*.dllをパスの通ったディレクトリ(例えば/usr/binとか)の 下にコピーする。
  5. これでesdl-0.94.1025/test 下でテストプログラムをビルドして(makeを実行 するだけ)、
        % erl
        Eshell V5.4.2.1  (abort with ^G)
        1> testgl:go().
        
    てな感じに実行すればうまくゆきました。前述のlibディレクトリに一式 コピーせず、説明書通りにテストプログラムを実行しても、何故かうまく ゆかなかったのが謎ですが。

ESDLのテストプログラムのビルド&実行に成功すれば、Wingsの再コンパイルはできると 思って良いようです。

続いてWingsのソースアーカイブをダウンロードして展開。 環境変数ESDL_PATHにEDSLのebinパスを指定する必要がありますが、 erlangのlibの下に置いたので、特に指定する必要は無いようです。 ただし、/ebinというパスを検索パスに加えるようなので、気持ち悪い 場合は二重指定になりそうですが環境変数ESDL_PATHに /usr/local/erl5.4.2.1/lib/esdl/ebinを指定しておけば良いと思います。
makeを実行すると、erlangで書かれたソースのコンパイルが実行されます。 途中 plugins_src/accel/ディレクトリ以下に置かれるC言語で書かれた ソースのコンパイルに失敗します。Wingsビルドの説明書にはMinGWを 使用する手順で書かれていますが、CygwinのgccでMinGWパッケージを リンクさせる方法を取りました。Makefileを以下の様に書き換え。

accel% diff Makefile.org Makefile
54c54
<       mingw32-gcc -I$(ERL_INC) -o $(LIBDIR)/wings_ogla_drv.dll \
---
>       gcc -mno-cygwin -I$(ERL_INC) -o $(LIBDIR)/wings_ogla_drv.dll \

てな感じで、mingw32-gccを gcc -mno-cygwin にしただけ。 これで本当にDLLを作成してるんだっけ?という疑問があるのですが、 ここを直せばビルドに成功しました(^^)v
実行はコマンドラインから以下の様に実行。
% werl -pa c:/tane/develop/work/wings/wings-0.98.26/ebin -run wings_start start_halt

これは、ビルド説明書BUILD.win32の通りでよさげ。

ここまでできたので、続いてPOVプラグインを再コンパイルしてみる事にしました。
Kayos氏のページより、POV Exportプラグインのアーカイブをダウンロードし、 wingsのビルドディレクトリで展開すると、丁度 plugins_src,plugins といったディレクトリ 構成そのままで展開されます。 plugins_src/import_export下のMakefileを書きかえます。 変数MODULESに「kayos_utils,pov_exp,pov_ui,wpc_pov」を追加し、 再度ビルドすると、POVプラグインがインストールされた状態の Wingsが出来あがります。これをこのまま使用すると、バイナリを そのまま使用したのと同じ様にエラーします(^^;;;; で、Wings3D起動時に 開くコンソールを見てみると、 e3d_vec:norm_cross()なる関数が見つからないみたいなメッセージが 出ていたので、他のプラグインを参考にそれっぽい感じに書き換えてみました。

229c229
<   L = e3d_vec:norm_cross(Rev, {0.0,1.0,0.0}),
---
>   L = e3d_vec:norm(e3d_vec:cross(Rev, {0.0,1.0,0.0})),
236c236
<   DownN = e3d_vec:norm_cross(Rev, LeftN),
---
>   DownN = e3d_vec:norm(e3d_vec:cross(Rev, LeftN)),

要は「外積を求めて正規化する」を一度に行なう関数が無くなったというだけの 事らしい。てゆーか、プラグインの互換性を無視してまで引っ込めなくても 良いレベルの関数にも思えますが、それはそれとして。

これで取りあえず最新のWingsにプラグインを追従できそうな予感。
これで自分プラグインを作る環境も手に入れられた事になるのですが、 如何せんerlangはTANE的に非常に可読性が悪いと言いますか、 記述が記号めいていて、何がなんだかよくわからないプログラム 言語という印象が強くて、自分で書くまでに至れないような気がして います。

2004/11/25

日付け越え。

蛍光灯が一本切れたままで、しばらく使っていたのですが、ついに残りの 一本が切れてしまい、居間のあかりが無くなって死亡。どうしようもない ので寝る。

2004/11/24

日付け越え。

先日の法線の方向の話。取りあえず3Dの場合は辺の法線を使って 頂点法線と辺法線のなす平面上に経路を乗せれば、取りあえず2Dと 同じ問題までは絞り込めそうな予感。曲線の進行方向に対して右方向(もしくは 左方向)に法線が向くように、曲線上の位置に対する法線を更新していけば 良いのかなぁ。でも、それって凄く重そうな予感が。
後、辺の法線を使用した時、二点の頂点が真逆を向いていて辺法線が0に の場合に失速するという問題がありそう。でも、極端な話、表向きと裏向き のポリゴンが隣り合わせにならないと、そういうケースというのは普通には 存在しないと思われる為、その場合は例外的に飛ばないようにコントロール すれば良さそうな予感。

SAIの6版がリリースされてますが試す事ができず。

2004/11/23

普通に目が覚めるも、風邪気味で一日中寝てたり。

サブディビジョン。頂点の法線と重なる直線の交点から適当な円を決めて、 近似できないかと考えて、シンデレラで取りあえず2点について平面作図を行なって みたのですが、法線が平行の時には当然のことながら、交点が存在する場合 でも、交点からそれぞれの頂点までの距離が同じでないと円周上に乗らないと いう当然の事に気づいて惨敗。

その後、ベジェ的な物で補完すれば良いのじゃないかと作図を行なって みました。多少ハンドルの長さを見直す必要がありそうですが、 法線をどんなにいじってもそれなりの結果が得られそうで、3Dへの拡張も 可能そうな予感。新たに増殖させる頂点の位置としては、曲線の長さの 半分の距離の位置を利用し、法線はその位置から二つ頂点法線の混合割合 を求めれば良いのかなぁという感じに考えてみました。テクスチャマッピング 座標も同じような感じで求めるのが良いかなぁと思います。実際うまく いくかどうかは判りませんが。そんな感じで作図は以下のような感じ。

二点の位置と頂点法線から曲線を補完する図

ベジェ作図がよく判ってないので(シンデレラ自体にはベジェ描画プリミティブは ありません)ベジェっぽいものになってますが、それはそれとして。

んーー、よく観察してみると、新しく追加する点の法線は良く考えない とダメな予感。例えば、二点の頂点法線をどちらも左斜め上45度くらいに 設定した時、補完したベジェ曲線はS字型のようになるのですが、 単純に二つの頂点法線を混合率で法線を求めるのでは、曲線のどの点においても 法線は左斜め上45度の方向を向くことになります(平均値を取っている感じなの で当然です)。でもそれは期待と違う結果になると思います。 所が単純に曲線を微分した傾きベクトルに垂直な ベクトルを法線にしたとすると、2Dでは二つの方向(表方向と裏方向)、 3Dだと外積ベクトルの元になる平面上のベクトル全てがその答えの対象 となります。という訳で、あんまうまくない予感がしてきました。 はて.......

どんどん具合が悪くなってきて死亡。

2004/11/22

日付け越え。

なんだか具合が悪くてすぐ寝たり。

2004/11/21

昼頃起床。

すっかりシンデレラにはまっている感じ。点の従属関係がきちんと管理 されている為、正しく描けばマジックハンドのような作図も可能なようです。 点の移動倍率を変更したり、動きを変換したりする作図方法(機械製図の分野 にあてはまるかも知れませんが)について興味が湧き始めている所。そんな感じで パース作図の例を描いてみました。赤い点を動かせばぐにぐに動かせ ます。茶色の点は赤い点の従属関係にある点なので動かせません。 画面の外に点が飛んだ時はリロードという事で。

ふむ、でも実際の所、「Windowsだから」という理由以上の根拠って 特に見当たらないのですよね。XboxもWindowsにDirectXだったようにも 思うのですが、あれも、作る所によるといった感じが大きい気がしますし。 色々なソフトメーカーが参入するようなので、その結果によって真価が判ると いう気もします。どこが作っても同じ感じになるのであれば、共通部分に 問題があるのでしょうし、そうでなければ、作る所によるというのが大きい のかも知れません。
それよりも、専用開発機材が不要という点はやっぱり大きいところなので しょうかね。「PCで開発できる」ってPCで開発できなかったの?と逆に 疑問に思ったりしましたが。

2004/11/20

朝普通に目が覚めたものの、そのまま二度寝して起きたら昼過ぎ。

サブディビジョン。何か無いかとWebをぐるぐるしていたら、 「 シンデレラ」なる平面作図ソフトの存在を知りました。 リンクしたページはそのソフトを使用して色々な作図の例を示した ページなのですが、作図された結果をアップレットとして動かしたり する事ができて、なかなか楽しいです。TANE自身も机上で考えるのに 時々Tgifで作図する事があるのですが、解像度(Tgif上の最小グリッド) の問題でニ直線の交点から更に線を引く場合など、交点自体がグリッド上 に無い時は微妙にずれてたり、円周上にうまく点が打てないなど難儀な事が あります。やっぱこういうソフトは存在するんだと思いました。 このシンデレラ上には自己証明機能があるらしく、例えばその作図が一般解 なのか、その図形だけに当てはまる特殊解なのかを検査できるようです。 使う人が使えば、IKの机上検証なんかにも応用できそうな予感。

よくよく調べてみると、シンデレラのソフトは解説本にバンドルされている ようで、本屋で買えるらしいという事で、散髪のついでに本屋を覗いて みることに。こういうのに限って見つからないというのがいつものパターン なのですが、数学分野の書棚であっさり発見。4000円也と普通に買うには 少々高価に感じられるかも知れませんが、そんな事は気にしません。

そんな感じで試してみたり。どうやらJavaで書かれているらしく、JavaVMも インストールされるのですが、どうも我が家のシステムに既に入っているJavaの それと相性が良くないようで、描画にマウスカーソルを消すためのゴミが残る とか、OSを再起動した後、シンデレラを起動するとそのままシステムがハング状態 に陥るとかハマり事がありました。1.4.2のVMを指定してインストールする事で、 OKとなりました。うーむ。
で、早速遊んでみました。基本操作を覚えれば、後はアイコンに出てくる ツールチップを読めば、大体何をするものなのか判るというシンプルな操作が 良い感じ。後は、作図に必要なコツを少々掴めば結構思い通りに図が描けます。 作図したデータをHTML形式で保存するとJavaアップレットになるようで、 オンラインで操作できる作図データやアニメーション表示という事が行なえるようです。 PostScript形式にも変換できるので、いくつかの画像変換ツールを用いれば、 画像への変換も可能です。GhostScriptを使用して、次のような感じでpng に変換してみました。

gs -q -dNOPAUSE -dBATCH -sDEVICE=ppm -sOutputFile=- foo.eps | pnmscale -width=320 | pnmtopng.exe > foo.png

でも、gsで変換した画像が紙のイメージそのままで、縦長画像で上下に余白が 出ている為、結局トリミングはGIMPを使用したというのがへっぽこなのですが(^^;

スキニングの作図

内角を1/2にした線分を扱うことができるので、クォータニオンを意識した 作図が簡単に行なえます。当然、ぐにぐにと動かせます。もう少し細かく描けば、 以前スキニングのテスト で問題となったまま放置されているひじの丸まりについても、きちんと 作図できるものと思われます。

このシンデレラの本(って書くと童話の本みたい(^^;)ですが、フリーソフトの 解説本みたいな感じで、ソフトを作成するに至った経緯であるだとか、 内部処理の簡単な説明が書かれています。内部は複素数で扱っているらしく、 極解や特殊解に対してうまく振舞うように工夫されているようです。 例えば、円と直線の交点を求める場合、交点が二点ある場合と、接点が一点 ある場合と交わりの無い解無しの場合があります。この時、解無しが曲者に なるケースで、その場合、必ず解ありになるよう操作制限したり、考え無し にやると例外でソフトが飛んだりする訳です(<それはあなたの場合だけです)。 複素数だと負の数の平方根を求めるようなケースでも 原理的に解無しという状況が無くなる為、特殊解に対して場合分けなどの必要が無く、 うまく振舞うというのが、その構造が選択された成り行きという事のようです。 とても高度な数学を利用してプログラミングされているようなのですが、 その利用は実に簡単というのに、すばらしさを感じました。そんな訳でTANE的ステキ ソフトに認定です。

2004/11/19

日付け越え少し前に帰着。

そういや全然関係無い話ですが、水曜の深夜にやっている「BECK」って TVアニメ。動きが固い所とかある様にも思うのですが、所どころに 散りばめられた微妙な「間」が個人的に良いなぁと思ったり。そんだけ。

眠くて死亡。

2004/11/18

日付け越え前に帰着。

Pixieのサブディビジョンの実装やWingsのスムーズなんかが参考に なるかな?とソースを見てみたのですがよく判らず。

久しぶりにWingsの新しいの(0.98.26)を入れてみたり。POV出力プラグインを インストールして実際に出力確認をした所、failしてExportできず。 0.98.22cでは大丈夫だったので、単に対応の問題かも。 問題は、POVプラグインの対応が最近は止まっているという点かもしれませんが。 むーん。

2004/11/17

日付け越え。

サブディビジョンを行なう際の、面の曲率を考慮した分割時の 頂点位置の決定について、Webを少し漁ってみたり。毎度の事ながら、 探し方が悪いのか、これっていう感じのは見つけられず。

2004/11/16

日付け越え前に帰着。

ポリゴン細分化。やっと理解できたり。というか、正20面体から 球に近似する話を扱っていたのですが、球を近似する前提で話を しているのを、一般解と混同していた為、訳の判らない事になって ました(^^; で、一般化された例では、一部具体的なコードが欠けて いるので、そのままでは使用できず。でも、なんとなくイメージは 判った感じ。

雰囲気としては、 三角ポリゴンの各辺を約半分に分ける点を決めて、その点を繋ぐ のが分割の基本手順で、

         V1                      V1
        /\                    /\
      /    \    →       V12/____\V31
    /        \            /\    /\
V2/            \ V3   V2/    \/    \V3
   ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄         ̄ ̄ ̄ ̄V23  ̄ ̄

V12,V23,V31の位置が曲面の上に乗るようなうまい位置を探すのが キモらしい。具体的にどうするのが良いのかは判りませんが、 頂点法線のベクトルを使ってどうにか補完すれば良いのかなぁ?

2004/11/15

日付け越え。

赤本に載っているポリゴンの細分化のコードを見ながら机上で作図をして、 どういう事なのか確認してみたり。所が、作図がマズいのか、何か間違っている のか、細分化される感じにならず。何故これでうまく細分化できるのか 全く理解できないまま、眠くて死亡。

2004/11/14

昼前起床。

gcc-3.4.3が出てたのでPPCクロスビルドしてみたり。しばらく終りそうに ないので、ちょっこりお出かけ。

先日思いついたスキニングのアイデアについて少し考えてみたのですが、 もう一つ問題がある事に気づいたり。変形後の形状を用意したとして、 そうした場合、1自由度の曲げしかうまくゆかない気がしてきました。 例えば、ひじやひざのような個所ならばそれでも良いのですが、 肩の場合、上下に前横と変形後の期待値が非常に多いです。なので、 もうちっとうまい方法でないとダメかも。やっぱ、関節球をブロブの ようなものでひっつけるのが良いのかなぁ......
あと、ハイポリモデルとローポリモデルの関係について。今の所、 Wings上で作成するのは、ある程度ローポリ寄りのモデルで作成し、 POV出力する際にSubdivisionで細分化モデルにしたものをハイポリと してレンダラに渡しています。つまり、ハイポリを手で変更する 事は無いというのが現状で、SubdivisionさえWingsの外でできれば 良いという事が言えそうです。問題は、その方法が良くわからないと いう点なのですが(^^;、赤本に基本的な手法が載っていたのでちょっと 調べてみようと思ったところ。

帰ったらエラーなくgccビルドは終っていたり。make installして POVRayをクロスコンパイルして、ppcsim上で実行してみた所、 3.4.2よりも0.000112%程度実行命令数が減っていました。実行結果も 一応問題無さげ。

SAIの新版を本格的に使ってみたり。いくつか挙動が不審な点があった のですが、再現性などがイマイチはっきりしないので、取りあえず メモ。

  1. 一発目のSAI専用タブレットドライバの組み込みに失敗する場合がある。Wacomの ドライバで一度認識させた後でOFFにして、この状態でSAI専用タブレット を組み込むとうまくいく。
  2. 使っているとカーソルが突然とんでもない所に移動するときがある。 Windows自体をしばらく違う用途で使っていて、継続してSAIを使うと そういう挙動不審ケースに陥り易いもよう。再起動してSAIだけを使用している分 には問題無さげ。
  3. スペースキー押下状態でのキャンバススクロールができなくなる状態に陥った。 契機不明。その状態になった所で、メモ帳を開いてスペースキーを押せば 空白入力できたので、スペースキーが死んでいる訳でもなく、キャンバス回転や カーソルによるスクロールはできたので、キーイベントが死んでいる訳でもなく。 復帰できなかったので、SAI自体を再起動しました。

そんな感じのことがありました。

2004/11/13

昼過ぎ起床。

そういや、gdcで生成した実行バイナリのファイルサイズについて調べて みました。先日のPNGのラッパー関数を、CとDで使用した場合の差は、以下 のような感じ。

% gcc -DDEBUG -O2 _load_png.c -lpng -o cexe
% gdc -O2 load_png.d _load_png.o -lpng -o dexe
% ls -l cexe dexe
-rwxr-xr-x    1 tane     mkgroup     17841 Nov 13 15:51 cexe
-rwxr-xr-x    1 tane     mkgroup    197747 Nov 13 15:51 dexe
% strip cexe.exe dexe.exe 
% ls -l cexe dexe
-rwxr-xr-x    1 tane     mkgroup      6656 Nov 13 15:51 cexe
-rwxr-xr-x    1 tane     mkgroup     97792 Nov 13 15:51 dexe

Cの場合はライブラリ群が殆ど全てDLLリンクされてそうなので、 異常に小さい感じになってます。でもまぁ、それを考慮に入れたとして、 ガベージコレクタとかのライブラリ分を考えても、Dで生成した実行ファイルは 妥当なサイズに収まっていると思います。 流石に「hello world」を表示するだけのもので、1MBの実行ファイル (しかもstrip後)を 生成したgcjよりは現実的という感じでしょうか。

テクスチャ読み込みを仕込んでみたり。赤本を見ながら仕込んで、なんとなく 表示できてみたり。POV-Rayなどで使用する場合とテクスチャ座標の上下の 関係が逆だったり、2のべき乗サイズである必要があるのを忘れてたり、 色々とハマり事はありましたが、表示自体は問題なくできるようです。 Wingsでできても良さそうなのにと思わなくはなかったり。 色味が少々暗いですが、ライトなどで調節すればもうちっとマシな感じには なるかも。あと、アルファ値を落としてロードしているので、アルファ 付きテクスチャを貼った時の結果も見てみたい所。

テクスチャ表示テスト

2004/11/12

日付け越え。

PNGローダのテスト。その前にDでファイル操作を行なう方法を調査したり。 色々とハマりましたが、ファイル書き込みは次の様な感じにするのが良いらしい。 因みに、PPMファイルへの書き込みです。

1:    import std.stream;
      :
2:    FileMode fmd ;
3:    File outfile = new File() ;
4:    char[] img=image[0..(width*height*(bpp/8))] ;
5:    outfile.create("wtest.ppm",fmd.Out) ;
6:    outfile.printf("P6\n%d %d\n255\n",width,height) ;
7:    outfile.writeString(img) ;
8:    outfile.close() ;

imageは「char*」でポインタ型で宣言された変数で、画像の生データを 指しています(ポインタの内容はCのPNGロード関数の戻り値が入ります)。 ポイントは、次の点という感じ。

  1. 新規で書き込みファイルを開く場合はcreate()メソッドを使用する。open()メソッド で開くと、fopen()関数のfilemode言う所の"w"ではなく、 先頭からの上書き("a"とは少し違う)になるみたい。なので、 10バイトのファイルに、5バイト書き込むと10バイトのうちの先頭5バイトが 書き換わるという感じになるようです。
  2. サイズ不定のポインタ型をサイズの判る(.lengthプロパティの使用できる) 配列型に変えるには、「スライシング」を使用する。具体的には4行目の ような感じ。動的配列imgに、ポインタ型imageの先頭[0]から画像サイズ分 を指し直すようなイメージです。後に出てくるwriteString()メソッドでは、 書き込みサイズを指定するのではなく、サイズの明確な配列を使用するので、 Cの関数から得たポインタ型のimageではダメで、サイズを与えてやる 必要があるという事のようです。D言語の中で閉じていれば、ポインタ型を 使用する場面は殆ど無いと思われますが、C関数とインターフェースを取る 場合にはこのような変換を行なう必要があるようです。
  3. 書き込みはwrite()メソッドではなく、writeString()メソッドを使用する。 なんとなく直感に反するのですが、write()メソッドでは、引数となる 配列の配列サイズを格納し、その後にデータの実体を書き込む様です。 データの実体だけを書き込むには、writeString()を使用するという事 の様です。 因みに、/usr/include/d/std/stream.dを見てみると、 write(char[])メソッドはwrite(int)メソッド(write()メソッドはオーバー ロードした色々な引数バリエーションがあります)でサイズを書き込んだ後、 writeString(char[])で、実体を書き込むように書かれているようです。 文字列の場合、ファイルではなくターミナルへ出力する場合もあるので、 その辺から、このような仕様になっているのではないかと思われます。 writeString()に文字コード変換フィルタとか入れてしまうと、 その限りではないと思われますが、今の所はそういうものだという事で。

一度流儀が判ってしまえば、ややこしいことは無いという感じ。 所で、今回調べた使い方は、Streamモジュールをimportする事だけを 知って、あとは、モジュール自体を見て調べました。面倒ではありますが、 いざという時、これはこれでアリかも。

2004/11/11

日付け越え。

先日のPNGローダのデバッグ。しょーもない間違いでえらく時間がかかったり。 そのせいで、Dからの使用テストまで到達できず(汗;

2004/11/10

日付け越え前に帰着。

テクスチャ読み込み用にPNGロードのラッパーを書いてみたり。 コンパイルできる所までで終了。

2004/11/09

日付け越え前に帰着。

OpenGLのマテリアルについて。lib3dsを使用した時は、OpenGLの glMaterial()にそのまま突っ込める値が取得できたのですが、 POV読みで得た場合は、一連のPOV-finish値とglMaterial()に突っ込む 形式と若干の違いがある為、変換が必要な模様。

しばらく放置しているスキニングについて、ちょいといいかもという アイデアを思いついたり。基本型を0、変形型を1とした時、その間の変形 係数を回転量を示すクォータニオンと位置の変位で表し、その係数を 全頂点に対して保持するというもの。そもそも放置状態になった理由は、 変形をコントロールするのに、一意のアルゴリズムでは、全ての変形 ケースを表現できないというのが問題だったからです。 以前はこの分割を回転軸からの距離で決めていたのですが、 その方法で得られた変形後の結果は極めて狭いでしか適合しないものでした。 で、今回思いついたのは、変形後の形状と変形前形状との差を 補完する係数を探し出す訳ですから、少なくとも、変形後の形状が 思ったものと違うという事は無いハズという目論みです。 大抵の場合、変形前と変形後の形状は一意に決まっている場合が殆どなので、 その間をどう分割するかというのが今回のアイデアのポイントになると思います。 枯れた言葉で言うならば、モーフィングの一種なのかも知れませんが(^^;
問題は、頂点に係数をくくり付けてしまうと、ローポリモデルで 確認し、ハイポリでその骨格をそのまま使用するという事や、モデル の差し替えなどができなくなってしまいます。なので、代表頂点を使ったり、 変形影響度を表現するうまい方法を考える必要があるかも。それを 考えると、ハイポリをもっちりもっちりいじる方が楽だったりして。

2004/11/08

ほんの少し早めに帰着。

SAIの新しいのをちょっとだけ試してみたり。以前報告したバグについては 修正されている模様。マスクの方が実装されたとの事だったので、少し 試してみたのですが、何か挙動が不審な予感。というか、仕様なのかしら? マスクを解除すると全面がマスク状態となるようで、自動選択ツールは、 この状態から非マスク領域となる部分を選択する様です。 今までと逆になっており、「マスキング」という直感的意味と合わない ので混乱しそう。マスクペンとマスク消しゴムも、作業内容の直感と違う記号 (ペンの方が現在のマスクを消す方で、消しゴムの方がマスクを塗る)なので、 気持ち悪さを感じます。まぁ、大抵の場合はマスキングした領域を 反転させるので、それを直接穴をあける領域を作成するようにしたものと 推測されますが、これぁどうでしょう。
あと、手で同じ事をすればできますが、選択領域をレイヤーに自動変換する パスが無いようなのでちょっと辛いも。
そんな感じ。ちょろっと触った程度なので、まだバグっぽい感じのものは 発見できす。

きょうもダメぽで早めに寝ます(x_x)

2004/11/07

風邪気味で一日中寝てたり。

POVパーサー。取りあえずサーフェスだけをOpenGLで表示してみたり。OKそう。 テクスチャや色はどうするか考え中。

どんどん具合が悪くなってきて早めに死亡。SAIの新しいのが出ているのですが、 試せず。

2004/11/06

朝から、はす向かいの建物の取り壊し工事を行なっていて、うるさくて起きたり。

POVパーサーの整理の続き。なんとなく形になってきたような予感。 テクスチャーで思い出したのですが、テクスチャマップ表示を行なう事を 考えると、画像ローダのラッパークラスを書く必要がありそうな予感。
Dでは配列の連結を行なう事ができますが、これが便利過ぎてヤバいです。 例えば、読み込む「数(サイズ)」が事前に判っているデータであれば、 データの数が収まるバッファを用意してそこに読み込めば良いです。 POVの場合、mesh2文の頂点データなどは、全体の数が最初に出てきて、 その後に頂点データが続きます。もし予め宣言した数よりも多い場合は、 エラーにするなり読み捨てるなりすれば良い訳です。 逆に、読み込むデータの数が不定の場合、方法としては、挿入可能な 連結リストを使用するか、予め適当なサイズを想定しておき、それを超える場合は ポインタリストのサイズを拡張するなどの方法が考えられます。 あえて言うなら、前者の方は実装が面倒、後者の方はリストのサイズを バンドルした構造体で扱い、その構造体を操作する関数を用意する必要が あるでしょう。で、Dの配列は、 後者のポインタリストを拡張するものに近いと考えられますが、 演算子で連結でき、変更後の配列サイズも.lengthプロパティで 取得できます。言語仕様の範囲で配列サイズの拡張が実装されている のが良い感じです。
Dでは文字列はchar型の配列なので(即ちCと同じ感じ)、文字列の連結は、 この配列の連結そのものという事のようです。 ただ、JavaのStringクラスの様にコード変換を行ないたい場合など に比べると、低レベル過ぎるかも知れませんが、その場合は Stringクラスっぽいものを実装すれば良い訳でして、演算子をオーバーロード できるDでは、演算子も含めたStringクラスと同等のクラスを実現すること は可能な範囲内と思われます。

ちょっこり本屋に。「DEATH NOTE (4)」が出てたので買ってみたり。 帰りにゲーセンに寄って、翼神をやってみたり。あー、なんか体が 受け付けないかも。目がチカチカするし、自機が極端に動き過ぎて弾が避け にくいような感じがしました。 PCアーキテクチャ+WinXP(Embeded)という事らしいのですが、 システムやOSが今回の翼神のデキにどれだけ関係しているのかは よく判らず。DreamcastもWindowsCE搭載だったように思いますが、 DCはどのゲームを見てもOSがゲームのシステムに影響している感じには 見えませんでしたので、WinXP(Embeded)もそれと同じく大した影響を与えない とするならば、PC(ハード)アーキテクチャや、それを駆動するドライバの方に 問題があるんじゃと思ったり思わなかったり。本当にPCそのままだと、 あんな感じになりそうですが。
帰ってデスノ読んでぴひゅ〜、こうなるか、そういう感じ。それにしても、 (2)辺りからですが、読むのにスゲー時間がかかります(^^;

だんだんと具合が悪くなってきた。

2004/11/05

日付け越え前に帰着。

今日のタモリ倶楽部は鳥瞰図。手描きの立体地図なのですが、 すんげー細かくて驚き。こういうのを専門で描くイラストレーター の存在を初めて知りました。

POVパーサー整理の続き。テクスチャーどうしようかと考え中。

2004/11/04

日付け越え前に帰着。

昨日のPOVパーサーを少し整理してみたり。

2004/11/03

昼過ぎ起床。

D言語から、yaccを利用する方法を考えてみたり。 DではCの関数をそのまま利用できると共に、逆にextern(C)宣言された Dの関数をCからも利用できる事になっています。また、Dで書かれた Cコンパチ関数の中では普通にDの文法が利用できる為、ガベージコレクタ などの機能も有効になるハズです。
yaccでは、パース時に文のパターンにマッチした時点でアクションとなる 関数を実行する事で、自前のデータ登録だとか、エラー処理だとかを 行ないます。このアクションで実行する関数をCコンパチのDで書かれた 関数を利用する事で、yaccパーサーを利用して、Dのみで有効なクラス などで書かれたデータの読み込みが可能ではなかろうか?と考えました。

実際のインプリメントについて考えてみました。例えば、

obj {
  pos=10,10;
  speed=0.1 ;
}

みたいなデータ構造を示す文法があったとして、yaccでこの文を解釈した時、 実際にDでのデータを使えるものとしてD風に書いたとすると、

class CharObj{
  int posx,posy ;
  double speed ;
}

みたいなクラスを生成して、データを保持したいと思ったとき、次のような 感じにするのが良いと思われます。

obj_primitive : OBJ '{' /* OBJ は "obj"をlexでパースしたものとする */
                  { newobj = new CharObj() ; }
                obj_params '}'
                  {
                    List.add(newobj) ;
                    newobj=null ;
                  }
obj_params    : POS '=' NUM ',' NUM ';' /* POS は "pos"をlexでパースしたものとする */
                 { newobj.setpos($3,$5) ; }
              | SPEED '=' NUM ';'       /* SPEED は "speed"をlexでパースしたものとする */
                 { newobj.setspeed($3) ; }

obj文の解釈が始まった所で、newobjを新規にインスタンス化し、 setterメソッドを使って、各種パラメータを取り込んでいくというものです。 obj文の解釈が完了した所で、リストに繋いで終了という感じにしてみました。 で、これをC言語ネイティブに置きかえる事を考えると、さりげなく使用している setterメソッドに相当する関数や、newに相当するイニシャライザーを Cコンパチ関数にしなくてはならないので、これらのラッパーを作成する必要 があります。しかしながら、このラッパーを作成するのが少々面倒臭いという のが難点でしょうか。

で、実際に以前書いたPOVファイルのパーサーをちょっといじって、使えるかどうか試して みました。一応データの読み込みはできていそう。今のはまだプログラムの構造を 少々見直す必要がありますが、取りあえず使えそうです。ただし、リンク時に -lflと-ly でflex,bisonのライブラリをリンクしていたのですが、これだと 何故かリンク後のプログラムがうまく動かないようで、実行すると標準入力を 待っているような状態になりました。リンク時に-lflと-lyは付けなくて良いようです。

「全国一斉IQテスト」というTV番組をやっていたのでやってみました(^^;
結果から言うとTANEの現在のIQは100で、極めてフツーという結果でした(^^;;; 知覚(図形を反転させて同じのは?とかそんなの)と数(結果を導くのに 数字や演算子の並びを変えるのとか)は、まぁまぁ良い感じかなぁ?という 気がしました。知覚については、多分、最近3DCGづいていたりするからでしょう。 逆に、論理の推論(Aは100、BはAより30多く、cはBより40少ない、一番少ないのはどれ? とかいうの)がメタメタ。 内容自体は時間があれば全然判るものなのですが、文章から状況をイメージするのに、 実際に紙に図を描かないと判らないタイプなので、脳味噌の中だけで状況判断できない という感じ。あと、聴覚記憶もダメ。特に興味の無い文章を耳で聞いて、 一回で覚えるというのは普段から苦手で、一度聞いても すぐに殆ど全て忘れ 去っているという感じです。他はフツーで、 トータルでフツーという事らしい。そんなフツーのTANEがお届けしているフツーの 日記です(<何だそれ?)。

2004/11/02

日付け越え前に帰着。

Dのマニュアルを眺めていると、先日のオブジェクトとnullとの比較式で、 「===」が「is」という演算子に変わっているのが判りました。 で、内容をよくよく読んでみると、「==」の方は構造体にしろ、オブジェクト にしろ、その内容のビットパターンが等しいかどうか を検査するという事のようで、「is」の方はオブジェクトの参照の同一性 を検査する、というように動作に微妙な差がある事が判りました。
オブジェクト同士を「==」で比較すると、例えば「a == b」の場合「a.opCmp(b)」 のような形に変わって、opCmp()メソッドは /usr/include/d/object.dを見る感じ、 「return (int)(void *)this - (int)(void *)o;」というような演算 の結果が返されるという事のようです(んー?本当にこれで構造体の内容も 比較できるのか?)。 先日のnullとの比較を「==」で行なうと、nullポインタの内容を引き 出そうとして、Segfaultで死ぬという事みたいです。マニュアルを読む感じでは、 インスタンスの内容比較ができるという様に読めたのですが、 実際にテストコードを書いてみたところ、何故か一致を検出できず。

% cat obj_cmp.d
import std.stream;

class Test{
  int a ;
  int b ;
  this(){
    a=0 ;
    b=0 ;
  }
}

int main(char[][] args){
    Test test_a = new Test() ;
    Test test_b = null ;

    printf("step1\n") ;
    if( test_a is test_b ){
      printf(" test_a eq test_b\n") ;
    }

    test_b = test_a ;
    printf("step2\n") ;
    if( test_a is test_b ){
      printf(" test_a eq test_b\n") ;
    }

    printf("step3\n") ;
    test_b = new Test() ;
    if( test_a is test_b ){
      printf(" test_a eq test_b\n") ;
    }

    printf("step4\n") ;
    if( test_a == test_b ){
      printf(" *test_a eq *test_b\n") ;
    }
    printf("test_a: a=%d, b=%d\n",test_a.a,test_a.b) ;
    printf("test_b: a=%d, b=%d\n",test_b.a,test_b.b) ;

    return 0;
}
% gdc obj_cmp.d
% ./a.exe 
step1
step2
 test_a eq test_b
step3
step4
test_a: a=0, b=0
test_b: a=0, b=0

期待値としては、step4の比較で一致を検出しても良さそうなのですが、 何故か同じでは無いらしい。でも、各インスタンスの内容を表示する 限りでは同じに見えるような気がします。何故?っていうか、 実はオブジェクトの場合はopCmp()をオーバーロードして、自分で 比較ロジックを入れなくてはダメなのかしら?そうだと言われれば、 それは当然かも。

そんな訳で、opCmp()をオーバーロードしてみたのですが、何故か オーバーロードしたopCmp()メソッドを通過する気配無し。 マニュアルを読んでみると、「==」はopEquals()メソッドが実行 されるらしく、実際にそれでオーバーロードできました。って、あれ? 変だなぁ?/usr/include/d/object.dでは、opEquals()メソッドは、

    int opEquals(Object o)
    {
        return this === o;
    }

という事になっており、これは即ち「a == b」って書けば「a === b」と 同じになるって事じゃないの?「演算子のオーバーロード」の章で、

〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
注意: クラスオブジェクトへの参照と null を比較するには次のように書きます。 

        if (a === null)
        
下のようには書きません: 
        if (a == null)
        
後者は次のように変換され: 
        if (a.opCmp(null))
        
opCmp()が仮想関数であった場合失敗します。
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜

って書いてあったから、そうなんだと思っていたのですが、あれ?何か辻褄が合って ないような気がしてきましたよ?.........いや、良いのか。 「a===b」に置きかえられるならば、先のテストコードでstep4比較で一致が検出 できないのは理解できますし、もしオブジェクトが 有効な領域への参照を持っていないのならば、「null.opEquals(null)」と いう置き換えになりますが、そもそも参照が無い訳ですから、opEquials() メソッドも無いハズで、だから「===」の比較結果を得る前にSegfaultするという イメージで、良いような気がしてきました。 あぁ、ややこしい。なんとなく、演算子をオーバーロードできるようにした副作用 という気がしてきました。
じゃあ、「is」と「==」は何もしなければ、事実上同じ?というのを確かめる為、 step2の「is」による比較を「==」に変えてみた所、やっぱり一致検出されなくて、 あれぇ?って感じになったり。

参照型の変数の事を呼び方が良く判らず、「クラス変数」と呼んでいたのですが、 Javaではstatic宣言されたメンバーフィールドの事を特に「クラス変数」と呼ぶ らしいので、混乱しないように、参照型の変数の事を単に「オブジェクト」 と呼ぶように過去の文書を直してみました。どうもオブジェクト指向言語の 構成要素の呼び方は、使いなれない単語ばかり(インスタンス、メソッド、 コンストラクタ、スロー....)で覚えられません(^^;

2004/11/01

日付け越え前に帰着。

風呂を沸かそうと風呂場に入ったらゴキブリの姿が(汗; しとめてやろうと新聞紙を丸めて叩ける位置に移動するのを伺っていたら、 いきなり動いて湯船の中にポチャって.....うわーん、溜めてあった水を 落とさなくちゃならないやん! それよりも、泳いで出てこようとしていたので、 すかさず放水して溺死させる事に。でもこれがなかなかしつこくて、 数分間 水を浴びせてやっと動かなくなったり。と、思ったらまだ 触覚が動いていたりして、むひーー!。これぁ死なないと判断し、 バスマジックリンを浴びせてやっと動かなくなったり。 割り箸でつまんで厳重に袋詰した後、風呂掃除して、また水溜め直して ってやってたら、すっかり時間が無くなって死亡。なんてこった。


TOP PREV