门格海绵解决思路:
1. 迭代如何实现
2. 立方体该怎么画
3. 实现门格海绵代码
4. 画图板+门格海绵代码
1. 迭代如何实现
为了实现从1图—>2图—>3图效果,我们就要想到用迭代去实现.
因为像3图这样的图形,是由若干个2图这样的基本图形组成的
那么,怎样实现镂空的效果呢?
观察2图
2图的正方体可以分成3层结构:
下层有8个小正方体,中层有4个,上层有8个.
所以我们现在思考的就是怎样画出基本图形的这三层
但是在画之前,我们先思考一下:哪一层先画呢:?
如果是按上–>中–>下的顺序,我们会得到:
很明显,这和我们所需要的图形是不一致的
所以答案是:下–>中–>上
那么,问题又来了,每一层的的小正方体是按什么顺序画呢?
通过上一个问题的测试,我们可以知道,每一层的正方体,距离我们近的后画,距离我们远的先画,才会达到立方体正确叠加的效果.
2. 立方体该怎么画
好了.确定完上面这些,我们再来确定最基本的问题,正方体该怎么画?
(x,y)正方体正面左上角的点
dx,dy:因为我们在视觉上除了正面是正方形,其余面都是平行四边形,所以增加一个偏移值
d:正方体的边长
有了这些值,我们就可以确定各个顶点的坐标
颜色的话,自由发挥,只要颜色深度:上面>右侧面>正面,且
//上面
int[] xs1={x,x+d,x+d+dx,x+dx};
int[] ys1={y,y,y-dy,y-dy};
g.setColor(new Color(0,50,50));
g.fillPolygon(xs1, ys1, 4);//fillPolygon就是画填充多边形,传进的参数就是x坐标的数组,y坐标的数组,顶点的数量//右侧面
int[] xs2={x+d,x+d+dx,x+d+dx,x+d};
int[] ys2={y,y-dy,y-dy+d,y+d};
g.setColor(new Color(0,100,100));
g.fillPolygon(xs2, ys2, 4);//正面
g.setColor(new Color(0,160,160));
g.fillRect(x, y, d, d);
3. 实现门格海绵代码
因为画正方体的过程是先画最里层,最小的,才有叠加的效果,所以,只要迭代没进行到底,还要继续迭代,再去画正方体
public void drawSponge(Graphics g,int n,int x,int y,int dx,int dy,int d){//n为迭代的层数//从里往外画,从上往下画n--;if(n>0){ //最下层drawSponge(g,n,x+2*dx/3,y-2*dy/3+2*d/3,dx/3,dy/3,d/3);drawSponge(g,n,x+2*dx/3+d/3,y-2*dy/3+2*d/3,dx/3,dy/3,d/3);drawSponge(g,n,x+2*dx/3+2*d/3,y-2*dy/3+2*d/3,dx/3,dy/3,d/3);drawSponge(g,n,x+dx/3,y-dy/3+2*d/3,dx/3,dy/3,d/3);drawSponge(g,n,x+dx/3+2*d/3,y-dy/3+2*d/3,dx/3,dy/3,d/3);drawSponge(g,n,x,y+2*d/3,dx/3,dy/3,d/3);drawSponge(g,n,x+d/3,y+2*d/3,dx/3,dy/3,d/3);drawSponge(g,n,x+2*d/3,y+2*d/3,dx/3,dy/3,d/3);//中间层drawSponge(g,n,x+2*dx/3,y-2*dy/3+d/3,dx/3,dy/3,d/3);drawSponge(g,n,x+2*dx/3+2*d/3,y-2*dy/3+d/3,dx/3,dy/3,d/3);drawSponge(g,n,x,y+d/3,dx/3,dy/3,d/3);drawSponge(g,n,x+2*d/3,y+d/3,dx/3,dy/3,d/3);//最上层drawSponge(g,n,x+2*dx/3,y-2*dy/3,dx/3,dy/3,d/3);drawSponge(g,n,x+2*dx/3+d/3,y-2*dy/3,dx/3,dy/3,d/3);drawSponge(g,n,x+2*dx/3+2*d/3,y-2*dy/3,dx/3,dy/3,d/3);drawSponge(g,n,x+dx/3,y-dy/3,dx/3,dy/3,d/3);drawSponge(g,n,x+dx/3+2*d/3,y-dy/3,dx/3,dy/3,d/3);drawSponge(g,n,x,y,dx/3,dy/3,d/3);drawSponge(g,n,x+d/3,y,dx/3,dy/3,d/3);drawSponge(g,n,x+2*d/3,y,dx/3,dy/3,d/3); }else{int[] xs1={x,x+d,x+d+dx,x+dx};int[] ys1={y,y,y-dy,y-dy};g.setColor(new Color(0,50,50));g.fillPolygon(xs1, ys1, 4);int[] xs2={x+d,x+d+dx,x+d+dx,x+d};int[] ys2={y,y-dy,y-dy+d,y+d};g.setColor(new Color(0,100,100));g.fillPolygon(xs2, ys2, 4);g.setColor(new Color(0,160,160)); g.fillRect(x, y, d, d);} }
4. 画图板+门格海绵代码
我们把门格海绵加到画图板上
并且添加按钮,实现,点击按钮后,根据之后按下的点的坐标画图的效果
画图板类:
import javax.swing.JFrame; //窗体
import javax.swing.JButton; //按钮import java.awt.FlowLayout; //流式布局器
import java.awt.Graphics; //画笔public class DrawPad {public static void main(String args[]){DrawPad dp = new DrawPad();dp.showUI();}public void showUI(){JFrame jf = new JFrame();DrawPadListener dl = new DrawPadListener();JButton btn = new JButton("门格海绵");btn.setName("门格海绵");btn.addActionListener(dl);jf.add(btn);}FlowLayout fl = new FlowLayout();jf.setTitle("可视化"); //名称jf.setSize(800,600); //尺寸jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //关闭进程jf.setLayout(fl); //设置流式布局jf.setResizable(false); //不可以改变窗体大小jf.setLocationRelativeTo(null);//居中显示jf.addMouseListener(dl);jf.setVisible(true); //设置窗体可视Graphics g = jf.getGraphics(); dl.g = g;}}
画图板监听器类:
import java.awt.Color; //颜色
import java.awt.Graphics; //画笔
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;//动作监听器
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener; //鼠标监听器public class DrawPadListener implements MouseListener, ActionListener{ String btnstr;//记录按钮的字符串Graphics g; int x1,x2,y1,y2;int n = 1;//迭代层数,自己去改public void actionPerformed(ActionEvent e){btnstr = e.getActionCommand();System.out.println("actionPerformed方法被调用,btnstr为:"+btnstr); }public void mouseClicked(MouseEvent e){System.out.println("点击"); }public void mousePressed(MouseEvent e){System.out.println("按下");x1=e.getX();y1=e.getY();}public void mouseReleased(MouseEvent e){System.out.println("释放");x2=e.getX();y2=e.getY();//释放点的坐标if(btnstr.equals("门格海绵"))drawSponge(g,n,x1,y1,99,99,198);//数值可以自己改//友情提示:dx,dy,d尽量选择3的倍数,不要海绵上可能会出现一条明显的直线}public void mouseEntered(MouseEvent e){System.out.println("进入");}public void mouseExited(MouseEvent e){System.out.println("退出");}public void drawSponge(Graphics g,int n,int x,int y,int dx,int dy,int d){//从里往外画,从上往下画n--;if(n>0){ //最下层drawSponge(g,n,x+2*dx/3,y-2*dy/3+2*d/3,dx/3,dy/3,d/3);drawSponge(g,n,x+2*dx/3+d/3,y-2*dy/3+2*d/3,dx/3,dy/3,d/3);drawSponge(g,n,x+2*dx/3+2*d/3,y-2*dy/3+2*d/3,dx/3,dy/3,d/3);drawSponge(g,n,x+dx/3,y-dy/3+2*d/3,dx/3,dy/3,d/3);drawSponge(g,n,x+dx/3+2*d/3,y-dy/3+2*d/3,dx/3,dy/3,d/3);drawSponge(g,n,x,y+2*d/3,dx/3,dy/3,d/3);drawSponge(g,n,x+d/3,y+2*d/3,dx/3,dy/3,d/3);drawSponge(g,n,x+2*d/3,y+2*d/3,dx/3,dy/3,d/3);//中间层drawSponge(g,n,x+2*dx/3,y-2*dy/3+d/3,dx/3,dy/3,d/3);drawSponge(g,n,x+2*dx/3+2*d/3,y-2*dy/3+d/3,dx/3,dy/3,d/3);drawSponge(g,n,x,y+d/3,dx/3,dy/3,d/3);drawSponge(g,n,x+2*d/3,y+d/3,dx/3,dy/3,d/3);//最上层drawSponge(g,n,x+2*dx/3,y-2*dy/3,dx/3,dy/3,d/3);drawSponge(g,n,x+2*dx/3+d/3,y-2*dy/3,dx/3,dy/3,d/3);drawSponge(g,n,x+2*dx/3+2*d/3,y-2*dy/3,dx/3,dy/3,d/3);drawSponge(g,n,x+dx/3,y-dy/3,dx/3,dy/3,d/3);drawSponge(g,n,x+dx/3+2*d/3,y-dy/3,dx/3,dy/3,d/3);drawSponge(g,n,x,y,dx/3,dy/3,d/3);drawSponge(g,n,x+d/3,y,dx/3,dy/3,d/3);drawSponge(g,n,x+2*d/3,y,dx/3,dy/3,d/3); }else{int[] xs1={x,x+d,x+d+dx,x+dx};int[] ys1={y,y,y-dy,y-dy};g.setColor(new Color(0,50,50));g.fillPolygon(xs1, ys1, 4);int[] xs2={x+d,x+d+dx,x+d+dx,x+d};int[] ys2={y,y-dy,y-dy+d,y+d};g.setColor(new Color(0,100,100));g.fillPolygon(xs2, ys2, 4);g.setColor(new Color(0,160,160)); g.fillRect(x, y, d, d);} }
}