目次

XAML 雛形

ボタンを押したらメッセージボックスが表示されるだけの単純なものです。 Visual Studio を使わずに、コマンドラインで MSBuild を使って XAML Windows アプリケーションを作りたい場合の雛形にどうぞ。

ファイル一式(ZIP 圧縮)

ラインアート

C# でもやってるんですけど(「ラインアート」)、 僕は GUI 開発環境の提供されているプログラミング言語を新しく覚えるたびにラインアートを作っています。 (比較とか勉強のため、とりあえず作る。)

(でも、「スクリーンセーバーっていったらラインアート」ってのも、 もうだいぶ昔の話ですが。 最近は 3D テキストか Windows ロゴ? まあ、Windows の出荷時のデフォルト設定で、 「スクリーンセーバーを使用しない」にするだけで、 全世界で消費される電力がかなり減るって言うような話を聞いたこともあるんですが。)

で、コードなしの Loose XAML だけでラインアートを作れそうな感じがしたんでやってみました。

LineArt.xaml

3次元バブルチャート(雛形)

バブルチャートの3次元版、ようするに、 値に応じた大きさのバブルを3次元に表示するプログラムが欲しかったので作ったもの。 現状の WPF の System.Windows.Media.Media3D では、三角メッシュしか使えないみたいなので、 バブルは球状じゃなくて正8面体で妥協。

今回使った機能は、以下のような感じ。

  • 3D メッシュ MeshGeometry3D で正8面体を作成。

  • ScaleTransform3D で正8面体の所望の大きさに拡大・縮小。

  • TranslateTransform3D で正8面体を所望の場所に移動。

  • 球状に配置されてるのが分かりやすく見えるように、中心に点光源 PointLight を配置。

  • 裏面も見えるように環境光 AmbientLight を設定。

  • 前後を分かりやすくするために、方向性光源 DirectionalLight で、前から赤い光、後ろから青い光を当てる。

  • アニメーション機能 Storyboard & DoubleAnimation を使ってカメラを回転。

ソースファイル(zip形式書庫) … テスト用に、球面上のランダムな位置にランダムな大きさの正8面体を200個ほど配置したもの。

XAML ファイル … コードビハインドなしの、XAML のみ。固定位置に同じサイズの正8面体を6つ配置したもの。(セキュリティ権限上、ブラウザ中で直接実行付加。一度ローカルに保存してください。)

凸包計算プログラム

後輩に、「任意に与えられた点を全て囲む面積最小の長方形を求めたいんですが」と言われてノリで作ったもの。 せっかくだからサンプルプログラムとして公開。

ファイル一式(ZIP 圧縮)

画面コピー
画面コピー

計算アルゴリズム

「全点囲む最小の長方形」は以下の条件を満たしてそう。

  • 与えられた点列の凸包を囲む面積最小の長方形を求めれば OK。

  • 凸包を囲む長方形が面積最小のとき、長方形のどれか1辺は、凸包の少なくとも1辺に接している。

なので、以下のような処理で「全点囲む最小の長方形」を計算可能。

  1. 与えられた点列の凸包を求める。

  2. 1辺の方向を与えたときに、その向きで面積最小の長方形を求める。

  3. 凸包の全ての辺の方向について、2. を計算。

1 は、Graham 走査という有名なアルゴリズムがあるのでそれを利用。 2 は、向きが決まっていれば、辺から点までの距離が法線との内積で求まるので、 面積最小の長方形は簡単に求まる。

GUI プログラム

↑のアルゴリズムの確認のために、 以下のような GUI プログラムを作成。

  • ウィンドウ内を左クリックしたとき、その位置に新しい点を追加。

  • 右クリックしたとき、その位置に一番近い点を削除。

  • 点列に対して、凸包、全点を囲う最小の長方形を求めて、 それぞれをウィンドウ中に表示。

GUI の作成には Windows Presentation Foundation を使用。 点や凸包は、 System.Windows.Shapes 名前空間内の、 Ellipse や Polyline を使用。

参考

ちなみに、最初プログラムを作った目的は、 求めたい長方形が本当に凸包に接してるのか、証明するのが面倒だし、 総当りで試してみようというものです。 (長方形を0.01ラジアン刻みとかで回転させて、 その向きの面積最小の長方形を総当りで求めて、 最小のものを選択。)

その後、後輩が調べてきた所によると、 「全点囲む最小の長方形」はやっぱり凸包の辺に接してるみたい。 証明の書かれた論文あり↓

  • H. Freeman, R. Shapira: "Determining the minimum-area encasing rectangle for an arbitrary closed curve," Communications of the ACM, Vol. 18, Issue 7, pp. 409 - 413, (July 1975).

