「」に属する記事(最新5件のみ展開表示)

メイン

2006年11月18日

反発力の計算が14倍ほど速くなった、他。

失敗談 grinedit.addEdge("LinearEdge", {"v1": v1, "v2": v2})とやるべき所を grinedit.addVertex("LinearEdge", {"v1": v1, "v2": v2})とやって、 クラスキャスト失敗。 AddVertexの時点で型をチェックするようにしてもいいかもしれない。

GRINEditの中で一番重たい関数は反発力を計算している PL_Repulsion#applyなのだけど、ちょっと眺めて、ループの奥でやっている割り算が 定数での割り算なのであらかじめ逆数を求めて置いて掛け算するようにしたら5%早くなった。 そこで火が付いて、毎回頂点をIMassPointにキャストしてgetPositionしてたのを 先にキャストとgetPositionをすませて配列に入れておくようにしたら元の半分の時間に減った。 あとベクトルの計算を不定長のベクトルと見なしてforで回して計算していたのを、 長さ2のベクトル決めうちにしてインライン展開したら、元の実行時間の7%に縮んだ。 プロファイラ上のもたもたした画面で見ると早くなったのが実感でわかる。 まぁ、プロファイラをかけていることで、関数呼び出しのオーバーヘッドが増えているはずなので、 インライン展開による高速化の度合いは誇張されているだろう。 この高速化のせいで、反発力計算クラスはそのままでは3次元に対応できなくなったけど、 対応させるさほど難しくないし、その見返りとしてプログラム全体で見て30%の高速化になったのだったら 悪くない取引だと思う。

1746頂点の「全ての辺が8本のグラフ」の描画が5FPS以上で動く! 実用的な速度で動かないグラフの例として入れたのに、ぎりぎり実用範囲内に入ってしまった。

物理法則を設計する上で大事なこと。 まず力が連続的に変化すること。 次に作用反作用の法則を入れること。 最後に、現実の物理法則はあり得る物理法則の一つに過ぎないので、 物理学的に正しい物理法則ではなく、得たい結果が得られる物理法則を選ぶべき。 この3つだろうか。 最初の項はちょっと正しくなくて、例えば壁に貼り付く物理法則の場合、 一定距離に近づくと急に力が発生するから連続的ではない。 だから正確に言うと「適切な長さの切り替え区間を挟まずに プラスの力とマイナスの力を切り替えてはいけない」 ということになるだろうか。 要するに「0以上はマイナス1、0未満はプラス1」なんて力は 0周辺で振動を起こすのでダメだということ。 たまに1ピクセル以上の振動を起こすソフトがあるけど、 それは物理演算の設計のミスだろう。 作用反作用がないと合計が0にならずに1方向に動いていってしまう。 例外はやっぱり壁に対する力で、壁は力を吸収しても自然に見える。 最後の物理法則は自由にデザインしてもいいという宣言は重要で、 GRINEditの反発力なんか半径の二乗分の一どころか、半径分の一でもない。 なぜかというと、うっかりこんな実装にしたら、 運悪くすごく近い位置に頂点が並んだが最後、画面の果てのそのまた果てまで吹き飛んでしまう。

プラグインシステムのおかげで新しい頂点や物理法則の実装が楽になったかも。 プラグインフォルダのinit.pyは自動的に発見されて実行されるので、 新しい何かを実装しようと思ったらまずtestフォルダの中にinit.pyを作る。 そしてそこで頂点や辺や物理法則をグラフに追加するコードを書く。 実行すると実装中の頂点とかが表示される。 でJavaのコードを修正して実行して、とやって完成したら、 そのinit.pyをtestFileIconVertex.pyとかに名前変更する。 そうするともう呼び出されなくなるけど、テストフォルダの中に テスト用のスクリプトが入っていることになる。 そのままにしていてもいいし、Jythonでその「新しい頂点」の機能を試すための 簡単なサンプルとしてsampleフォルダに移して置いてもいい。

新しいフローレイアウト用の物理法則を追加。今は強さ決めうちの方向も上下決めうちだけど、手で書いたちっちゃいツリーはちゃんと整形された。明日はもっと大きいツリーや、合流のある例、ループのある例を作ってテストだ。

拡張子を指定するとアイコンを頂点に

iconvertex.png

SWTで拡張子からアイコン画像を取得し。それをAWTのImageに変換して2倍に拡大してから描画しました。ファイルをドラッグドロップしたらこの頂点ができて、ダブルクリックしたらファイルが開く、というのを作りたいのだけど、とりあえずアイコンを描画するところまで。でも残りはさほど難しくない気もする。

