Scripts
Interferentie tekenen
Ik had voor een project even wat plaatjes van interferentie nodig. Een snel scriptje bood de uitkomst. En ach, laat ik hem hier maar plaatsen, misschien hebben anderen er nog wat aan.
interferentie-tekenen
<?php
set_time_limit(120); // geloof me, hij vreet tijd!
define('IMAGES', 3); // x bij x plaatjes; bijv. 3 levert 3 x 3 = 9
// plaatjes op
define('WIDTH', 300); // breedte van een individueel plaatje
define('HEIGHT', 300); // hoogte van een individueel plaatje
define('FREQUENTIE', 0.1); // frequentie, hoe lager hoe mooier de golven
// zichtbaar zijn. ong: 1 / aantal pixels per golf
define('BRON_VERSCHIL_STAP', 2); // stapgrote waarmee de bronnen uit elkaar
// bewegen
/**
* Golffuncties
*/
function standaardGolf($t)
{
return sin(2 * pi() * FREQUENTIE * $t);
}
function omgekeerdeGolf($t)
{
return standaardGolf($t) * -1;
}
/**
* Definitie van een positie. Een positie kan zijn afstand ten opzichte van
* een andere positie uitrekenen. Handig voor $t voor de golffuncties.
*/
class Positie {
public
$x,
$y;
public function __construct($x, $y)
{
$this->x = $x;
$this->y = $y;
}
public function afstand(Positie $ander)
{
return sqrt(
pow(max($this->x, $ander->x) - min($this->x, $ander->x), 2)
+ pow(max($this->y, $ander->y) - min($this->y, $ander->y), 2)
);
}
}
/**
* Een bron is een golffunctie op een beplaald punt. Met behulp van de functie
* en de afstand tussen de positie van de bron en de positie van de pixel die
* wordt uitgerekend wordt de fase bepaald, welke verantwoordelijk is voor
* de grijze tint.
*/
class Bron {
public
$positie,
$functie;
public function __construct(Positie $positie, $functie = 'standaardGolf')
{
$this->positie = $positie;
$this->functie = $functie;
}
public function fase($t)
{
$f = $this->functie;
return $f($t);
}
}
$x = IMAGES * WIDTH;
$y = IMAGES * HEIGHT;
$spectrum = array();
$img = imagecreatetruecolor($x, $y);
$positie = new Positie(0, 0);
$offset = new Positie(0, 0);
// Spectrum met kleuren maken. Naja, kleuren, eigenlijk 256 grijswaarden
for($i = 0; $i < 256; $i++) {
$spectrum[$i] = imagecolorallocate($img, $i, $i, $i);
}
$i = 0;
// lussen voor de plaatjes
for($offset->y = 0; $offset->y < $y; $offset->y += HEIGHT) {
for($offset->x = 0; $offset->x < $x; $offset->x += WIDTH) {
// positie bronnen bepalen, staat hier omdat $i variabel is.
$bronnen = array(
new Bron(
new Positie((WIDTH / 2) - $i, 50),
'standaardGolf'),
new Bron(
new Positie((WIDTH / 2) + $i, 50),
'omgekeerdeGolf')
);
$i += BRON_VERSCHIL_STAP;
// lussen voor de pixels van het plaatje
for($positie->x = 0; $positie->x < WIDTH; $positie->x++) {
for($positie->y = 0; $positie->y < HEIGHT; $positie->y++) {
$intensiteit = 0;
// bereken voor iedere bron de intensiteit op dit punt
foreach($bronnen as $bron) {
$intensiteit += $bron->fase($positie->afstand($bron->positie));
}
$intensiteit = $intensiteit / count($bronnen);
// kleur de pixel op dit punt op basis van de intensiteit met
// één van de kleuren uit het spectrum.
imagesetpixel(
$img,
$positie->x + $offset->x,
$positie->y + $offset->y,
$spectrum[round((($intensiteit + 1) / 2) * 255, 0)]);
}
}
}
}
// Plaatje omzetten naar iets gangbaars en opsturen naar de browser
header('Content-Type: image/png');
imagepng($img);
?>
Reacties
0