Reputation: 43
For this program I'm required to recursively draw a 'pagoda', which is a series of diminishing rectangles, aligned centrally, stacked on top of each other. I think I've gotten the logic behind the actual figure, but I'm having trouble figuring out how to actually get the figure drawn as Rectangles with Graphics2D. I tried to shoehorn it into a basic shape drawing program and couldn't find out how to work recursion into it.
This is the code that I've written to this point, without taking graphics into account:
import java.awt.Rectangle;
public class PagodaDrawer
{
private int initialY; //Top of the bottom rectangle
private int initialHeight; //Height for the bottom rectangle
private double scale; //Amount to reduce each layer
public PagodaDrawer(int initialY, int initialHeight, double scaleFactor)
{
this.initialY = initialY;
this.initialHeight = initialHeight;
scale = scaleFactor;
}
public void drawPagoda()
{
drawLayer(0, initialY, 2 * initialHeight, initialHeight);
}
public void drawLayer(double x, double y, double width, double height)
{
if(y < 0 || height < 5) //If off the top of the screen, or less than 5 tall
{
return;
}
drawLayer(x - (((1 - scale)* x) / 2), y + (y * scale), width * scale, height * scale );
Rectangle r = new Rectangle((int)x, (int)y, (int)(2 * height), (int)height);
//Draw r?
}
}
How can I recursively draw layers of the figure in a frame?
EDIT:
For any interested, this is the final code
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class PagodaDrawer extends JPanel
{
private int initialX;
private int initialY; //Top of the bottom rectangle
private int initialHeight; //Height for the bottom rectangle
private double scale; //Amount to reduce each layer
private boolean isRenderable;
private ArrayList<Rectangle> recs;
public PagodaDrawer(int initialX, int initialY, int initialHeight, double scaleFactor)
{
this.initialX = initialX;
this.initialY = initialY;
this.initialHeight = initialHeight;
scale = scaleFactor;
isRenderable = false;
recs = new ArrayList<Rectangle>();
}
public void drawPagoda()
{
drawLayer(initialX, initialY, 2 * initialHeight, initialHeight);
}
public void drawLayer(double x, double y, double width, double height)
{
if(y < 0 || height < 5) //If off the top of the screen, or less than 5 tall
{
isRenderable = true;
return;
}
drawLayer(x + .5 * (width - (width * scale)), y - (height * scale), width * scale, height * scale );
Rectangle r = new Rectangle((int)x, (int)y, (int)(2 * height), (int)height);
recs.add(r);
}
public void paintComponent(Graphics g)
{
if(!isRenderable)
return;
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
for(int i = 0; i < recs.size(); i++)
{
g2.draw(recs.get(i));
System.out.println(recs.get(i));
}
}
}
Coupled with this JFrame:
import javax.swing.JFrame;
import javax.swing.JPanel;
public class DisplayComponent extends JFrame
{
private static final long serialVersionUID = -4279682826771265863L;
private static final int FRAME_WIDTH = 500;
private static final int FRAME_HEIGHT = 500;
private JPanel panel;
private PagodaDrawer p;
public DisplayComponent(int initialHeight, double scaleFactor)
{
p = new PagodaDrawer(FRAME_WIDTH / 2, FRAME_HEIGHT, initialHeight, scaleFactor);
panel = new JPanel();
p.drawPagoda();
add(p);
pack();
setSize(FRAME_WIDTH, FRAME_HEIGHT);
setVisible(true);
}
}
Upvotes: 1
Views: 5374
Reputation: 88
In Java AWT and Swing you draw with Graphics
/ Graphics2D
methods.
Example: graphics.fillRect(x, y, w, h);
You should get the graphics(?:2d)
object from the component where you want to draw into, usually the main Frame or some Component.
Calling your drawings within paintComponent()
of the frame should work fine like this:
How to use paintComponent in Java to paint multiple things, but rotate one?
Here is the Java6 docs: http://docs.oracle.com/javase/6/docs/api/
Upvotes: 1
Reputation: 205785
Instead of making drawLayer()
recursive, write a recursive createRectangle()
that adds each new Rectangle
instance to a List<Rectangle>
. Render the list in your implementation of paintComponent()
, illustrated here.
Upvotes: 2