![]() |
Матрица статей Список статей Всячина Контакты | ||||||||||||
|
Игры с треугольником и ковром Серпинского
Идея как всегда проста как пять копеек. Рассматриваем треугольник Серпинского как подмножество комплексной плоскости и применяем к нему различные преобразования комплексной плоскости. Например, пусть треугольник Серпинского построен на единичном отрезке действительной оси. Сделаем это следующим кодом.
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;
}
}
Преобразование инверсии относительно центра ковра имеет вид
Также можно применить инверсию относительно угла или возвести в квадрат.
Смотрите также:
Ссылки: |