#!/usr/app/bin/perl eval 'exec /usr/app/bin/perl -S $0 ${1+"$@"}' if 0; # not running under some shell use Gimp; use Gimp::Fu; use Gimp::Util; # this is silly, sorry that I am too dumb to come up with niftier functions :( # btw, this should generate something between 1/f and 1/f² noise. { my @weight = (1/8, 1/4, 1/2, 1); my @dice; my $total = 0; my $tweight = 0; my $n = 0; my $seed; sub gen_rand() { my ($prevrand, $newrand, $k); $n++; for (0..$#weight) { if ($n & (1<<$_)) { $prevrand = $dice[$_]; $newrand = rand() * $weight[$_]; $dice[$_] = $newrand; $total += $newrand - $prevrand; } } $total / $tweight; } sub set_seed($) { if ($_[0]) { srand $_[0]; } else { srand; } $total = 0; $tweight = 0; for (0..$#weight) { $dice[$_] = rand()*$weight[$_]; $total += $dice[$_]; $tweight += $weight[$_]; } } } # the next line just shows a graph of the "random" numbers. #set_seed 0; use PDL; use PDL::Graphics::PGPLOT; line(pdl(float,map gen_rand, 1..500)); register "dust", "", "", "Marc Lehmann", "Marc Lehmann /Filters/Render/Add Dust...", "*", # Eingabeparameter # Typ Name Beschreibung Wert [ [PF_FLOAT, 'density', 'dust density in dust/pixel', 0.0001], [PF_INT32, 'seed', 'the random seed (0 == unspecified)', 0], [PF_SPINNER, 'length', 'the average dust corn length', 50, [1,300]], ], sub { # Perl-Code # Die Parameter werden ganz "normal" übergeben: my ($image, $layer, $density, $seed, $len) = @_; $len *= 0.75; set_seed $seed; my ($w, $h) = ($image->width, $image->height); $image->undo_push_group_start; my $state = Gimp::Util::get_state(); Palette->set_foreground("white"); Brushes->set_brush("Circle (01)"); Brushes->set_opacity(50); Brushes->set_spacing(100); Brushes->set_paint_mode(NORMAL_MODE); if (1) { $layer = $image->add_new_layer (0, TRANS_IMAGE_FILL, 1); $layer->set_mode(DIFFERENCE_MODE); } for (1..($w*$h*$density)) { my ($x, $y) = (rand $w, rand $h); my $l = int($len + rand $len); my @c; my $b = 0; for (1..$l) { push @c, $b += 5*(gen_rand-0.5); push @c, $b += 5*(gen_rand-0.5); } $layer->paintbrush_default([map { $x+$c[$_], $y+$c[$_+$l] } 0..$l-1]); } Gimp::Util::set_state($state); $image->undo_push_group_end; (); }; #register "gen_rand_1f", # "generate 1/f noise", # "Generate approximate 1/f (white) noise in the range [0,1[", # "Marc Lehmann", # "Marc Lehmann ", # undef, # # Eingabeparameter # # Typ Name Beschreibung Wert # [ # [PF_FLOAT, 'count', 'the number of values', 1], # [PF_INT32, 'seed', 'the random seed (0 == unspecified)', 0], # ], # [ # [&Gimp::PDB_FLOATARRAY,'noise','the requested number of 1/f noise values'], # ], # sub { # my ($count, $seed) = @_; # set_seed $seed; # [map gen_rand_1f, 1..$count]; # }; exit main;