倭マン's BLOG

くだらない日々の日記書いてます。 たまにプログラミング関連の記事書いてます。 書いてます。

クリスマス・イヴに3次元プロットw

以前の記事で、Griffon を使って3次元プロットを行う プラグイン Jzy3d Plugin の使い方を見ました。 そこではプラグインのインストール方法やソースの配置場所などを見ただけだったので、今回はプロットを行うソースをイジってみます。

Jzy3d プラグイン


Jzy3d では

  

というタイプの関数をプロットできます。 他にも Scatter Chart (散布図)も描画できるようです(今回は扱いませんが)。

プロットを行う手順は

  1. 関数を表す Mapper オブジェクトを作成
  2. Mapper オブジェクトと定義域やサンプル数などの情報を合わせた Shape オブジェクトを生成(必要なら設定を行う)
  3. チャートの Shape オブジェクトをセット

といった感じです。 z = f(x, y) の形の関数をプロットしたい場合、Mapper オブジェクトに (x, y) の値から z を計算するアルゴリズムを実装します。

サンプル・コード


ここでは、ちょっと複雑ですが、以下のような関数をプロットします:

極座標
  
を用いて
  
ただし
  

あくまで (x, y) の組が与えられて z を計算する式です。 z を与える式は3つ目です。 r, θ, R は (x, y) の値から計算できる補助変数です。 これをコードで書くと以下のようになります:

import org.jzy3d.colors.Color
import org.jzy3d.colors.ColorMapper
import org.jzy3d.colors.colormaps.ColorMapWhiteRed
import org.jzy3d.maths.Range
import org.jzy3d.plot3d.builder.Builder
import org.jzy3d.plot3d.builder.Mapper
import org.jzy3d.plot3d.builder.concrete.OrthonormalGrid
import org.jzy3d.plot3d.rendering.legends.colorbars.ColorbarLegend
import static java.lang.Math.*

class DefaultChart3D {
    void mvcGroupInit(Map<String, ?> args) {
        initChart()
    }

    void initChart(){
        // 1. プロットする関数の定義 z = f(x, y) のアルゴリズムを実装
        Mapper mapper = new Mapper(){
            public double f(double x, double y) {
                if(x < -1.59 && y < -1.59)return 2.0d    // この部分は本質的ではありません

                double r = hypot(x, -y)    // -y にしてるのは描画の都合上
                double theta = atan2(-y, x)    // -y にしてるのは描画の都合上

                double cosTheta = cos(theta), sinTheta = sin(theta)
                double cbrt_cosTheta = cbrt(cosTheta)

                double X = cosTheta, Y = sinTheta + cbrt_cosTheta*cbrt_cosTheta - 0.5d
                double R = hypot(X, Y)

                if(r > R)
                   return -1.0d    // この部分は本質的ではありません
                else
                   return sqrt(1.0d - r/R)
            }
        }

        // 2. 与えられた範囲・サンプル数での関数を表す Shape オブジェクトを生成・設定
        def range = new Range(-1.6d, 1.6d)    // x, y の範囲
        int steps = 320                                  // x, y のサンプル数
        
        def surface = Builder.buildOrthonormal(new OrthonormalGrid(range, steps, range, steps), mapper)
        surface.with{
            colorMapper = new ColorMapper(new ColorMapWhiteRed(), surface.bounds.zmin, surface.bounds.zmax)
            faceDisplayed = true
            wireframeDisplayed = false
            wireframeColor = Color.RED
            legend = new ColorbarLegend(surface, chart.view.axe.layout)
        }
        
        // 3. チャートに関数をセット
        chart.scene.graph.add(surface)
    }
}

このプロットを実行すると(実行方法は以前の記事参照)、以下のようなチャートが表示されるハズです:


ハート3D! イェーイw 皆様、よいクリスマス・イヴを。

参考 URL

  • ハート型のグラフについては「THE LOVE FORMULA」の平面ハートを参考にしました。 数式の原型は留めてませんが。

プログラマの数学

プログラマの数学


プログラミングGROOVY

プログラミングGROOVY