Kirjoittaja: Kryil
Kirjoitettu: 02.02.2004 – 02.02.2004
Tagit: grafiikka, koodi näytille, vinkki
Piirtää sierpinskin maton.
Sierpinskin matto on neliö, josta on poistettu keskeltä yhden yhdeksäsosan kokoinen neliö, ja jäljelle jääneistä neliöistä on poistettu 1/9, jne.
Demottaa voi osoitteessa http://koti.mbnet.fi/ilarim/w00t/sierpinski.php
get-parametrit: s = sivun pituus (pikseleitä), h = poistojen määrä, rc = random color (boolean)
<?php //Sierpinskin matto. //Koska meillä on käytössämme pikselit, joita ei tunnetusti hirveästi jaella, //joudumme käyttämään pyöristyneitä arvoja. Pyöristykset tehdään normaalin säännön mukaisesti //Tästä syystä kuvassa ilmenee erikokoisia välejä neliöllä. //Nämä tulevat hyvin esiin esim. 2000 pikselin leveydellä ja kuudella hypyllä. //Koodi on hieman raskasta, eikä sitä ole pahemmin yritettykään optimoida error_reporting(0); //Kuvaan ei voi tulostaa virheilmoituksia (vaikkei niitä pitäisi tullakaan) header("Content-type: image/jpeg"); //jpeg siksi, että IE tahtoo downloadata png:t (kavereilla on, ei mulla :) //Muuttujat $size = (int) $_GET['s'] > 200 ? (int) $_GET['s'] : 200; //Kuvasta tehdään neliö $hops = (int) $_GET['h'] > 0 ? (int) $_GET['h'] : 3; //Kuinka monta kertaa tehdään poisto $rndcolor = (bool) $_GET['rc']; //Satunnainen väri (ei ole enää aito sierpinskin matto näin) //HUOM Ei ole muuten aito muutenkaan, mutta näyttää siltä :) $im = imagecreatetruecolor($size, $size); $cback = imagecolorallocate($im, 0, 0, 0); //Taustaväri ei ole satunnainen if (!$rndcolor) { //Jos ei satunnaista väriä, määritellään neliöiden väri $cfore = imagecolorallocate($im, 255, 0, 0); } imagefill($im, 0, 0, $cback); //Floodataan taustaväri kuvaan $hopsdone = 0; //Kuinka monta on tehty while ($hopsdone < $hops) { $width = $size / pow(3, $hopsdone); //Yhden neliön leveys $howmany = pow(3, $hopsdone); //Kuinka monta pääneliötä sivulla on. (Niin monta hyppyä tehdään) //Eli jokaisesta neliöstä pitää värittää 1/3 keskeltä $y = 0; while($y < $howmany) { //Y-akseli //Neliön piirtopisteet määritellään seuraavasti: //Pääneliön kanta kertaa jo piirrettyjen neliöiden määrä plus 1/3 neliön koosta (kertaa 2 jos kyseessä loppupiste) $starty = round(($width * ($y)) + $width / 3); $endy = round(($width * ($y )) + $width / 3 * 2); $x = 0; while ($x < $howmany) { //X-akseli $startx = round(($width * ($x)) + $width / 3); $endx = round(($width * ($x)) + $width / 3 * 2); if (!$rndcolor) { imagefilledrectangle($im, $startx, $starty, $endx, $endy, $cfore); //Tehdään neliö. } else { //Ei hyväksytä täysin mustaa satunnaisessa värissä, jotta jokainen neliö erottuu taustasta //(koska neliöt menevät päällekäin, ne eivät aina erotu toisistaan) imagefilledrectangle($im, $startx, $starty, $endx, $endy, imagecolorallocate($im, rand(10, 255), rand(10, 255), rand(10, 255))); } $x++; } $y++; } $hopsdone++; } imagejpeg($im); //Tulostetaan kuva imagedestroy($im); //Vapautetaan serverin resursseja die(); //Kuollaan pois jottei tulostella vahingossakaan ylimääräistä ?>
Hieno! Toisaalta turha, mutta näitä olisi hyvä harjoitella.
Ihan ok, mutta toi kuva on jotenkin sutuinen. (pakattu?)
En tiedä mitkä ovat mbnetin asetukset jpegin pakkauksen suhteen...
PNG on suotuisampi vaihtoehto :)
Toimivat demot:
JPG-kuva: http://koti.mbnet.fi/ollins/muuta/testi/matto.
PNG-kuva: http://koti.mbnet.fi/ollins/muuta/testi/mattop.
PNG näyttää kivemmalta minun mielestäni :)