我有一项任务要求我们使用递归绘制毕达哥拉斯树。树以方形ABCD开始,点A和B由鼠标点击定义。一切似乎都有效,直到我进入递归,在那里我可以得到树的左侧或右侧部分进行绘制,但不能同时进行。我发表评论,我相信我遇到了问题。
import java.awt.*;
import java.awt.event.*;
import java.util.Random;
import javax.swing.*;
public class PythagorasTree extends JFrame
{
public static void main(String[] args)
{
new PythagorasTree();
}
PythagorasTree()
{
super("Pythagoras Tree");
setSize(800,800);
add("Center", new DrawingPanel());
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
class DrawingPanel extends JPanel
{
Random random = new Random();
int centerX;
int centerY;
int clickCount = 0;
float pixelSize;
float rWidth = 10.0F;
float rHeight = 7.5F;
float red, green, blue;
Point a = new Point();
Point b = new Point();
Point c = new Point();
Point d = new Point();
Point e = new Point();
Point u = new Point();
DrawingPanel()
{
addMouseListener(new MouseAdapter()
{
public void mousePressed(MouseEvent click)
{
clickCount++;
if (clickCount == 1)
{
a.x = fx(click.getX());
a.y = fy(click.getY());
repaint();
}
if (clickCount == 2)
{
b.x = fx(click.getX());
b.y = fy(click.getY());
repaint();
}
}
});
}
void initgr()
{
Dimension d = getSize();
int maxX = d.width - 1;
int maxY = d.height - 1;
pixelSize = Math.max(rWidth/maxX, rHeight/maxY);
centerX = maxX/2;
centerY = maxY/2;
}
int iX(float x){return Math.round(centerX + x/pixelSize);}
int iY(float y){return Math.round(centerY - y/pixelSize);}
float fx(int x){return (x - centerX) * pixelSize;}
float fy(int y){return (centerY - y) * pixelSize;}
public void paintComponent(Graphics g)
{
initgr();
super.paintComponent(g);
setBackground(Color.white);
g.setColor(Color.red);
if (clickCount == 1)
g.drawLine(iX(a.x), iY(a.y), iX(a.x), iY(a.y));
if (clickCount > 1)
drawTree(g,a,b);
}
public void drawTree(Graphics g, Point first, Point second)
{
float xSquared = (float) Math.pow((second.x-first.x),2);
float ySquared = (float) Math.pow((second.y-first.y),2);
float length = (float) Math.sqrt(xSquared + ySquared);
if ( length > .001)
{
u.x = second.x - first.x;
u.y = second.y - first.y;
a.x = first.x;
a.y = first.y;
b.x = second.x;
b.y = second.y;
d.x = first.x + (u.y * -1);
d.y = first.y + u.x;
c.x = d.x + u.x;
c.y = d.y + u.y;
e.x = d.x + .5F * (u.x + (u.y*-1));
e.y = d.y + .5F * (u.y + u.x);
Polygon square = new Polygon();
Polygon triangle = new Polygon();
square.addPoint(iX(a.x), iY(a.y));
square.addPoint(iX(b.x), iY(b.y));
square.addPoint(iX(c.x), iY(c.y));
square.addPoint(iX(d.x), iY(d.y));
red = random.nextFloat();
green = random.nextFloat();
blue = random.nextFloat();
g.setColor(new Color(red, green, blue));
g.fillPolygon(square);
triangle.addPoint(iX(c.x), iY(c.y));
triangle.addPoint(iX(d.x), iY(d.y));
triangle.addPoint(iX(e.x), iY(e.y));
red = random.nextFloat();
green = random.nextFloat();
blue = random.nextFloat();
g.setColor(new Color(red, green, blue));
g.fillPolygon(triangle);
/* Problem code is here, tree will draw Left or Right depending on which recursive call
* is first in the code, but will never reach the 2nd call.
*/
drawTree(g,d,e); //Draw tree left
drawTree(g,e,c); //Draw tree right
}
}
}
class Point
{
public float x;
public float y;
public Point()
{
}
}
答案 0 :(得分:0)
是时候这个问题了。问题在于这些成员变量声明:
Point c = new Point();
Point e = new Point();
drawTree()
中的这段代码:
drawTree(g,d,e); //Draw tree left
drawTree(g,e,c); //Draw tree right
由于c
和e
是成员变量,而不是局部变量,因此它们在第一次对drawTree(g, d, e)
的递归调用时被修改,因此在我们第二次对{{1 }},它不再是我们以前认为的drawTree(g, e, c)
和c
。下面的代码重做使得这些代码局部化(显然在GC方面效率不高,但在bug方面也不那么有效)以及其他一些小的修改:
e
输出