問題はマウスハンドラかなぁ。 今は「右ボタンのイベントを処理するハンドラ」「左ボタンのイベントを処理するハンドラ」という二つがあり、そこにMouseOperationクラスのインスタンスを入れる形になっている。でも、逆に言うとその二つしか登録できない。 以前、拡大縮小と平行移動が別のクラスで実装されていて、いちいち切り替えないといけないのが面倒だったので、Shiftキーが押されているかどうかで挙動の変わるものを作ったけど、いまいち納得がいかなかった。それはこういうこと。「右ドラッグ」と「Shiftを押された右ドラッグ」は競合しないものだから、それぞれを取るハンドラを両方同時にアクティブにしてあっても問題は起きない。それなのに「右マウス用ハンドラ」と「左マウス用ハンドラ」の2つしかハンドラを入れる場所がない。現状のまま「ダブルクリック」というドラッグと競合しないイベントを取るハンドラを追加したとしても、また抱き合わせクラスを作るか、さもなくば「ハンドラを切り替えてからダブルクリック」とやるかしかない。これはどう考えてもイベント分配システムの設計が間違っている。

2006年11月13日

BufferStrategy

[2006-11-13 21:24] J2SE, v1.4 の新機能 Buffer Strategyを使えば高速に描画できるようだ。 しかし現状で100頂点のグラフが60FPSで動いているし、 描画の切り替えは律速ではない。 遅いのは反発力の計算なので、高速化がしたいならば空間分割とかをする方がいいのかも知れない。

新しい頂点クラスを作る手順メモ

[2006-11-13 18:25] まずpluginsの中にtestというフォルダを作ってinit.pyを作成。
grinedit.addVertex("BoxVertex", {})
と書いてみる。実行すると頂点が表示された。OK。

BoxVertexの所を org.nishiohirokazu.graph.FileVertex に変えてみる。 Graph#addObjでキャストエラー。IGRINObjectインターフェイスをimplementsしていないから。 ちなみに今回はRenderableVertexを継承していないのだ。 なぜならextends JLabelだから。

	private String id;
	public String getId() {
		return id;
	}

	public void setId(Object o){
		id = o.toString();
	}

	public Hashtable getParams() {
		return new Hashtable();
	}

SimpleLayout#layoutStepでキャストエラー。 MassPointを継承していないから。これはIMassPointに変えるべきですな。 IMassPointをimplementsしてMassPointを参考に実装。

	private Vector dVelList = new Vector();
	private double[] position = new double[2];
	private double[] velocity = new double[2];

	public Vector getDVelList() {
		return dVelList;
	}

	public void setDVelList(Vector velList) {
		dVelList = velList;
	}

	public double[] getPosition() {
		return position;
	}

	public void setPosition(double[] position) {
		this.position = position;
	}

	public double[] getVelocity() {
		return velocity;
	}

	public void setVelocity(double[] velocity) {
		this.velocity = velocity;
	}

PL_RepulsionでRenderableVertexにキャストしようとしてエラー。 これはRepulsionが悪い。 IMassPointに変更。

ワールド座標系からスクリーン座標系に変換するところで RenderableVertexにキャストしていたのを、

Object o = i.next();
IMassPoint v = (IMassPoint) o;
IHasScreenPos sv = (IHasScreenPos) o;
sv.setScreenPos(vp.viewportTransform(v.getPosition()));
に修正。IHasScreenPosにセッタがなかったので追加。
private double[] screenPos;
public double[] getScreenPos() {
	return screenPos;
}
public void setScreenPos(double[] pos) {
	screenPos = pos;
}

レンダリングエンジンがIRenderにキャストしようとするのでそれもimplements

public void render(Object target) {
	update((Graphics) target);
}
無事描画はされるようになったが、描画される位置がおかしい。 どうやって直すかなぁ、これ。

legacyFormatの短いサンプル

VERTEX
3
1	Hello
2	GRINEdit
EDGE
1	2
2	3

legacyFormatは簡単なグラフを作る上では楽に書けるので、 今後のバージョンでも(非推奨ながら)残していこうと思っています。 しかし、頂点の色など色々とカスタマイズをしようとすると、 タブ区切りの現状ではどんどん泥沼にはまっていきます。 それを解決するためにYAMLベースで作った新しいフォーマットが 今後のリリースでは「標準のフォーマット」という位置づけになる予定です。

Vertex: 
  v1: {label: Hello}
  v2: {label: GRINEdit}
  v3: {}
Edge: 
  e1: [v1, v2]
  e2: [v2, v3]

古い記事タイトル一覧

凡例{ ●: 単一エントリーへのリンク, □: そこから最新記事までを一覧表示, ■: そこから最新記事までをwindow.openで開く}(comming soon)

2006年11月07日
 ■ □ By 西尾泰和 at 2006-11-07 00:43:04
2006年10月18日
 ■ □ By 西尾泰和 at 2006-10-18 23:17:14
2006年10月17日
 ■ □ By 西尾泰和 at 2006-10-17 02:11:19
2006年10月15日
 ■ □ By 西尾泰和 at 2006-10-15 13:01:18
2006年10月09日
 ■ □ By 西尾泰和 at 2006-10-09 18:19:00
 ■ □ By 西尾泰和 at 2006-10-09 15:17:07
2006年10月08日
 ■ □ By 西尾泰和 at 2006-10-08 16:17:19
2006年10月06日
 ■ □ By 西尾泰和 at 2006-10-06 19:18:51
2006年09月27日
 ■ □ By 西尾泰和 at 2006-09-27 23:57:15
