3次元グラフ
C言語による最新アルゴリズム事典 (ソフトウェアテクノロジー)
- 作者: 奥村晴彦
- 出版社/メーカー: 技術評論社
- 発売日: 1991/03/01
- メディア: 単行本
- 購入: 20人 クリック: 396回
- この商品を含むブログ (95件) を見る
y = f( x, z )の関数を3次元のグラフで表現するというものです。
以下は、y = exp( - ( x * x + z * z ) ) * cos( 10 * sqrt( ( x * x + z * z ) )を描いた結果です。
以下は、これを描くためのJavaコードです。
主要なアルゴリズムの箇所は、事典の内容をそのままです。
描画メソッド(move_()、draw()とpaint())のみ自前で用意しています。
import java.util.*; import java.awt.*; import javax.swing.*; /** * 三次元グラフのウィンドウ */ public class ThreeDimensionGraph extends JFrame { /** * メインルーチン */ public static void main( String arsg ) { // 三次元グラフのウィンドウを起動する。 new ThreeDimensionGraph(); } /** * 三次元グラフのウィンドウを起動する。 */ public ThreeDimensionGraph() { // 閉じるボタンのクリック時、ウィンドウを破棄する。 setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE ); // ウィンドウのサイズを設定する。 setSize(1000, 600); // ウィンドウを表示する。 setVisible( true ); // 描画アルゴリズムを実行する。 drawFunction(); } ////////////////////////////////////////////// // 描画アルゴリズム START ////////////////////////////////////////////// private static final double Xmin = -1; private static final double Ymin = -1; private static final double Zmin = -1; private static final double Xmax = 1; private static final double Zmax = 1; private static final double Ymax = 1; /** * 描画アルゴリズムを実行する。 */ private void drawFunction() { double x, y, z; int i, ix, iz; boolean ok, ok1; double lowerhorizon = new double[241]; double upperhorizon[] = new double[241]; for ( i = 0; i <= 240; ++i ) { lowerhorizon[i] = Float.MAX_VALUE; upperhorizon[i] = Float.MIN_VALUE; } for ( iz = 0; iz <= 20; ++iz ) { z = Zmin + ( Zmax - Zmin ) / 20 * iz; ok1 = false; for ( ix = 0; ix <= 200; ++ix ) { x = Xmin + ( Xmax - Xmin ) / 200 * ix; i = ix + 2 * ( 20 - iz ); y = 30 * ( func( x, z ) - Ymin ) / ( Ymax - Ymin ) + 5 * iz; ok = false; if ( y < lowerhorizon[i] ) { lowerhorizon[i] = y; ok = true; } if ( y > upperhorizon[i] ) { upperhorizon[i] = y; ok = true; } if ( ok && ok1 ) draw( i, y ); else move_( i, y ); ok1 = ok; } } } ////////////////////////////////////////////// // 描画アルゴリズム END ////////////////////////////////////////////// /** * 描画対象の関数 */ private double func( double x, double z ) { double r2; r2 = x * x + z * z; return Math.exp( -r2 ) * Math.cos( 10 * Math.sqrt( r2 ) ); } // ペンの座標 private Coordinate pen; // 線分のリスト private java.util.Listlines = new ArrayList (); /** * 線分のリストの内容を描画する。 */ public void paint( Graphics g ) { // 表示内容をクリアする。 g.clearRect( 0, 0, 1000, 600 ); // リスト中のすべての線分を表示する。 // うまく表示できるように座標の補正を行う。 for ( Line line : lines ) { g.drawLine( adjust( line.start().x() ), 600 - adjust( line.start().y() ), adjust( line.end().x() ),600 - adjust( line.end().y() ) ); } } /** * double型の座標値を補正し、int型にする。 * @param d 補正前の座標値 * @return 補正後の座標値 */ private int adjust( double d ) { return (int) ( d * 4.0 ); } /** * 線分をリストに追加する。 */ private void draw( double x, double y ) { // ペンの座標から指定した座標までの線分をリストに追加する。 Coordinate temp = new Coordinate().x( x ).y( y ); lines.add( new Line().start( pen ).end( temp ) ); // ペンの座標を指定した座標に変更する。 pen = new Coordinate().x( x ).y( y ); } /** * ペンの座標を指定した座標に変更する。 * @param x X座標 * @param y Y座標 */ private void move_( double x, double y ) { pen = new Coordinate().x( x ).y( y ); } private Container contentPane() { return getContentPane(); } } /** * 線分 */ class Line { private Coordinate start; // 始点の座標 private Coordinate end; // 終点の座標 /** * 始点の座標を設定する。 * @param start 始点の座標 * @return 自分 */ public Line start( Coordinate start ) { this.start = start; return this; } /** * 終点の座標を設定する。 * @param end 終点の座標 * @return 自分 */ public Line end( Coordinate end ) { this.end = end; return this; } /** * 始点の座標を取得する。 * @return 始点の座標 */ public Coordinate start() { return start; } /** * 終点の座標を取得する。 * @return 終点の座標 */ public Coordinate end() { return end; } } /** * 座標 */ class Coordinate { private double x; // X座標 private double y; // Y座標 /** * X座標を設定する。 * @param x X座標 * @return 自分 */ public Coordinate x( double x ) { this.x = x; return this; } /** * Y座標を設定する。 * @param y Y座標 * @return 自分 */ public Coordinate y( double y ) { this.y = y; return this; } /** * X座標を取得する。 * @param X座標 */ public double x() { return x; } /** * Y座標を取得する。 * @param Y座標 */ public double y() { return y; } }
何かに使えないだろうか・・・。