Матрица статей        Список статей        Всячина        Контакты       

Игры с треугольником и ковром Серпинского


Преобразованный треугольник Серпинского

Идея как всегда проста как пять копеек. Рассматриваем треугольник Серпинского как подмножество комплексной плоскости и применяем к нему различные преобразования комплексной плоскости. Например, пусть треугольник Серпинского построен на единичном отрезке действительной оси. Сделаем это следующим кодом.

public class SierpinskiTriangleGenerator implements Generator {
    Complex z = Complex.ZERO;
    public Complex generatePoint() {
        double r = Math.random();
        if (r < 1./3) {
            z = z.mul(.5);
        } else if (r < 2./3) {
            z = z.mul(.5).add(.5);
        } else {
            z = z.mul(.5).add(new Complex(.25, Math.sqrt(3)/4));
        }
        return z;
    }
}

И теперь применим к комплексной плоскости преобразование инверсии относительно центра треугольника: . Тогда получим следующую картинку.


Преобразованный треугольник Серпинского

public class Painter {
    Generator generator;
    Transformator transformator;

    public Painter(Generator generator, Transformator transformator) {
        this.generator = generator;
        this.transformator = transformator;
    }

    public BufferedImage draw(int width, int height, int countPoint, 
		Transformator viewTransformator) {
        BufferedImage image = new BufferedImage(width, height, 
		BufferedImage.TYPE_INT_RGB);
        Graphics imageGraphics = image.getGraphics();
        imageGraphics.setColor(Color.WHITE);
        imageGraphics.fillRect(0, 0, width, height);

        for (int i = 0; i < countPoint; ++i) {
            Complex z = viewTransformator.transform(
				transformator.transform(
					generator.generatePoint()));
            if (z.getReal() >= 0 && z.getReal() < width &&
                    z.getImag() >= 0 && z.getImag() < height) {
                image.setRGB((int)z.getReal(), (int)z.getImag(), 0);
            }
        }
        return image;
    }
}
public class Main {
    private static Image image;

    private static Image drawInvCenterSierpinskiTriangle() {
        Painter painter = new Painter(
		new SierpinskiTriangleGenerator(), 
		new Transformator() {
            public Complex transform(Complex z) {
                return Complex.inv(
			z.add(new Complex(-.5, -Math.sqrt(3)/6))).add(
				new Complex(.5, Math.sqrt(3)/6));
            }
        });
        return painter.draw(640, 480, 500000, new Transformator() {
            public Complex transform(Complex z) {
                return Complex.conj(z).mul(36).add(new Complex(320, 240));
            }
        });
    }

    public static void main(String[] args) {
        image = drawInvSomewhereSierpinskiTriangle();
        JFrame frame = new JFrame();
        frame.addNotify();
        frame.setSize(frame.getInsets().left
                + frame.getInsets().right + image.getWidth(null),
                frame.getInsets().top
                + frame.getInsets().bottom + image.getHeight(null));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.add(new JPanel() {
            @Override
            public void paintComponent(Graphics g) {
                Graphics2D G = (Graphics2D) g;
                if (image != null) {
                    G.drawImage(image, 0, 0, null);
                }
            }
        });
        frame.setVisible(true);
    }
}

Ниже приведены картинки для , , .


Преобразованный треугольник Серпинского Преобразованный треугольник Серпинского Преобразованный треугольник Серпинского

Тоже самое можно сделать и с ковром Серпинского. Пусть он построен на единичном квадрате.

public class SierpinskiCarpetGenerator implements Generator {
    Complex z = Complex.ZERO;
    public Complex generatePoint() {
        double r = Math.random();
        if (r < .125) {
            z = z.mul(1./3);
        } else if (r < .25) {
            z = z.mul(1./3).add(1./3);
        } else if (r < .375) {
            z = z.mul(1./3).add(2./3);
        } else if (r < .5) {
            z = z.mul(1./3).add(new Complex(0, 1./3));
        } else if (r < .625) {
            z = z.mul(1./3).add(new Complex(2./3, 1./3));
        } else if (r < .75) {
            z = z.mul(1./3).add(new Complex(0, 2./3));
        } else if (r < .875) {
            z = z.mul(1./3).add(new Complex(1./3, 2./3));
        } else {
            z = z.mul(1./3).add(new Complex(2./3, 2./3));
        }
        return z;
    }
}

Преобразование инверсии относительно центра ковра имеет вид .


Преобразованный ковёр Серпинского

Также можно применить инверсию относительно угла или возвести в квадрат.
Преобразованный ковёр Серпинского Преобразованный ковёр Серпинского

Скачать исходный код.

Смотрите также:

Ссылки: