何となく形が気に入ったのでリサージュ曲線なるものを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(); } }