2006年09月24日
 ■ □ By 西尾泰和 at 2006-09-24 15:48:35
 ■ □ By 西尾泰和 at 2006-09-24 15:20:15
2006年09月23日
 ■ □ By 西尾泰和 at 2006-09-23 18:03:39
2006年09月20日
 ■ □ By 西尾泰和 at 2006-09-20 03:04:55
2006年09月19日
 ■ □ By 西尾泰和 at 2006-09-19 14:24:02
2006年09月14日
 ■ □ By 西尾泰和 at 2006-09-14 19:01:46
2006年09月13日
 ■ □ By 西尾泰和 at 2006-09-13 04:02:46
 ■ □ By 西尾泰和 at 2006-09-13 00:05:14
2006年09月12日
 ■ □ By 西尾泰和 at 2006-09-12 03:39:09
2006年09月08日
 ■ □ By 西尾泰和 at 2006-09-08 03:51:07
2006年09月07日
 ■ □ By 西尾泰和 at 2006-09-07 00:07:47
2006年09月06日
 ■ □ By 西尾泰和 at 2006-09-06 04:43:36
2006年09月05日
 ■ □ By 西尾泰和 at 2006-09-05 00:27:42
2006年09月03日
 ■ □ By 西尾泰和 at 2006-09-03 08:10:32
2006年09月02日
 ■ □ By 西尾泰和 at 2006-09-02 01:11:01
2006年07月25日
 ■ □ By 西尾泰和 at 2006-07-25 15:23:50
2006年07月24日
 ■ □ By 西尾泰和 at 2006-07-24 18:56:02
2006年07月14日
 ■ □ By 西尾泰和 at 2006-07-14 15:11:32
2006年07月13日
 ■ □ By 西尾泰和 at 2006-07-13 15:29:41
2006年07月10日
 ■ □ By 西尾泰和 at 2006-07-10 19:25:19
2006年07月07日
 ■ □ By 西尾泰和 at 2006-07-07 16:30:04
2006年07月04日
 ■ □ By 西尾泰和 at 2006-07-04 13:16:00
2006年06月29日
 ■ □ By 西尾泰和 at 2006-06-29 17:22:14
 ■ □ By 西尾泰和 at 2006-06-29 16:58:34
2006年06月26日
 ■ □ By 西尾泰和 at 2006-06-26 13:34:33
2006年06月21日
 ■ □ By 西尾泰和 at 2006-06-21 17:13:41
2006年06月19日
 ■ □ By 西尾泰和 at 2006-06-19 17:39:42
 ■ □ By 西尾泰和 at 2006-06-19 14:25:13
2006年06月16日
 ■ □ By 西尾泰和 at 2006-06-16 14:11:00
2006年06月15日
 ■ □ By 西尾泰和 at 2006-06-15 13:57:13
2006年06月14日
 ■ □ By 西尾泰和 at 2006-06-14 15:11:22
2006年06月09日
 ■ □ By 西尾泰和 at 2006-06-09 13:35:03
2006年06月08日
 ■ □ By 西尾泰和 at 2006-06-08 19:46:55
 ■ □ By 西尾泰和 at 2006-06-08 16:31:32
 ■ □ By 西尾泰和 at 2006-06-08 13:24:32
 ■ □ By 西尾泰和 at 2006-06-08 02:23:31
2006年06月04日
 ■ □ By 西尾泰和 at 2006-06-04 05:50:44
2006年06月02日
 ■ □ By 西尾泰和 at 2006-06-02 16:05:55
 ■ □ By 西尾泰和 at 2006-06-02 14:48:17
 ■ □ By 西尾泰和 at 2006-06-02 14:13:53
 ■ □ By 西尾泰和 at 2006-06-02 13:20:51
2006年06月01日
 ■ □ By 西尾泰和 at 2006-06-01 21:55:34
 ■ □ By 西尾泰和 at 2006-06-01 15:33:12
2006年05月31日
 ■ □ By 西尾泰和 at 2006-05-31 22:50:01
 ■ □ By 西尾泰和 at 2006-05-31 02:56:53
2006年05月29日
 ■ □ By 西尾泰和 at 2006-05-29 23:36:29
 ■ □ By 西尾泰和 at 2006-05-29 17:30:59
2006年05月26日
 ■ □ By 西尾泰和 at 2006-05-26 23:26:16
 ■ □ By 西尾泰和 at 2006-05-26 20:14:47
 ■ □ By 西尾泰和 at 2006-05-26 16:11:07
2006年05月25日
 ■ □ By 西尾泰和 at 2006-05-25 20:10:49
 ■ □ By 西尾泰和 at 2006-05-25 19:54:26
 ■ □ By 西尾泰和 at 2006-05-25 19:20:46
 ■ □ By 西尾泰和 at 2006-05-25 18:52:36
 ■ □ By 西尾泰和 at 2006-05-25 18:36:11
 ■ □ By 西尾泰和 at 2006-05-25 15:27:15
 ■ □ By 西尾泰和 at 2006-05-25 15:26:35