log
つらつら考えながら書くだけではなく、きちんと作業日誌っぽくしよう。
- 13:19-14:11
- 制約と物理法則が微妙に分かれていたが、この2つは「どのタイミングでsatisfyするか」が異なるだけなので整理してcode cloneを削った。またMaxxPointクラスのvelocityフィールドは使用されていなかったので、きちんと正しい値が入るようにした。物理法則によって頂点に与えられる加速度をvelocityListという名前のメソッドに入れていたが、これは実際には加速度なので名前が正しくない。accelerationListは長いのでdVelListにした。
- 制約は繰り返し回数の上限までの範囲で満たされるまで繰り返し実行されるので、ステップの最初と最後では満たされている。その為、その他の物理法則とまとめた際に0ステップ目で「satisfied = true」を返してしまい、物理法則は常に「satisfied = true」であるので、すべての条件が満たされたと判定されて繰り返しを終了してしまう。これが原因でバネを引っ張りAnchorした場合に「Anchorが働くフレーム」と「働かないフレーム」が交互に現れ振動して見える現象が起きる。制約は0ステップ目でfalseを返さなければいけないことに注意。これをライブラリのユーザに対する注意にするか、こういうミスが発生し得ないフレームワークにするかは難しいところだ。
- 頭ではうまく動くつもりの設計だけども、慣性力と剛体制約を入れて本当にうまく動くのか早めに確認する必要がある。
- 次はVertexListをHashtableに変えるあたりの修正。
- ここまでの作業はコミット済み
- 14:23 - 15:43
- vertexList を Vector から Hashtable に変更。
-
for (int i = 0; i < numVtx; i++) { RenderableVertex v = (RenderableVertex) vertexList.get(i); (中略) }の部分をfor(Enumeration e = vertexList.elements(); e.hasMoreElements();){ RenderableVertex v = (RenderableVertex) e.nextElement(i); (中略) }に変更する。 - 反発力の計算ではすべての頂点の対に対して計算するけども、i < jに限定しておいて作用反作用の法則を使って計算量を半分に減らしている。だからEnumerationではやりづらい。values()でjava.uitl.Correctionを取得してtoArray()で配列にしてしまえばいい。
- IteratorとEnumerationはどう違うのか。Enumeration (Java 2 Platform SE 5.0)によれば
このインタフェースの機能は、Iterator インタフェースにもあります。Iterator インタフェースの方には、任意指定の削除のオペレーションが追加されており、メソッドの名前も短くなっています。新しく実装する場合は、 Enumeration ではなく Iterator を使うようにしてください。
がーん。修正やり直し。 - 一意なキーと頂点の対応付けに関して、XML-RPCでintを受け渡しして、いちいちIntegerに変換してキーにするより、キーを一意なStringにしてしまう方が手っ取り早い。int indexの代わりにString nameをつける。
- Graphが持っていたAddVertexやAddEdgeを除去。ad hocなもの(引数がなかったらCircleVertexを作って、1つ文字列があったらBoxVertexのlabelだと見なして…という感じ)だし、頂点オブジェクト自体や、辺オブジェクト自体を返しているので。しかし当然のようにLegacyLoaderが動かなくなった。うーん。メソッドは一応復活させておいて、LegacyLoaderを捨てるときに一緒に捨てよう。
-
- vertexList を Vector から Hashtable に変更。
- 15:49 - 16:19
- コメントアウトしたGraph#AddVertexの復元。結局、XMLRPCHandlerに持たせたgetUniqNameをMediatorに移しておけばいいのだろう。
- そうだ、忘れてた。Vertexに自分のnameを持たせるんだった。そうすればインスタンスから名前も取れるし、名前からインスタンスも取れるんだった。
- 以降、vertexListに頂点を追加する際はString graph.addVertex(RenderableVertex)を呼べば自動的に一意な名前をつけて頂点を追加し、その名前を返してくれます。
- 17:30 - 18:37
- 現状でXML-RPCでのAddEdgeはクラス名と頂点のインデックスが必須の引数になっているけども、頂点のインデックスもparamsに含めてしまった方がいいのかも…。省略不可であることを表現したつもりだったけどもJSONでの保存時に特別扱いが必要になるし、現状で作成した辺の頂点を変更することはできないし(これは別にできないという仕様にしても構わないと思うのだが)
- 一気呵成にedgListもHashtableにした。とりあえず表示は問題なく動いている。
- nameもparamsに含めるべきなのだろうか…。
- 含めてみた。
- 頂点や辺の種類(クラスの名前)もname, 頂点や辺を識別するための一意な文字列もname…、使われる場所が違うから衝突はしないが、ユーザが混乱しそうではある。
- おおっ、JSONで保存したファイルを読み込むのがうまく行った。
- ただしまだ辺と頂点だけしか保存していないので、固定した頂点もまた動くようになってしまう。
先に根本に近い方をいじろうと思って作業していたので、変化がいまいちわかりにくい。この一連の修正で、JSONでの保存ができるようになったのはもちろんだけど、それだけではなくて、「選択範囲をグループ化」「選択範囲だけこの手法で整形」「選択した頂点にこういう物理法則を適用」ということができるようになるはず。
あと、しばらくぶりに自分のコードを見て、やはり「一つのクラスでSWTにもAWTにも対応」というのは良くないと思った。美しくない。アプレットなのにswt.jarが必要になるのもばかげている。
LinearEdgeだけAWT用とSWT用を分離した。ColorHolderもAWT用のを作成した。