C#で3次元グラフを表示する ILNumerics

ILNumericsは.NETで使用可能な数値計算等のライブラリである.グラフ表示機能も備わっているので,それを使ってC#のWindowsフォーム上に3次元グラフを表示する.

ILNumericsのインストール

現在最新バージョン(4.x系)のILNumericsは14日間のトライアル版以外は有償だが,Community Editionという無償版が提供されていた3.x系のバージョンNuGetでインストール可能なのでそれを使う.

まず,Visual StudioでWindowsフォームアプリケーションを作成する.

そして,プロジェクトを右クリックして「NuGetパッケージの管理」を選択する.オンラインから「ILNumerics」を検索・インストールする.

グラフ表示用コントロールの配置

フォームデザイナを開きツールボックスの適当なところで右クリックして「アイテムの選択(I)...」を選択する.

「.NET Framework コンポーネント」タブの「参照(B)...」ボタンを押して,「(ソリューションのパス)\packages\ILNumerics.3.3.3.0\lib\ILNumerics.dll」を選択したらOK.

するとツールボックスIL○○というコントロールが追加される.その中の,ILPanelコントロールをフォーム上に配置する.

f:id:whoopsidaisies:20141202163400p:plain

使ってみる

曲面

例として,以下の2変数関数を表示させてみる.
z=\frac{\sin(\sqrt{x^2+y^2})}{\sqrt{x^2+y^2}}

まず,コードの適当な場所に以下のusingを書いておく.

using ILNumerics.Drawing;
using ILNumerics.Drawing.Plotting;

そして,フォームロードイベントとかの適当なイベントに以下のコードを書く.

// グラフを格納するオブジェクトの生成
var scene = new ILScene
{
    // 3次元モードでプロット領域を生成
    new ILPlotCube(twoDMode: false)
    {
        // 曲面の生成
        new ILSurface(
            (x,y) => (float)(
                Math.Sin(Math.Sqrt(x*x + y*y))/Math.Sqrt(x*x + y*y)))
    }
};
// 描画用コントロールに生成したグラフをセット
ilPanel1.Scene = scene;

実行すると以下のように3次元グラフが表示される.マウスドラッグとかホイールとかで視点や拡大率を変えられる.

f:id:whoopsidaisies:20141202172655p:plain

等高線

サンプル用の地形データも用意されていて,以下のように使うことが出来る.

var scene = new ILScene
{
    new ILPlotCube(twoDMode: false){
        new ILSurface(ILNumerics.ILMath.tosingle(ILNumerics.ILSpecialData.terrain))
    }
};
ilPanel1.Scene = scene;

f:id:whoopsidaisies:20141202180125p:plain

ここまでは曲面表示のためILSurfaceクラスを使ってきたが,ILContourPlotクラスを使えば以下のように等高線表示も出来る.

var scene = new ILScene
{
    new ILPlotCube{
        new ILContourPlot(ILNumerics.ILMath.tosingle(ILNumerics.ILSpecialData.terrain))
    }
};
ilPanel1.Scene = scene;

f:id:whoopsidaisies:20141202180132p:plain

散布図

ILPointsクラスで散布図を表示させることも出来る.以下はランダムに点を打って対数軸にして表示した例.

ILNumerics.ILArray<float> p = ILNumerics.ILMath.tosingle(ILNumerics.ILMath.rand(3, 10000));
var scene = new ILScene{
    new ILPlotCube(twoDMode:false){
        new ILPoints
        {
            Positions = p,
            Color = null,
            Colors =  p,
            Size = 1,
        }
    }
};
var scaleModes = scene.First<ILPlotCube>().ScaleModes;
scaleModes.XAxisScale = AxisScale.Logarithmic;
scaleModes.YAxisScale = AxisScale.Logarithmic;
scaleModes.ZAxisScale = AxisScale.Logarithmic;

ilPanel1.Scene = scene;

f:id:whoopsidaisies:20141202182150p:plain