This question is related to my older question.
What I am trying to do is to draw that same butterfly curve up to 30 times. Each time with a random scale/translation/color.
I tried this code:
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;
}
}
}
The problem with this code is, at the end, it will only show/draw one curve. It won't show more than one. Since painting in Swing is destructive, I suspected that the problem I am facing have something to do with these lines being inside the for loop:
double tr = Math.random() * 300;
g2.translate(tr,tr);
double sc = Math.random() * 50 + 10;
g2.scale(sc,sc);
For a quick test, I tried this code:
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);
}
}
This drew 30 lines, and when I added the scale
and translate
methods inside the loop, it only drew 1 line. So I guess that I am right.
Can a simple for loop do the job or should I be going with a bit of more complex algorithm to draw that butterfly curve multiple times while changing scale and translation?
I found a solution using AffineTransform to scale and translate.
Basically, the solution was to get rid of g2.scale
and g2.translate
, and use g2.setTransform(tx);
. tx
being an AffineTransform
which scales and translates.
Here's the code that did it for me:
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;
}
}
}