Java拾遺(五)
- 分形
-
-
- MengerSponge的實作(僅畫出過程)
-
分形
MengerSponge的實作(僅畫出過程)
package drawpadListener;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Polygon;
import javax.swing.JFrame;
public class TRY extends JFrame{
public void paintMenger(Graphics g, int t){
int x=100,y=600;//正方體的頂點坐标
int d=100,dx=65,dy=50; //正方體的高,寬深度
//畫出來
paintOneMenger(g, x, y, d, dx, dy, t);
}
public void paintOneMenger(Graphics g, int x, int y, int d, int dx, int dy, int t){
t--;//疊代次數
//下層
Point p00=new Point(x,y);
Point[] ps01=getPointByP0(p00, d, dx, dy);
Point[] ps02=getPointByP0(ps01[3], d, dx, dy);
Point[] ps03=getPointByP0(ps02[3], d, dx, dy);
Point[] ps04=getPointByP0(ps01[6], d, dx, dy);
Point[] ps05=getPointByP0(ps02[6], d, dx, dy);//不畫
Point[] ps06=getPointByP0(ps03[6], d, dx, dy);
Point[] ps07=getPointByP0(ps04[6], d, dx, dy);
Point[] ps08=getPointByP0(ps05[6], d, dx, dy);
Point[] ps09=getPointByP0(ps06[6], d, dx, dy);
draw(g, ps07[0], ps07[1], ps07[2], ps07[3], ps07[4], ps07[5], ps07[6]);
if(t>0){
paintOneMenger(g, ps07[0].x, (ps07[0].y+d/3*2), d/3, dx/3, dy/3, t);
}
draw(g, ps08[0], ps08[1], ps08[2], ps08[3], ps08[4], ps08[5], ps08[6]);
if(t>0){
paintOneMenger(g, ps08[0].x, (ps08[0].y+d/3*2), d/3, dx/3, dy/3, t);
}
draw(g, ps09[0], ps09[1], ps09[2], ps09[3], ps09[4], ps09[5], ps09[6]);
if(t>0){
paintOneMenger(g, ps09[1].x, (ps09[0].y+d/3*2), d/3, dx/3, dy/3, t);
}
draw(g, ps04[0], ps04[1], ps04[2], ps04[3], ps04[4], ps04[5], ps04[6]);
if(t>0){
paintOneMenger(g, ps04[1].x, (ps04[0].y+d/3*2), d/3, dx/3, dy/3, t);
}
draw(g, ps06[0], ps06[1], ps06[2], ps06[3], ps06[4], ps06[5], ps06[6]);
if(t>0){
paintOneMenger(g, ps06[1].x, (ps06[0].y+d/3*2), d/3, dx/3, dy/3, t);
}
draw(g, ps01[0], ps01[1], ps01[2], ps01[3], ps01[4], ps01[5], ps01[6]);
if(t>0){
paintOneMenger(g, ps01[1].x, (ps01[0].y+d/3*2), d/3, dx/3, dy/3, t);
}
draw(g, ps02[0], ps02[1], ps02[2], ps02[3], ps02[4], ps02[5], ps02[6]);
if(t>0){
paintOneMenger(g, ps02[1].x, (ps02[0].y+d/3*2), d/3, dx/3, dy/3, t);
}
draw(g, ps03[0], ps03[1], ps03[2], ps03[3], ps03[4], ps03[5], ps03[6]);
if(t>0){
paintOneMenger(g, ps03[1].x, (ps03[0].y+d/3*2), d/3, dx/3, dy/3, t);
}
//中間
Point p10=new Point(p00.x, p00.y-d);
Point[] ps11=getPointByP0(p10, d, dx, dy);
Point[] ps12=getPointByP0(ps11[3], d, dx, dy);//不畫
Point[] ps13=getPointByP0(ps12[3], d, dx, dy);
Point[] ps14=getPointByP0(ps11[6], d, dx, dy);//不畫
Point[] ps15=getPointByP0(ps12[6], d, dx, dy);//不畫
Point[] ps16=getPointByP0(ps13[6], d, dx, dy);//不畫
Point[] ps17=getPointByP0(ps14[6], d, dx, dy);
Point[] ps18=getPointByP0(ps15[6], d, dx, dy);//不畫
Point[] ps19=getPointByP0(ps16[6], d, dx, dy);
draw(g, ps17[0], ps17[1], ps17[2], ps17[3], ps17[4], ps17[5], ps17[6]);
if(t>0){
paintOneMenger(g, ps17[0].x, (ps17[0].y+d/3*2), d/3, dx/3, dy/3, t);
}
draw(g, ps19[0], ps19[1], ps19[2], ps19[3], ps19[4], ps19[5], ps19[6]);
if(t>0){
paintOneMenger(g, ps19[0].x, (ps19[0].y+d/3*2), d/3, dx/3, dy/3, t);
}
draw(g, ps11[0], ps11[1], ps11[2], ps11[3], ps11[4], ps11[5], ps11[6]);
if(t>0){
paintOneMenger(g, ps11[0].x, (ps11[0].y+d/3*2), d/3, dx/3, dy/3, t);
}
draw(g, ps13[0], ps13[1], ps13[2], ps13[3], ps13[4], ps13[5], ps13[6]);
if(t>0){
paintOneMenger(g, ps13[0].x, (ps13[0].y+d/3*2), d/3, dx/3, dy/3, t);
}
//上層
Point p20=new Point(p10.x,p10.y-d);
Point[] ps21=getPointByP0(p20, d, dx, dy);
Point[] ps22=getPointByP0(ps21[3], d, dx, dy);
Point[] ps23=getPointByP0(ps22[3], d, dx, dy);
Point[] ps24=getPointByP0(ps21[6], d, dx, dy);
Point[] ps25=getPointByP0(ps22[6], d, dx, dy);//不畫
Point[] ps26=getPointByP0(ps23[6], d, dx, dy);
Point[] ps27=getPointByP0(ps24[6], d, dx, dy);
Point[] ps28=getPointByP0(ps25[6], d, dx, dy);
Point[] ps29=getPointByP0(ps26[6], d, dx, dy);
draw(g, ps27[0], ps27[1], ps27[2], ps27[3], ps27[4], ps27[5], ps27[6]);
if(t>0){
paintOneMenger(g, ps27[0].x, (ps27[0].y+d/3*2), d/3, dx/3, dy/3, t);
}
draw(g, ps28[0], ps28[1], ps28[2], ps28[3], ps28[4], ps28[5], ps28[6]);
if(t>0){
paintOneMenger(g, ps28[0].x, (ps28[0].y+d/3*2), d/3, dx/3, dy/3, t);
}
draw(g, ps29[0], ps29[1], ps29[2], ps29[3], ps29[4], ps29[5], ps29[6]);
if(t>0){
paintOneMenger(g, ps29[0].x, (ps29[0].y+d/3*2), d/3, dx/3, dy/3, t);
}
draw(g, ps24[0], ps24[1], ps24[2], ps24[3], ps24[4], ps24[5], ps24[6]);
if(t>0){
paintOneMenger(g, ps24[0].x, (ps24[0].y+d/3*2), d/3, dx/3, dy/3, t);
}
draw(g, ps26[0], ps26[1], ps26[2], ps26[3], ps26[4], ps26[5], ps26[6]);
if(t>0){
paintOneMenger(g, ps26[0].x, (ps26[0].y+d/3*2), d/3, dx/3, dy/3, t);
}
draw(g, ps21[0], ps21[1], ps21[2], ps21[3], ps21[4], ps21[5], ps21[6]);
if(t>0){
paintOneMenger(g, ps21[0].x, (ps21[0].y+d/3*2), d/3, dx/3, dy/3, t);
}
draw(g, ps22[0], ps22[1], ps22[2], ps22[3], ps22[4], ps22[5], ps22[6]);
if(t>0){
paintOneMenger(g, ps22[0].x, (ps22[0].y+d/3*2), d/3, dx/3, dy/3, t);
}
draw(g, ps23[0], ps23[1], ps23[2], ps23[3], ps23[4], ps23[5], ps23[6]);
if(t>0){
paintOneMenger(g, ps23[0].x, (ps23[0].y+d/3*2), d/3, dx/3, dy/3, t);
}
}
public void draw(Graphics g, Point p0, Point p1, Point p2, Point p3, Point p4, Point p5, Point p6){
//g.drawLine(p0.x, p0.y, p1.x, p1.y);
//g.drawLine(p1.x, p1.y, p2.x, p2.y);
//g.drawLine(p2.x, p2.y, p3.x, p3.y);
//g.drawLine(p3.x, p3.y, p0.x, p0.y);
//g.drawLine(p2.x, p2.y, p4.x, p4.y);
//g.drawLine(p4.x, p4.y, p5.x, p5.y);
//g.drawLine(p5.x, p5.y, p6.x, p6.y);
//g.drawLine(p6.x, p6.y, p0.x, p0.y);
//g.drawLine(p3.x, p3.y, p5.x, p5.y);
Polygon pon1 = new Polygon();
pon1.addPoint(p0.x, p0.y);
pon1.addPoint(p1.x, p1.y);
pon1.addPoint(p2.x, p2.y);
pon1.addPoint(p3.x, p3.y);
g.setColor(new Color(255, 0, 0));
g.fillPolygon(pon1);
Polygon pon2 = new Polygon();
pon2.addPoint(p0.x, p0.y);
pon2.addPoint(p3.x, p3.y);
pon2.addPoint(p5.x, p5.y);
pon2.addPoint(p6.x, p6.y);
g.setColor(new Color(180, 0, 0));
g.fillPolygon(pon2);
Polygon pon3 = new Polygon();
pon3.addPoint(p2.x, p2.y);
pon3.addPoint(p3.x, p3.y);
pon3.addPoint(p5.x, p5.y);
pon3.addPoint(p4.x, p4.y);
g.setColor(new Color(120, 0, 0));
g.fillPolygon(pon3);
}
public Point[] getPointByP0(Point p0, int d, int dx, int dy){
Point p1 = new Point(p0.x, p0.y+d);
Point p2 = new Point(p0.x+d, p0.y+d);
Point p3 = new Point(p0.x+d, p0.y);
Point p4 = new Point(p2.x+dx, p2.y-dy);
Point p5 = new Point(p4.x, p4.y-d);
Point p6 = new Point(p5.x-d, p5.y);
Point[] ps = new Point[7];
ps[0] = p0;
ps[1] = p1;
ps[2] = p2;
ps[3] = p3;
ps[4] = p4;
ps[5] = p5;
ps[6] = p6;
return ps;
}
}
疊代的方式有點蠢,不過可以指定其階數,畫出來的效果還不錯。
可以發現畫出來小正方形之間存在間隙,顔色與先被覆寫的那一層相同。這是因為Graphics是以像素為機關操作,而在做操作邊長 d/3 的操作時,d 是 int 類型,如果 d 不能整除3,就會取餘取整儲存為 int 類型給Graphics操作。