Снежинка Коха


Реализация снежинки Коха на Python с использованием черепашьей графики:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#################################################################
#
# Koch Snowflake, Python, 2011-01-24
# 
# Artix, master@7masterov.ru, icq:53666599, skype:artixmaster
# 
# * Error in code? Nothing is perfect!
# * Free source for free Linux, use it for free!
# * Please, do not remove this comment!
#
#################################################################


from Tkinter import *
from math import *
import sys

SIZE_X=600
SIZE_Y=500
STEP=7
 
class Turtle:
    x = 0.0
    y = 0.0
    a = 0.0
    pen = 1
    canvas = None
 
    def __init__(self,canvas):
        self.canvas = canvas
 
    def setpen(self,yes):
        self.pen = yes
 
    def rotate(self,g):
        self.a += g
 
    def move(self,sx,sy):
        self.x = sx
        self.y = sy
 
    def forward(self,length):
        new_x = self.x+cos(pi/180*self.a)*length
        new_y = self.y+sin(pi/180*self.a)*length
        cx = SIZE_X / 2
        cy = SIZE_Y / 2
        if self.pen:
            self.canvas.create_line(cx+self.x, cy-self.y, cx+new_x, cy-new_y,fill="green")
        self.x = new_x
        self.y = new_y
 
    def line(self,angle,length):
        new_x = self.x+cos(pi/180*angle)*length
        new_y = self.y+sin(pi/180*angle)*length
        cx = SIZE_X / 2
        cy = SIZE_Y / 2
        if self.pen:
            self.canvas.create_line(cx+self.x, cy-self.y, cx+new_x, cy-new_y,fill="green")
        self.x = new_x
        self.y = new_y
        

class Koch:
    
    turtle = None
 
    def __init__(self,turtle):
        self.turtle = turtle
        

    def make(self,level):
        self.turtle.move(-STEP*0.64*(level*level*level), 0)
        self.segment(level)
        
    def segment(self,i):
        if i>0:
            self.segment(i-1)
            self.turtle.rotate(60)
            self.segment(i-1)
            self.turtle.rotate(-120)
            self.segment(i-1)
            self.turtle.rotate(60)
            self.segment(i-1)
        else:
            self.turtle.forward(STEP)
            


root = Tk()
root.title("Koch Snowflake")
c = Canvas(root,width=SIZE_X,height=SIZE_Y,bg="black")
c.pack()
s = Koch(Turtle(c))
s.make(4)
 
root.mainloop()


Другая реализация алгоритма с использованием "плоской" графики.
На этот раз снежинка действительно напоминает снежинку, поскольку
образована сторонами равностороннего треугольника.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#################################################################
#
# Koch Snowflake, Python, 2011-01-24
# 
# Artix, master@7masterov.ru, icq:53666599, skype:artixmaster
# 
# * Error in code? Nothing is perfect!
# * Free source for free Linux, use it for free!
# * Please, do not remove this comment!
#
#################################################################


from Tkinter import *
from math import *
import sys

SIZE_X=600
SIZE_Y=500
STEP=10
 
class Koch:
    
    def __init__(self,canvas):
        self.canvas = canvas

    def make(self,level):
        r = SIZE_Y/2-STEP
        x1 = SIZE_X/2
        y1 = SIZE_Y/2 - r*sin(pi/2)
        x2 = SIZE_X/2 + r*cos(pi/6)
        y2 = SIZE_Y/2 - r*sin(-pi/6)
        x3 = SIZE_X/2 - r*cos(-pi/6)
        y3 = SIZE_Y/2 - r*sin(-pi/6)
        self.segment(x1, y1, x2, y2, level)
        self.segment(x2, y2, x3, y3, level)
        self.segment(x3, y3, x1, y1, level)
        
    def segment(self,x1,y1,x2,y2,lev):
        if lev>0:
            angle = atan2(y2-y1, x2-x1);
            r = sqrt((x2-x1) * (x2-x1) + (y2-y1) * (y2-y1));
 
            new_x1 = x1 + r * cos(angle) / 3;
            new_y1 = y1 + r * sin(angle) / 3;
            new_x2 = new_x1 + r * cos(angle - pi / 3) / 3;
            new_y2 = new_y1 + r * sin(angle - pi / 3) / 3;
            new_x3 = x1 + 2*r * cos(angle) / 3;
            new_y3 = y1 + 2*r * sin(angle) / 3;

            self.segment(x1, y1, new_x1, new_y1, lev-1);
            self.segment(new_x1, new_y1, new_x2, new_y2, lev-1);
            self.segment(new_x2, new_y2, new_x3, new_y3, lev-1);
            self.segment(new_x3, new_y3, x2, y2, lev-1);
        else:
            self.canvas.create_line(x1, y1, x2, y2, fill="green")
            


root = Tk()
root.title("Koch Snowflake")
c = Canvas(root,width=SIZE_X,height=SIZE_Y,bg="black")
c.pack()
s = Koch(c)
s.make(3)
 
root.mainloop()

На Википедии нашлась еще одна реализация на PHP:

<?php
set_time_limit(3);

$x = 600;	// Длина рисунка
$y = 200;	// Высота рисунка
$r = 10;	// Рамка
$i = 4;		// Количество итераций

define("PI", 3.14159265358979323846);

$img = imagecreate($x, $y);
$black = imagecolorallocate($img, 0, 0, 0);
imagefill($img, 1, 1, $black);
$color = imagecolorallocate($img, 255, 255, 255);

recursion($i, $r, $y - $r, $x - $r, $y - $r);
function recursion($i, $x1, $y1, $x2, $y2) {
    global $img, $color;

    if($i == 0)
        imageline($img, $x1, $y1, $x2, $y2, $color);

    else {
        $alpha = atan2($y2 - $y1, $x2 - $x1);
        $r = sqrt(($x2 - $x1) * ($x2 - $x1) + ($y2 - $y1) * ($y2 - $y1));

        $xa = $x1 + $r * cos($alpha) / 3;
        $ya = $y1 + $r * sin($alpha) / 3;

        $xc = $xa + $r * cos($alpha - PI / 3) / 3;
        $yc = $ya + $r * sin($alpha - PI / 3) / 3;

        $xb = $x1 + 2 * $r * cos($alpha) / 3;
        $yb = $y1 + 2 * $r * sin($alpha) / 3;

        recursion($i - 1, $x1, $y1, $xa, $ya);
        recursion($i - 1, $xa, $ya, $xc, $yc);
        recursion($i - 1, $xc, $yc, $xb, $yb);
        recursion($i - 1, $xb, $yb, $x2, $y2);
    }
}

//header("Content-type: image/png");
imagepng($img,'result.png');
imagedestroy($img);
?>