import java.awt.*; import javax.swing.*; class Mystery extends JPanel implements Runnable { static final double p = 0.8660254; // sqrt(3) / 2 int x = 50, y = 0, z = 0, dx = 0, dy = 1, dz = 0; Thread thread = null; public Mystery() { setPreferredSize(new Dimension(220, 220)); startThread(); } public void startThread() { if (thread == null) { thread = new Thread(this); thread.start(); } } public void stopThread() { thread = null; } @Override public void run() { Thread me = Thread.currentThread(); while (thread == me) { for (int i = 0; i < 50; i++) { x += dx; y += dy; z += dz; repaint(); try { Thread.sleep(40); } catch (InterruptedException e) { } } int tmp = dz; dz = -dx; dx = -dy; dy = -tmp; } } @Override public void paintComponent(Graphics g) { super.paintComponent(g); g.setColor(new Color((int)(x * 255.0 / 50.0), (int)(y * 255.0 / 50.0), (int)(z * 255.0 / 50.0))); double x0 = 0.0 * x + p * y - p * z, y0 = 1.0 * x - 0.5 * y - 0.5 * z; g.fillOval(100 + (int)(x0 * 2), 100 + (int)(y0 * 2), 20, 20); } } void main() { SwingUtilities.invokeLater(() -> { JFrame frame = new JFrame("Mystery!"); frame.add(new Mystery()); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); }); }