続・3次元グラフ
d:id:nattou_curry_2:20081005:1223214031の続きです。
パラメータをいじくって、グラフの見え方を変更できるようにしました。
操作できるパラメータは、以下の五つです。
- X軸の倍率
- Z軸の倍率
- Y軸の倍率
- ZX平面の傾き
- ZY平面の傾き
Javaソース
import java.util.*; import java.awt.*; import java.awt.event.*; import javax.swing.*; public class ThreeDimensionGraph extends JFrame implements Parameter { public static void main( String arsg ) { new ThreeDimensionGraph(); } private JTextField Xpower = new JTextField( "200" ); private JTextField Zpower = new JTextField( "20" ); private JTextField Ypower = new JTextField( "30" ); private JTextField ZXtilt = new JTextField( "2" ); private JTextField ZYtilt = new JTextField( "5" ); private Canvas canvas = new Canvas(); private GraphAlgorithm algorithm = new GraphAlgorithm().parameter( this ).canvas( canvas ).function( new Function() ); public ThreeDimensionGraph() { setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE ); setSize(400, 150); layoutContentPane( getContentPane() ); setVisible( true ); algorithm.draw(); } public int Xpower() { return textFieldToInt( Xpower ); } public int Zpower() { return textFieldToInt( Zpower ); } public int Ypower() { return textFieldToInt( Ypower ); } public int ZXtilt() { return textFieldToInt( ZXtilt ); } public int ZYtilt() { return textFieldToInt( ZYtilt ); } public int textFieldToInt( JTextField textField ) { try { return Integer.parseInt( textField.getText() ); } catch ( ArithmeticException e ) { return 0; } } private void layoutContentPane( Container container ) { JPanel panel = new JPanel(); layoutInputForm( panel ); container.setLayout( new BorderLayout() ); container.add( canvas, BorderLayout.CENTER ); container.add( panel, BorderLayout.EAST ); } private void layoutInputForm( Container container ) { container.setLayout( new GridLayout( 0, 2, 0, 0 ) ); container.add( new JLabel( "X軸の倍率" ) ); container.add( Xpower ); container.add( new JLabel( "Z軸の倍率" ) ); container.add( Zpower ); container.add( new JLabel( "Y軸の倍率" ) ); container.add( Ypower ); container.add( new JLabel( "ZX平面の傾き" ) ); container.add( ZXtilt ); container.add( new JLabel( "ZY平面の傾き" ) ); container.add( ZYtilt ); container.add( attachEvent( new JButton( "再描画" ) ) ); } private JButton attachEvent( JButton button ) { button.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { algorithm.draw(); } } ); return button; } } interface Parameter { public int Xpower(); // Xの倍率 public int Zpower(); // Zの倍率 public int Ypower(); // Yの倍率 public int ZXtilt(); // Z軸とX軸のの傾き public int ZYtilt(); // Z軸とY軸の傾き } /** * 主要なアルゴリズム */ class GraphAlgorithm { 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 Parameter param; private int hoge; private Canvas canvas; private Function func; public GraphAlgorithm function( Function func ) { this.func = func; return this; } public GraphAlgorithm parameter( Parameter param ) { this.param = param; this.hoge = param.Xpower() + param.Zpower() * param.ZYtilt(); return this; } public GraphAlgorithm canvas( Canvas canvas ) { this.canvas = canvas; return this; } public void draw() { double x, y, z; int i, ix, iz; boolean ok, ok1; double lowerhorizon = new double[hoge + 1]; double upperhorizon[] = new double[hoge + 1]; canvas.clear(); for ( i = 0; i <= hoge; ++i ) { lowerhorizon[i] = Float.MAX_VALUE; upperhorizon[i] = Float.MIN_VALUE; } for ( iz = 0; iz <= param.Zpower(); ++iz ) { z = Zmin + ( Zmax - Zmin ) / param.Zpower() * iz; ok1 = false; for ( ix = 0; ix <= param.Xpower(); ++ix ) { x = Xmin + ( Xmax - Xmin ) / param.Xpower() * ix; i = ix + param.ZXtilt() * ( param.Zpower() - iz ); y = param.Ypower() * ( func.func( x, z ) - Ymin ) / ( Ymax - Ymin ) + param.ZYtilt() * iz; ok = false; if ( y < lowerhorizon[i] ) { lowerhorizon[i] = y; ok = true; } if ( y > upperhorizon[i] ) { upperhorizon[i] = y; ok = true; } if ( ok && ok1 ) canvas.draw( i, y ); else canvas.move_( i, y ); ok1 = ok; } canvas.repaint(); } } } /** * 描画する関数 */ class Function { public double func( double x, double z ) { double r2; r2 = x * x + z * z; return Math.exp( -r2 ) * Math.cos( 10 * Math.sqrt( r2 ) ); } } class Canvas extends Panel { private Coordinate pen; private java.util.Listlines = new ArrayList (); public void paint( Graphics g ) { g.clearRect( 0, 0, getWidth(), getHeight() ); for ( Line line : lines ) { g.drawLine( adjust( line.start().x() ), getHeight() - adjust( line.start().y() ), adjust( line.end().x() ),getHeight() - adjust( line.end().y() ) ); } } private int adjust( double d ) { return (int) d; } public void clear() { lines = new ArrayList (); repaint(); } public 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 ); } public void move_( double x, double y ) { pen = new Coordinate().x( x ).y( y ); } } class Line { private Coordinate start; private Coordinate end; public Line start( Coordinate start ) { this.start = start; return this; } public Line end( Coordinate end ) { this.end = end; return this; } public Coordinate start() { return start; } public Coordinate end() { return end; } } class Coordinate { private double x; private double y; public Coordinate x( double x ) { this.x = x; return this; } public Coordinate y( double y ) { this.y = y; return this; } public double x() { return x; } public double y() { return y; } }