Java双递归调用。

时间:2013-03-03 19:33:11

标签: java recursion fractals

我有一项任务要求我们使用递归绘制毕达哥拉斯树。树以方形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()
    {

    }
}

1 个答案:

答案 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

由于ce是成员变量,而不是局部变量,因此它们在第一次对drawTree(g, d, e)的递归调用时被修改,因此在我们第二次对{{1 }},它不再是我们以前认为的drawTree(g, e, c)c。下面的代码重做使得这些代码局部化(显然在GC方面效率不高,但在bug方面也不那么有效)以及其他一些小的修改:

e

输出

enter image description here