Java面向对象编程:利用递归思想绘制“谢尔宾斯基地毯”和“谢尔宾斯基三角形”

1、递归:在方法中调用本方法。

2、递归调用会无限循环下去,因此方法体中必须有结束方法的条件。返回值为void时通常写为:

if (条件) {
    return;
}

下面使用递归绘制“谢尔宾斯基地毯”和“谢尔宾斯基三角形”。


谢尔宾斯基地毯。

1)取一个正方形。

2)绘制出该正方形的九宫格。

3)保留中间的九宫格,擦除其他线。

4)对九宫格的其余八个正方形重复步骤2-3。

效果图如下:

完整代码如下:

import javax.swing.*;
import java.awt.*;

public class SierpinskiCarpet extends JFrame {
    @Override
    public void paint(Graphics g) {
        super.paint(g);
        int x = 100;
        int y = 100;
        int width = 729;
        int height = 729;
        g.drawRect(x, y, width, height);
        drawSierpinskiCarpet(g, x, y, width, height);
    }

    public void drawSierpinskiCarpet(Graphics g, 
            int x, int y, int width, int height) {
        if (width <= 1) {
            return;
        }
        //小正方形
        int _width = width / 3;
        int _height = height / 3;
        int _x = x + _width;
        int _y = y + _height;
        g.drawRect(_x, _y, _width, _height);
        width /= 3;
        height /= 3;

        drawSierpinskiCarpet(g, x, y, width, height);
        drawSierpinskiCarpet(g, x + width, y, width, height);
        drawSierpinskiCarpet(g, x + width * 2, y, width, height);
        drawSierpinskiCarpet(g, x, y + height, width, height);
        drawSierpinskiCarpet(g, x + width * 2, y + height, width, height);
        drawSierpinskiCarpet(g, x, y + height * 2, width, height);
        drawSierpinskiCarpet(g, x + width, y + height * 2, width, height);
        drawSierpinskiCarpet(g, x + width * 2, y + height * 2, width, height);
    }

    public static void main(String[] args) {
        SierpinskiCarpet sierpinskiCarpet = new SierpinskiCarpet();
        sierpinskiCarpet.setTitle("Sierpiński Carpet");
        sierpinskiCarpet.setSize(1000, 1000);
        sierpinskiCarpet.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        sierpinskiCarpet.setVisible(true);
    }
}

①重写paint() 方法:负责绘制出大正方形,并调用drawSierpinskiCarpet() 方法。

②drawSierpinskiCarpet() 方法:递归地绘制中间的小正方形。

        - 终止条件:小正方形边长≤1(每递归一次边长除以3);

        - 绘制小正方形; 

        - 递归调用drawSierpinskiCarpet() ,在八个位置分别绘制1/3倍大小的小正方形。

 

程序运行结果:

更改终止条件:小正方形边长≤9,运行结果:


 

谢尔宾斯基三角形。

1)取一个三角形。

2)沿三边中点的连线,将它分成四个小三角形。

3)去掉中间的那一个小三角形。

4)对其余三个小三角形重复步骤1。

效果图如下:

 

完整代码如下:

import javax.swing.*;
import java.awt.*;
import static java.lang.Math.sqrt;

public class SierpinskiTriangle extends JFrame {
    @Override
    public void paint(Graphics g) {
        super.paint(g);
        int ax = 100;
        int ay = 100;
        int bx = 1124;
        int by = 100;
        int cx = 100;
        int cy = 1124;
        Point a = new Point(ax, ay);
        Point b = new Point(bx, by);
        Point c = new Point(cx, cy);
        drawTriangle(g, a, b, c);
//        drawSierpinskiCarpet(g, x, y, width, height);
        Point d = new Point(a, b);
        Point e = new Point(a, c);
        Point f = new Point(b, c);
        drawTriangle(g, d, e, f);
        drawSierpinskiTriangle(g,a,b,c);
    }

    public void drawTriangle(Graphics g, Point a, Point b, Point c) {
        g.drawLine(a.x, a.y, b.x, b.y);
        g.drawLine(a.x, a.y, c.x, c.y);
        g.drawLine(b.x, b.y, c.x, c.y);
    }

    public void drawSierpinskiTriangle(Graphics g, 
            Point a, Point b, Point c) {
        if (Point.PointDistance(a, b) <= 8) {
            return;
        }
        Point d = new Point(a, b);
        Point e = new Point(a, c);
        Point f = new Point(b, c);
        drawTriangle(g, d, e, f);
        drawSierpinskiTriangle(g, a, d, e);
        drawSierpinskiTriangle(g, d, b, f);
        drawSierpinskiTriangle(g, e, f, c);

    }

    public static void main(String[] args) {
        SierpinskiTriangle sierpinskiTriangle = new SierpinskiTriangle();
        sierpinskiTriangle.setTitle("Sierpiński Triangle");
        sierpinskiTriangle.setSize(1200, 1200);
        sierpinskiTriangle.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        sierpinskiTriangle.setVisible(true);
    }
}

class Point {
    int x;
    int y;

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

    public Point(Point a, Point b) {
        this.x = (a.x + b.x) / 2;
        this.y = (a.y + b.y) / 2;
    }

    public static double PointDistance(Point a, Point b) {
        double distance = sqrt(
            (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
        return distance;
    }
}

 ①Point类:

        - 定义创建两个点的中点的构造函数Point(Point a, Point b)。

        - 定义求两个点之间距离的方法PointDistance(Point a, Point b)。

②SierpinskiTriangle类:

        - 重写paint() 方法:负责绘制出大三角形(本程序采用等腰直角三角形),并调用drawSierpinskiTriangle() 方法。

        - drawTriangle() 方法:Graphics库并没有给出绘制三角形的函数,我们在程序中通过调用三次drawLine() 方法绘制出三角形。

        - drawSierpinskiTriangle() 方法:递归地绘制小三角形。

                - 终止条件:直角边的长度≤8

                - 更新三角形的顶点:调用构造方法Point(Point a, Point b)。

                - 递归调用drawSierpinskiTriangle() ,在三个位置分别绘制小三角形。

程序运行结果:

 更改终止条件:小三角形直角边长≤32,运行结果:

 

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值