如何使用 single/simple for 循环以不同的比例和平移多次绘制蝴蝶曲线?
How to draw a butterfly curve multiple times with different scale and translation using a single/simple for loop?
此问题与有关。
我想做的是将同一条蝴蝶曲线最多绘制 30 次。每次用一个随机的scale/translation/color.
我试过这个代码:
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
for (int j=0;j<30;j++) {
double tr = Math.random() * 300;
g2.translate(tr,tr);
double sc = Math.random() * 50 + 10;
g2.scale(sc,sc);
g2.setStroke(new BasicStroke(0.01f ));
g2.setColor(new Color((int)(Math.random()*255), (int)(Math.random()*255),(int) (Math.random()*255)));
double x1,y1;
double x0 = 0;
int nPoints = 1500;
double y0 = Math.E-2;
for(int i=0;i<nPoints;i++) {
double t= 12*i*Math.PI/nPoints;
x1=(Math.sin(t)*(Math.pow(Math.E,Math.cos(t))-2*Math.cos(4*t)-Math.pow(Math.sin(t/12),5)));
y1 = (Math.cos(t)*(Math.pow(Math.E,Math.cos(t))-2*Math.cos(4*t)-Math.pow(Math.sin(t/12),5)));
g2.draw(new Line2D.Double(x0,y0,x1,y1));
x0=x1;
y0=y1;
}
}
}
这段代码的问题是,最后它只会 show/draw 一条曲线。它不会显示超过一个。由于在 Swing 中绘画具有破坏性,我怀疑我面临的问题与 for 循环内的这些行有关:
double tr = Math.random() * 300;
g2.translate(tr,tr);
double sc = Math.random() * 50 + 10;
g2.scale(sc,sc);
为了快速测试,我尝试了以下代码:
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
double tr = Math.random() * 300;
g2.translate(tr,tr);
double sc = Math.random() * 50 + 10;
g2.scale(sc,sc);
for (int j=0;j<30;j++) {
g2.setStroke(new BasicStroke(0.01f ));
g2.setColor(new Color((int)(Math.random()*255), (int)(Math.random()*255),(int) (Math.random()*255)));
double x1,y1;
double x0 = 0;
int nPoints = 1500;
double y0 = Math.E-2;
g2.drawLine(5,j,100,j);
}
}
这画了30行,当我在循环中添加scale
和translate
方法时,它只画了1行。 所以我想我是对的。
一个简单的 for 循环可以完成这项工作,还是我应该使用一些更复杂的算法在更改比例和平移的同时多次绘制该蝴蝶曲线?
我找到了一个使用 AffineTransform 缩放和平移的解决方案。
基本上,解决方案是摆脱 g2.scale
和 g2.translate
,并使用 g2.setTransform(tx);
。 tx
是一个可以缩放和平移的 AffineTransform
。
这是为我完成的代码:
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
for (int j=0;j<30;j++) {
double sc = Math.random() * 30 + 10;
AffineTransform tx = new AffineTransform();
tx.scale(sc, sc);
tx.translate(Math.random() * 50, Math.random() * 50);
g2.setTransform(tx);
g2.setStroke(new BasicStroke(0.01f ));
g2.setColor(new Color((int)(Math.random()*255), (int)(Math.random()*255),(int) (Math.random()*255)));
double x1,y1;
double x0 = 0;
int nPoints = 1500;
double y0 = Math.E-2;
for(int i=0;i<nPoints;i++) {
double t= 12*i*Math.PI/nPoints;
x1=(Math.sin(t)*(Math.pow(Math.E,Math.cos(t))-2*Math.cos(4*t)-Math.pow(Math.sin(t/12),5)));
y1 = (Math.cos(t)*(Math.pow(Math.E,Math.cos(t))-2*Math.cos(4*t)-Math.pow(Math.sin(t/12),5)));
g2.draw(new Line2D.Double(x0,y0,x1,y1));
x0=x1;
y0=y1;
}
}
}
此问题与
我想做的是将同一条蝴蝶曲线最多绘制 30 次。每次用一个随机的scale/translation/color.
我试过这个代码:
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
for (int j=0;j<30;j++) {
double tr = Math.random() * 300;
g2.translate(tr,tr);
double sc = Math.random() * 50 + 10;
g2.scale(sc,sc);
g2.setStroke(new BasicStroke(0.01f ));
g2.setColor(new Color((int)(Math.random()*255), (int)(Math.random()*255),(int) (Math.random()*255)));
double x1,y1;
double x0 = 0;
int nPoints = 1500;
double y0 = Math.E-2;
for(int i=0;i<nPoints;i++) {
double t= 12*i*Math.PI/nPoints;
x1=(Math.sin(t)*(Math.pow(Math.E,Math.cos(t))-2*Math.cos(4*t)-Math.pow(Math.sin(t/12),5)));
y1 = (Math.cos(t)*(Math.pow(Math.E,Math.cos(t))-2*Math.cos(4*t)-Math.pow(Math.sin(t/12),5)));
g2.draw(new Line2D.Double(x0,y0,x1,y1));
x0=x1;
y0=y1;
}
}
}
这段代码的问题是,最后它只会 show/draw 一条曲线。它不会显示超过一个。由于在 Swing 中绘画具有破坏性,我怀疑我面临的问题与 for 循环内的这些行有关:
double tr = Math.random() * 300;
g2.translate(tr,tr);
double sc = Math.random() * 50 + 10;
g2.scale(sc,sc);
为了快速测试,我尝试了以下代码:
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
double tr = Math.random() * 300;
g2.translate(tr,tr);
double sc = Math.random() * 50 + 10;
g2.scale(sc,sc);
for (int j=0;j<30;j++) {
g2.setStroke(new BasicStroke(0.01f ));
g2.setColor(new Color((int)(Math.random()*255), (int)(Math.random()*255),(int) (Math.random()*255)));
double x1,y1;
double x0 = 0;
int nPoints = 1500;
double y0 = Math.E-2;
g2.drawLine(5,j,100,j);
}
}
这画了30行,当我在循环中添加scale
和translate
方法时,它只画了1行。 所以我想我是对的。
一个简单的 for 循环可以完成这项工作,还是我应该使用一些更复杂的算法在更改比例和平移的同时多次绘制该蝴蝶曲线?
我找到了一个使用 AffineTransform 缩放和平移的解决方案。
基本上,解决方案是摆脱 g2.scale
和 g2.translate
,并使用 g2.setTransform(tx);
。 tx
是一个可以缩放和平移的 AffineTransform
。
这是为我完成的代码:
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
for (int j=0;j<30;j++) {
double sc = Math.random() * 30 + 10;
AffineTransform tx = new AffineTransform();
tx.scale(sc, sc);
tx.translate(Math.random() * 50, Math.random() * 50);
g2.setTransform(tx);
g2.setStroke(new BasicStroke(0.01f ));
g2.setColor(new Color((int)(Math.random()*255), (int)(Math.random()*255),(int) (Math.random()*255)));
double x1,y1;
double x0 = 0;
int nPoints = 1500;
double y0 = Math.E-2;
for(int i=0;i<nPoints;i++) {
double t= 12*i*Math.PI/nPoints;
x1=(Math.sin(t)*(Math.pow(Math.E,Math.cos(t))-2*Math.cos(4*t)-Math.pow(Math.sin(t/12),5)));
y1 = (Math.cos(t)*(Math.pow(Math.E,Math.cos(t))-2*Math.cos(4*t)-Math.pow(Math.sin(t/12),5)));
g2.draw(new Line2D.Double(x0,y0,x1,y1));
x0=x1;
y0=y1;
}
}
}