The jonki

呼ばれて飛び出てじょじょじょじょーんき

【Java】リサージュ曲線をJavaで描いてみた。

何となく形が気に入ったのでリサージュ曲線なるものをJavaで書いてみました。

動画

プログラム解説

xとyの計算について

度数degを元にそれをラジアンに変えて計算してます。式はコメントにある通り。ラジアンへの変換はこれ使っても良いかと思います。
値を100倍してるのはjavaの描画が単にグラフを大きくしたかったからです。あとintしか受け取りません。フレーム幅・高さの半分を足してるのは描画原点をフレームの中心にするためです。Javaだと(0, 0)は左上の端点だもんね。

Timerについて

描画更新にTimerを使っています。下記プログラムでは10msec間隔でactionPerformed->repaint->paintComponentが呼ばれて描画され続けます。GraphicsクラスとpaintComponentメソッドについてはこのページが参考になるかと。

ソースコード

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;


/**
 * @author junki
 * 
 */

@SuppressWarnings("serial")
public class HeartfulMain extends JPanel implements ActionListener {
	final int frameWidth = 800;
	final int frameHeight = 800;
	int deg = 0;
	Color[] colors = {
			new Color(255, 0, 0), new Color(205, 0, 0), new Color(155, 0, 0), 
			new Color(105,0,0), new Color(55,0,0), new Color(45, 0, 0)
	};
	int[] x = new int[colors.length];
	int[] y = new int[colors.length];
	
	public HeartfulMain() {
	    JFrame frame = new JFrame();
	    frame.getContentPane().add(this);
	    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	    frame.setBounds(100, 10, frameWidth, frameHeight);
	    frame.setVisible(true);
	    frame.setBackground(Color.black);
	}
	
	public void paintComponent(Graphics g){
		//reload values
		x[0] = getX(deg); y[0] = getY(deg);
		for (int i = colors.length - 1; i > 0; i--) {
			x[i] = x[i-1];
			y[i] = y[i-1];
		}
		
		//draw circles
		for (int i = 0; i < colors.length; i++) {
			g.setColor(colors[i]);
			g.fillOval(x[i], y[i], 15, 15);
		}
		deg++;
	}

	//x = 2 sin 2 theta
	int getX (int deg) {
		double dx = 2*Math.sin(2*(deg*(Math.PI/180)));
		int x = (int)(dx*100) + frameWidth / 2;
		return x;
	}
	
	//y = 2 sin 3 theta
	int getY (int deg) {
		double dy = 2*Math.sin(3*(deg*(Math.PI/180)));
		int y = (int)(dy*100) + frameHeight / 2;
		return y;
	}
	
	@Override
	public void actionPerformed(ActionEvent arg0) {
		repaint();
	}
	  
	public static void main(String[] args) {
		HeartfulMain app = new HeartfulMain();
		new Timer(10, app).start();
	}
}