2

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

    }
}
4

1 回答 1

0

这个问题该有答案了。问题在于这些成员变量声明:

Point c = new Point();
Point e = new Point();

这段代码在drawTree()

drawTree(g,d,e);  //Draw tree left
drawTree(g,e,c);  //Draw tree right

由于cande是一个成员变量,而不是本地的,它们被第一次递归调用修改,drawTree(g, d, e)所以当我们第二次调用时drawTree(g, e, c),它不再是一样的ce我们认为我们有。以下代码的返工使这些本地化(显然没有高效的 GC 方式,但也没有错误)以及其他一些小的修改:

import java.awt.*;
import java.awt.event.*;
import java.util.Random;
import javax.swing.*;

class Point
{
    public float x;
    public float y;

    public Point(float x, float y) {
        this.x = x;
        this.y = y;
    }

    public Point() {

    }
}

class DrawingPanel extends JPanel
{
    Random random = new Random();

    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 center = 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();
                }
                else 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);
        center.x = maxX / 2; 
        center.y = maxY / 2;
    }

    int iX(float x){ return Math.round(center.x + x / pixelSize); }
    int iY(float y){ return Math.round(center.y - y / pixelSize); }
    float fx(int x){ return (x - center.x) * pixelSize; }
    float fy(int y){ return (center.y - y) * pixelSize; }

    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);

        initgr();
        setBackground(Color.white);

        if (clickCount == 1)
        {
            g.setColor(Color.red);
            g.drawLine(iX(a.x), iY(a.y), iX(a.x), iY(a.y));
        }
        else if (clickCount > 1) {
            drawTree(g, a, b);
        } 
    }

    public void drawTree(Graphics g, Point first, Point second)
    {
        double xSquared = Math.pow(second.x - first.x, 2);
        double ySquared = Math.pow(second.y - first.y, 2);

        if (Math.sqrt(xSquared + ySquared) < 0.01) {
            return;
        }

        Point u = new Point(second.x - first.x, second.y - first.y);
        Point d = new Point(first.x - u.y, first.y + u.x);

        Point c = new Point(d.x + u.x, d.y + u.y);
        Point e = new Point(d.x + 0.5F * (u.x - u.y), d.y + 0.5F * (u.y + u.x));

        Polygon square = new Polygon();

        square.addPoint(iX(first.x), iY(first.y));
        square.addPoint(iX(second.x), iY(second.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);

        Polygon triangle = new Polygon();

        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);

        drawTree(g, d, e); // Draw tree left
        drawTree(g, e, c); // Draw tree right
    }
}

public class PythagorasTree extends JFrame
{
    PythagorasTree()
    {
        super("Pythagoras Tree");
        setSize(800, 800);
        add("Center", new DrawingPanel());
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    public static void main(String[] args)
    {
        new PythagorasTree();
    }
}

输出

在此处输入图像描述

于 2018-12-17T04:55:36.820 回答