あと、凸包を囲う長方形の求め方、 もっと効率いい方法がありそう↓

  • N. Adlai, et. al.: "Algorthmic pradigms: examples in computational geometry II," ACM SIGCSE Bulletin archive, Vol. 22, Issue 1, pp. 186 - 191, (Feb. 1990).

Multi-line fitting

最小二乗法でフィッティングできるようなデータ列が2種類異常混ざっているような場合に、 n 本の回帰直線を求めるプログラム。

ファイル一式(ZIP 圧縮)

画面コピー
画面コピー

注: 画面コピーは結構うまく行った例。 実際にうまく行くかどうかはデータ列次第です。 混ざってるのが2種類(回帰直線2本)くらいなら割とうまく行きますが、 6本でここまでうまく行くことはそう多くない。 あと、回帰直線を何本くらい使えばうまくクラスタリングできるかを自動計算したりという機能はないです。

計算アルゴリズム

クラスタリングと最小二乗法を組み合わせで実装しています。

要するに、 回帰直線をクラスタ重心と考えて、

  • 各点に対して一番近い回帰直線を探して帰属情報を更新

  • クラスタごとに最小二乗法で回帰直線を求めなおす

の2つの処理を反復。

でも、クラスタ重心が点の場合と比べると、局所解に陥りやすいみたいです。 それを解決するような研究報告例あり↓。

乾 健太郎,金子 俊一,五十嵐 悟: “LMedSクラスタリングに基づく複数直線のロバスト回帰,” Technical report of IEICE. PRMU, Vol.99, No.449(19991119) pp. 81-86.

曲面上の物体の運動シミュレーション

せっかく Orcas(Visual Studio の次期バージョンのコードネーム)の新β版が出たことだし (2007/4末)、 なにか WPF を使ったプログラミングをしてみたくて作ったもの。

ちょうど最近、 「物理」の辺りを更新していたことだし、 3次元空間中の曲面上の物体の運動をシミュレーションして、 Viewport3D を使って3次元表示するプログラムを作ってみた。 (参考:「曲面上の運動」。)

ファイル一式(ZIP 圧縮)

Orcas で作ったので、Visual Studio 2005 だとコンパイルが通らないかも。 多分、using System.Linq とかをコメントアウトするくらいでコンパイルできると思いますが。

数値計算

ソリューション内にいくつかのプロジェクトがあって、 数値計算がらみは MyMath プロジェクト中にまとめています。

Lambda 計算

拘束面の式( x(u, v)=1.5 v cos u とか)だけ与えれば、

∂x
∂u
とか、 「ハミルトニアン」やその導関数は自動的に計算してくれるものを作りました。

そのために、 以下のような感じで使える Lambda 計算的なライブラリを作りました。 (MyMath.Lambda 名前空間内。)

Variable u = new Variable("u");
Variable v = new Variable("v");
Function x = 1.5 * v Function.Cos(u);
Function x_u = x.Differentiate(u);

double uu = 0.1;
double vv = 2;
double xx = x_u.GetValue(u.Set(uu), v.Set(vv));

ただ、あまり賢くはないです。 (u * v) / u が約分されて v になってくれたりはしないので、 分母の値が小さくなりすぎて精度が落ちることがしばしばあります。 あと、分母分子が共に 0 になって、結果が NaN になることもたまにあります。

微分方程式の数値解

4次のルンゲクッタ法を使ってハミルトンの微分方程式を解いています。 (MyMath.DifferentialEquation 名前空間内。)

3次元プロット

数値計算結果を3次元的に表示するユーザコントロールを作りました。 (Plot3D プロジェクト。)

Viewport3D(参考:「3次元モデル」)を使って、 拘束面と物体を表示します。

拘束面の裏面も見えるようにするために、 面と物体を回転させています。 コントロール上を右クリックすると、回転を一時停止・再開できます。 また、左クリックで、カメラの向きをある程度変化させることができます。

サンプル GUI プログラム

実例として、下図に示すようなプログラムを作りました。

実行画面
実行画面

この実行画面の例では、 拘束面の方程式を

x(u, v)=1.5 v cos u
y(u, v)=1.5 v sin u
z(u, v)=exp v +0.2cos5πv 2

ポテンシャルを φ = z として物体の運動をシミュレーションしています。

ちなみに、Lambda 計算の精度の問題で、 時々数値計算結果がおかしくなることがあります。 というか、拘束面の式にあまりに複雑なものを指定すると、 すぐにおかしくなります。 まあ、実用目的じゃなくてデモ用だと思ってご容赦ください。

バージョンアップ

何点か改善 → 「[サンプル] 式木を WPF で GUI 表示」。

更新履歴

ブログ