分形与数据结构第一篇(神奇的色子)
一、任务:
能够实现这次的小图形,不得不说真的很开心。图形出来的瞬间真的很激动,之前的纠结,郁闷一扫而空。我想这就是程序的魅力吧。
这次的任务是
1.平面上随机选A,B,C三个点。再随机选一个点,记为P。
2.有一个三面色子,每丢一次,则选中ABC三个中一点。
开始游戏:
1.重复丢色子,如果选中A,则取A和P的中点P1,画黑,
2.如果选中B,则取B和P1的中点P2,画黑
3.如果选中A,则取A和P2的中点P3,画黑
4….一直重复(如每点一下鼠标,丢10000次色子
二、思路:
1.通过确立事件源,来确定监听方法,这里和画图的基本相识;
2.加上监听机制之后,public void mouseClicked(MouseEvent e) {}方法中取得三点,(当然在其他的方法中取得也是一样的),取得三个点,并且存好(这是重点),再随机选一个点,记为P。其他的当做分别作为abc点。
3.加上一个for循环,每点击一次循环10000次,丢10000次色子;
4.在for循环中确认丢色子的方法:利用随机数,int s = rand.nextInt(3);随机值取0,1,2.当取零时,选中的是A;当取1时,抛出的色子是B,当取2时,抛出的是C;
5.先求出中点,再来画线。因为是中点都会变化,所以画完之后要改变它的值。
三、程序:
package fenxingshuzu; import java.awt.Color; import java.awt.FlowLayout; import java.awt.Graphics; import java.awt.Graphics2D; import javax.swing.JFrame; /* * 1.新建一个listener类事件处理类继承MouseListener; * 2.新建Tuxing类,实现窗口,实现画布; * 3.把Tuxing类中的画布传到Listener类中去:首先在Listener类中声明对象,在先建一个方法来取得画布; * 在Tuxing类中实例化一个Listener对象,调用刚刚定义的方法,把Listener的画布传过去。 */ public class Tuxing { public static void main(String[] args){ Tuxing T=new Tuxing (); T.initUT(); } public void initUT(){ JFrame jf=new JFrame();//实例化一个JFrame对象; jf.setTitle("分形和数据结构");//设置窗体的标题; jf.setSize(400, 500);//窗体的大小 jf.setLayout(new FlowLayout());//设置窗体的布局为流失布局; jf.setVisible(true);//设置窗体可见; jf.setLocationRelativeTo( null);//设置窗体显示的位置; jf.setDefaultCloseOperation(3);//设置关闭窗体的按钮; Graphics g=jf.getGraphics();//设置画布; jf.getContentPane().setBackground(Color.WHITE);//设置窗体画布的颜色; ((Graphics2D) g).setColor(Color.BLUE);//转化g的类型,Graphics2D是Graphics的子类; //设置画笔的颜色; Listener l=new Listener(); l.setG(g); jf.addMouseListener(l); } }
Tuxing.java
Listener.java
import java.awt.Graphics; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.util.Random; /* * 1.实例化接口中的方法; * 2.设置8个变量来存储ABCP四个点的坐标; * 3.定义一个变量i实现随机数; * 4.定义一个变量Count来实现存储四个数ABCP的坐标; * ctrl+shift+f,调整程序结构; */ public class Listener implements MouseListener { Graphics g; private int x1, y1, x2, y2, x3, y3, x4, y4;//x, y, private int i;//, ex, ey; int count = 0; private Random rand = new Random();/*之前是在for循环中定义实例化的rand,增加了时间复杂度和空间复杂度, 每次循环都会实例化一个rand变量,所以不要再循环中定义变量; */ public void setG(Graphics g) { this.g = g; }//利用快捷键可以添加。单击右键,点击Sourse(shift+alt+s),然后点击Generate Getters and Setters; public void mouseClicked(MouseEvent e) { if (count < 4){ //用变量控制存储四个值; // x = e.getX(); // y = e.getY(); g.drawLine(e.getX(), e.getY(), e.getX(), e.getY()); /* * 之前是写的四个并列的if语句,所以每执行一次都会调用所有的if语句,同样的增加了程序运行的时间,增加了时间复杂度; * 所有要加上else if;来减少程序运行的时间。 */ if (count == 0){//存储第一个值A x1 = e.getX();//之前是写的x1=x;这样增加了空间复杂度,时间复杂度; y1 = e.getY();//改成x1=e.getY();可以少定义一个变量;减少占用的空间; } else if (count == 1) {//存储第二个值B x2 = e.getX(); y2 = e.getY(); } else if (count == 2) {//存储第三个值C x3 = e.getX(); y3 = e.getY(); } else if (count == 3) {//存储第四个值P; x4 = e.getX(); y4 = e.getY(); } count++; } if (e.getClickCount() == 2) { for (i = 0; i <= 10000; i++) { int s = rand.nextInt(3);//这个不能放在for循环外边;随机数的大小;0到3;取值取0,1,2; if (s == 0) {//当随机数取0时,色子面为A; x4 = (x1 + x4) / 2; y4 = (y1 + y4) / 2; } else if (s == 1) {//当随机数取1时,色子面为B; x4 = (x2 + x4) / 2; y4 = (y2 + y4) / 2; } else {//当随机数取2时,色子面为C。 x4 = (x3 + x4) / 2; y4 = (y3 + y4) / 2; } g.drawLine(x4, y4, x4, y4); /*之前的写法: * ex = (x1 + x4) / 2; ey = (y1 + y4) / 2; g.drawLine(ex, ey, ex, ey); x4 = ex; y4 = ey; 虽然程序没有错但是增加了一个变量,程序运行所需要的空间增加了; 而且每个if语句中都是相同的(画线是在if语句中画,画完在转化);没有简化语句,没有把相同的语句拿出来;增加程序运行的时间; 也就是增加了程序的时间和空间复杂度;所以应该注意当所有if语句中,有些语句是一样的时可以挑出来写,写在程序外面;要学会减少不必要的语句;*/
} count = 0;//count值变为0,然后开始下一个图形。不然只能画一个图形;
}
}
public void mousePressed(MouseEvent e) {
/* * // ((Graphics2D )g).setStroke(new BasicStroke(10));
if(count<4){ x= * e.getX(); y = e.getY(); g.drawLine(x, y, x, y);
else if(count==0){ x1=x; * y1=y; } if(count==1){ x2=x; y2=y; } if(count==2){ x3=x; y3=y; }
* else if(count==3){ x4=x; y4=y; } count++; } */ }
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override public void mouseExited(MouseEvent e) {
}
}
运行结果:
四:注意点:
要注意程序的时间和空间复杂度;
1.申明定义变量不要在循环中;
2.相同的代码不要重复;在if语句中,要实现的功能一样时,可以提出来写;
3.尽量减少变量的定义,简化程序;
4.在使用if语句是。还有并列的if语句是,要用else if语句。减少时间和空间复杂度。
首先,理清楚思路再来写程序。