1 packagedemo;2
3 importjava.awt.Color;4 importjava.awt.Graphics;5
6 importjavax.swing.JFrame;7 importjavax.swing.JPanel;8
9 /**
10 * Java Cardioid 心脏形曲线 (整理)11 * 这是以前看到有关Cardioid一个故事之后,觉得好玩,那时把它实现了。12 *13 * 2016-1-2 深圳 南山平山村 曾剑锋14 */
15 public class Cardioid extendsJPanel{16 /**
17 *
- 18 *
- centerX:代表x轴中心点坐标19 *
- centerY:代表y轴中心店坐标20 *
25 static int centerX = 600/2;26 static int centerY = 600/2;27 /**
28 * angle:主要用于角度计算,下面程序中的for循环里的变量,360一个周期29 */
30 intangle;31 /**
32 *
- 33 *
- a:窗口中有2个心形图,a是其中一个的幅值34 *
- b:窗口中有2个心形图,b是其中一个的幅值35 *
38 int a = 0;39 int b = 50;40 /**
41 * 构造函数调用start()函数。
42 * 作用:开启一个线程,主要用于调整a、b的值,并刷新界面。43 */
44 publicCardioid() {45 start();46 }47 /**
48 * 重写paint()
49 * 程序流程:
- 50 *
- 调用父类paint方法、并设置背景颜色为黑色51 *
- 用for循环画两个发散的心形图52 *
54 @Override55 public voidpaint(Graphics graphics) {56 super.paint(graphics);57 this.setBackground(Color.black);58 graphics.setColor(Color.red);59 /*
60 * 这里是难点,主要是因为需要对坐标进行定位,下面是获取x、y的坐标公式,你可以在网上查到61 * x=a*(2*sin(t)-sin(2*t))62 * y=a*(2*cos(t)-cos(2*t))63 * 这里的x、y和网上的公式对调了,主要是因为需要进行y=x对称,网上的图是横着的,这个图是正着的。64 * sin()函数传入的是弧度制,所以需要通过angle*Math.PI/180,将角度值换成幅度值65 * 其中的500主要是用于坐标调整的,没有理由,是我自己试出来的,我也没有去深究为什么,因为功能完成了。66 */
67 for (angle = 0; angle < 360; angle++) {68 graphics.drawLine(69 centerY+(int)(a*(2*Math.sin(angle*Math.PI/180)-Math.sin(2*angle*Math.PI/180))),70 500 -(centerX+(int)(a*(2*Math.cos(angle*Math.PI/180)-Math.cos(2*angle*Math.PI/180)))),71 centerY+(int)((a+3)*(2*Math.sin((angle)*Math.PI/180)-Math.sin(2*(angle)*Math.PI/180))),72 500 -(centerX+(int)((a+3)*(2*Math.cos((angle)*Math.PI/180)-Math.cos(2*(angle)*Math.PI/180)))));73 }74 for (angle = 0; angle < 360; angle++) {75 graphics.drawLine(76 centerY+(int)(b*(2*Math.sin(angle*Math.PI/180)-Math.sin(2*angle*Math.PI/180))),77 500 -(centerX+(int)(b*(2*Math.cos(angle*Math.PI/180)-Math.cos(2*angle*Math.PI/180)))),78 centerY+(int)((b+3)*(2*Math.sin((angle)*Math.PI/180)-Math.sin(2*(angle)*Math.PI/180))),79 500 -(centerX+(int)((b+3)*(2*Math.cos((angle)*Math.PI/180)-Math.cos(2*(angle)*Math.PI/180)))));80 }81 }82 /**
83 * 创建一个匿名线程,线程主要完成以下事情:
- 84 *
- 改变a、b的值,相当于改变心形线的幅值;85 *
- 延时20ms;86 *
- 刷新界面repaint();87 *
89 public voidstart() {90 new Thread(newRunnable() {91
92 @Override93 public voidrun() {94 while (true) {95 try{96 if (a++ >100) {97 a = 0;98 }99 if (b++ >100) {100 b = 0;101 }102 Thread.sleep(20);103 repaint();104 } catch(InterruptedException e) {105 e.printStackTrace();106 }107 }108
109 }110 }).start();111 }112 /**
113 * 主函数完成以下内容:
- 114 *
- 初始化jframe窗口;115 *
- 创建cardioid,并将cardioid填充到jFrame中;116 *
- 设置jFrame可见。117 *
119 public static voidmain(String[] args) {120 JFrame jFrame = newJFrame();121 jFrame.setTitle("Cardioid");122 jFrame.setSize(centerX*2, centerY*2);123 jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);124 jFrame.setLocationRelativeTo(null);125
126 Cardioid cardioid = newCardioid();127 jFrame.add(cardioid);128 jFrame.setVisible(true);129 }130 }