:::::::::::::: CommonView.java :::::::::::::: import java.awt.*; import java.util.*; /** * $Id: composite.html,v 1.1 2009/06/22 16:12:07 kishi Exp kishi $ * @author KISHI Yasuhiro * 2次元座標をリスト化したものを線分で繋いで描画する汎用クラス */ public class CommonView implements Paintable { private java.util.List list; private Color color; public void setModel( java.util.List list, Color color ) { this.list = list; this.color = color; } public void paint( Graphics g ) { for ( int i = 1;i < list.size();i++ ) { g.setColor( color ); double[] from = ( double[] ) list.get( i - 1 ); double[] to = ( double[] ) list.get( i ); g.drawLine( ( int ) from[ 0 ], ( int ) from[ 1 ], ( int ) to[ 0 ], ( int ) to[ 1 ] ); } } } :::::::::::::: CompositeWaveModel.java :::::::::::::: import java.util.*; /** $Id: composite.html,v 1.1 2009/06/22 16:12:07 kishi Exp kishi $ */ public class CompositeWaveModel { private double verticalPosition; /** WaveModelを格納するリスト */ private List waveList; /** 複数個のWaveModelから得られた座標を合成した結果を格納する配列 */ private double[][] compositePoint; /** 計算結果を格納するリスト */ private List pointList; private int count; public CompositeWaveModel( double verticalPosition , int count ) { this.verticalPosition = verticalPosition; this.count = count; waveList = new LinkedList(); pointList = new LinkedList(); compositePoint = new double[ count ][]; for ( int i = 0;i < count;i++ ) { compositePoint[ i ] = new double[ 2 ]; } } public List getList() { return pointList; } public void addWaveModel( WaveModel waveModel ) { waveList.add( waveModel ); } /** 合成した座標の最新の値を求める */ public void recalculate() { // 合計値を初期化 for ( int i = 0;i < count;i++ ) { compositePoint[ i ][ 0 ] = 0.0; compositePoint[ i ][ 1 ] = 0.0; } Iterator iterator = waveList.iterator(); while ( iterator.hasNext() ) { WaveModel model = ( WaveModel ) iterator.next(); // 波モデルが持つ現在の座標をリストで取得 List points = model.getList(); for ( int i = 0;i < count;i++ ) { double[] point = ( double[] ) points.get( i ); // System.out.printf( "X=%8.3f", point[ 0 ] ); // System.out.printf( "Y=%8.3f", point[ 1 ] ); // System.out.println(); // X座標 compositePoint[ i ][ 0 ] = point[ 0 ]; // Y座標には垂直位置の基準点も加算する compositePoint[ i ][ 1 ] += ( point[ 1 ] + verticalPosition ); } } // リストを全クリア pointList.clear(); for ( int i = 0;i < count;i++ ) { double[] point = new double[ 2 ]; point[ 0 ] = compositePoint[ i ][ 0 ]; point[ 1 ] = compositePoint[ i ][ 1 ]; /* System.out.printf( "X=%8.3f", point[ 0 ] ); System.out.printf( "Y=%8.3f", point[ 1 ] ); System.out.println(); */ pointList.add( point ); } } } :::::::::::::: DrawingPanel.java :::::::::::::: import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.io.*; /** $Id: composite.html,v 1.1 2009/06/22 16:12:07 kishi Exp kishi $ @author KISHI Yasuhiro */ public class DrawingPanel extends JPanel implements Runnable { private WaveModel waveModel1, waveModel2; private CompositeWaveModel cwm; private LogisticCurveModel lcModel; private CommonView view1, view2, view3, view4; public DrawingPanel() { int pCount = 160; int pitch = 5; // 波#1 waveModel1 = new WaveModel( 0.0, 50.0 ); waveModel1.setParticleCount( pCount, pitch ); waveModel1.setIntialAngle( 20.0 ); waveModel1.setAnglularSpeed( 45.0 ); waveModel1.setMaxHeight( 50.0 ); waveModel1.setPhasePitch( 15.0 ); waveModel1.init(); view1 = new CommonView(); view1.setModel( waveModel1.getList(), Color.green ); // 波#2 waveModel2 = new WaveModel( 0.0, 75.0 ); waveModel2.setParticleCount( pCount, pitch ); waveModel2.setIntialAngle( 20.0 ); waveModel2.setAnglularSpeed( 60.0 ); waveModel2.setMaxHeight( 75.0 ); waveModel2.setPhasePitch( 25.0 ); waveModel2.init(); view2 = new CommonView(); view2.setModel( waveModel2.getList(), Color.white ); // 合成波 cwm = new CompositeWaveModel( 100.0, pCount ); cwm.addWaveModel( waveModel1 ); cwm.addWaveModel( waveModel2 ); view3 = new CommonView(); view3.setModel( cwm.getList(), Color.red ); // ベルハルストの曲線 lcModel = new LogisticCurveModel( 160, 5, 300 ); lcModel.setBirthRate( 1.0 ); view4 = new CommonView(); view4.setModel( lcModel.getList(), Color.yellow ); /***************************************************************************************/ /** ThreadクラスはRunnableインタフェースで実装されているクラスをrunさせることができる **/ /***************************************************************************************/ Thread thread = new Thread( this ); thread.start(); } public void run() { while ( true ) { SwingUtilities.invokeLater( new Runnable() { public void run() { repaint(); } } ); try { Thread.sleep( 100 ); } catch ( Exception e ) { e.printStackTrace(); } } } public void paintComponent( Graphics g ) { int width = getWidth(); int height = getHeight(); // 画面クリア g.setColor( Color.black ); // このコンポーネントのサイズを取得する g.fillRect( 0 , 0 , width , height ); // 波#1 waveModel1.move( ); view1.paint( g ); // 波#2 waveModel2.move( ); view2.paint( g ); // 合成波 //System.out.println( cwm.getList().size()); cwm.recalculate( ); view3.paint( g ); // ベルハルストの曲線 g.setColor( Color.yellow ); StringBuilder message = new StringBuilder( "■ベルハルストの曲線 -- " ); try { String currentBirthRate = sprintf( "%8.2f", lcModel.getBirthRate() ); message.append( currentBirthRate ); } catch ( Exception e ) { e.printStackTrace(); } g.drawString( message.toString(), 10, 280 ); lcModel.generate(); view4.paint( g ); lcModel.augmentBirthRate( 0.01 ); if ( lcModel.getBirthRate() > 5.0 ) { lcModel.setBirthRate( 1.0 ); } } static String sprintf( String format, Object obj ) throws Exception { String value = null; try { // C言語のsprinfもどき ByteArrayOutputStream baos = new ByteArrayOutputStream(); PrintWriter pw = new PrintWriter( baos ); pw.printf( format, obj ); pw.flush(); pw.close(); value = baos.toString( "UTF8" ); baos.close(); } catch ( Exception e ) { throw e; } finally { return value; } } } :::::::::::::: LogisticCurveModel.java :::::::::::::: import java.util.*; /** $Id: composite.html,v 1.1 2009/06/22 16:12:07 kishi Exp kishi $ */ public class LogisticCurveModel { private double birthRate; private List list; private int pCount; private int pitch; private double verticalPosition; public LogisticCurveModel( int pCount, int pitch, double verticalPosition ) { this.pCount = pCount; this.pitch = pitch; this.verticalPosition = verticalPosition; list = new LinkedList(); } public List getList() { return list; } public void setBirthRate( double birthRate ) { this.birthRate = birthRate; } public double getBirthRate() { return birthRate; } public void augmentBirthRate( double value ) { birthRate += value; } public void generate() { double height = 0.01; list.clear(); for ( int i = 0;i < pCount;i++ ) { height = birthRate * height * ( 1 - height ); if ( Math.abs( height * 100.0 ) >= 600.0 ) { // System.out.println("*** overflowed ***"); break; } double[] point = new double[ 2 ]; point[ 0 ] = i * pitch; point[ 1 ] = verticalPosition + height * 100.0; list.add( point ); } } static public void main( String[] args ) { if ( args.length != 1 ) { System.out.println( "Usage: java LogisticCurveModel [birthRate]" ); System.exit( 1 ); } LogisticCurveModel lcModel = new LogisticCurveModel( 160, 5, 0 ); double birthRate = new Double( args[ 0 ] ).doubleValue(); lcModel.setBirthRate( birthRate ); lcModel.generate(); List list = lcModel.getList(); Iterator iterator = list.iterator(); int i = 0; while ( iterator.hasNext() ) { double[] point = ( double[] ) iterator.next(); System.out.printf( "%3d: %8.3f\n", i, point[ 1 ] ); i++; } } } :::::::::::::: Paintable.java :::::::::::::: import java.awt.*; /** $Id: composite.html,v 1.1 2009/06/22 16:12:07 kishi Exp kishi $ @author KISHI Yasuhiro */ public interface Paintable { public void paint( Graphics g ); } :::::::::::::: WaveGenerator.java :::::::::::::: import javax.swing.*; import java.awt.*; import java.awt.event.*; /** * $Id: composite.html,v 1.1 2009/06/22 16:12:07 kishi Exp kishi $ * @author KISHI Yasuhiro */ public class WaveGenerator extends JApplet { public void init() { Container contentPane = getContentPane(); contentPane.setLayout( new FlowLayout() ); DrawingPanel dp = new DrawingPanel(); dp.setPreferredSize( new Dimension( 800 , 600 ) ); contentPane.add( dp ); } } :::::::::::::: WaveModel.java :::::::::::::: import java.util.*; /** $Id: composite.html,v 1.1 2009/06/22 16:12:07 kishi Exp kishi $ @author KISHI Yasuhiro */ public class WaveModel { private List list; private double angle; private int count; private int horizontalPitch; private double x, y, maxHeight, phasePitch, angularSpeed; public WaveModel( double x, double y ) { this.x = x; this.y = y; } /** 粒子の数と水平のピッチを決める @param count 粒子の数 @param horizontalPitch 粒子同士の水平の間隔 */ public void setParticleCount( int count, int horizontalPitch ) { this.count = count; this.horizontalPitch = horizontalPitch; } public void setIntialAngle( double initialAngle ) { this.angle = initialAngle; } public void setMaxHeight( double maxHeight ) { this.maxHeight = maxHeight; } public void setPhasePitch( double phasePitch ) { this.phasePitch = phasePitch; } public void setAnglularSpeed( double angularSpeed ) { this.angularSpeed = angularSpeed; } /** 初期状態をセットする */ public void init() { list = new ArrayList(); for ( int i = 0;i < count;i++ ) { double point[] = new double[ 2 ]; point[ 0 ] = x + i * horizontalPitch; point[ 1 ] = y + getVerticalDisplacement( i ); list.add( point ); } } /** 角速度分移動する */ public void move( ) { angle += angularSpeed; for ( int i = 0;i < list.size();i++ ) { // 各々のY座標を変更する rotate( ( double[] ) list.get( i ), i ); } } public List getList() { return this.list; } /** 垂直方向の変位を求める */ private double getVerticalDisplacement ( int i ) { return maxHeight * Math.sin( ( angle + i * phasePitch ) * Math.PI / 180.0 ); } private void rotate( double[] point, int i ) { point[ 1 ] = y + getVerticalDisplacement( i ); } public void dump() { System.out.println( "angle=" + angle ); for ( int i = 0;i < list.size();i++ ) { double[] point = ( double[] ) list.get( i ); System.out.print( "(x=" + point[ 0 ] ); System.out.print( " " ); System.out.print( "y=" + point[ 1 ] + ")" ); System.out.print( " " ); } System.out.println(); } static public void main( String[] args ) { WaveModel wm = new WaveModel( 0.0, 0.0 ); wm.setParticleCount( 5, 10 ); wm.setMaxHeight( 30.0 ); wm.setIntialAngle( 20.0 ); wm.setAnglularSpeed( 6 ); wm.setPhasePitch( 15.0 ); wm.init(); wm.dump(); for ( int i = 0;i < 3;i++ ) { wm.move( ); wm.dump(); } } }戻る