Very good idea. I used to draw such curves with basic too. So here's a perl one, just to disprove blazar's statement.
#!perl
use warnings; use strict;
sub pie() {
2 * atan2(1, 0);
}
sub asin {
atan2($_[0], sqrt(1 - $_[0]**2));
}
sub liss {
my($p_m, $p_n, $p_d) = @_;
my($ht, $wd) = (24, 60);
for my $l (0 .. $ht - 1) {
my $ou = " " x ($wd + 1);
my($y0, $y1) = (2 * $l / $ht - 1, 2 * ($l + 1) / $ht - 1);
my($su0, $su1) = (asin($y0), asin($y1));
for my $br (0 .. $p_m - 1) {
for my $sgn (0, 1) {
my($u0, $u1) =
($br * 2 * pie + $sgn * pie + $su0 * ($sgn?-1:1),
+$br * 2 * pie + $sgn * pie + $su1 * ($sgn?-1:1));
my($v0, $v1) = ($u0 / $p_m * $p_n + $p_d, $u1 / $p_m *
+ $p_n + $p_d);
my($x0, $x1) = (sin($v0), sin($v1));
$x1 < $x0 and ($x0, $x1) = ($x1, $x0);
int(($v0 - pie / 2) / 2 / pie) == int(($v1 - pie / 2)
+/ 2 / pie) or
$x1 = 1;
int(($v0 + pie / 2) / 2 / pie) == int(($v1 + pie / 2)
+/ 2 / pie) or
$x1 = -1;
my($p0, $p1) = (($x0 + 1) / 2 * $wd, ($x1 + 1) / 2 * $
+wd);
my ($ps, $pd) =
int($p0) < int($p1) ?
(int($p0), int($p1) - int($p0)) :
(int(($p0 + $p1 + 1) / 2), 1);
substr($ou, $p0, $pd) =~ y/ /*/;
}
}
print $ou, "\n";
}
}
# -log(r)/p = x
for (0 .. 19) {
print "\n" x 4;
my $r = sub { int(1 - log(1-rand(0.999)) / $_[0]) };
my($m, $n) = (&$r(0.7), &$r(0.9));
liss $m, $n, rand(2*pie);
sleep 3;
}
__END__
Update: I just want to mention that a classmate of mine has told me some years ago that you can render conic sections fast this way. This program uses basically the same algorithm except that it uses trigonometric functions instead of just square root. (Update: Yeah, except that this one is also cheating: where it says (p0+p1)/2, it should really use the p for (x0+x1)/2 really.)
Update: posted changed version at
Lissajous curves |