Beefy Boxes and Bandwidth Generously Provided by pair Networks Cowboy Neal with Hat
We don't bite newbies here... much
 
PerlMonks  

Lissajous curves

by ambrus (Abbot)
on Jun 14, 2007 at 08:46 UTC ( #621188=CUFP: print w/ replies, xml ) Need Help??

This script is a close variant of Re^2: [ASCII art graphs] Kisses. It's drawing Lissajous curves in ascii-art.

Big thanks to dewey and blazar who gave me the idea in that thread.

#!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); my $ou; for my $l (0 .. 2 * $ht - 1) { 0 == $l % 2 and $ou = " " x ($wd + 1); my($y0, $y1) = (2 * $l / (2 * $ht) - 1, 2 * ($l + 1) / (2 * $h +t) - 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); my $repl = \substr($ou, $p0, $pd); 0 == $l % 2 ? $$repl =~ y/ /'/ : $$repl =~ y/ '/,;/; } } 1 == $l % 2 and print $ou, "\n"; } } 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__

Here's an example output:

,'''', ,'''''', ,'', ; ', ,' ', ,' ', ; ; ; ; ; ; ; ; ; ', ; ; ; ; ; ', ,' ; ; ', ; ', ; ; ; ',; ', ; ; ; ;' ; ,' ; ; ,'; ; ; ; ; ; ; ; ; ; ; ; ', ; ,' ; ; ,' ', ', ; ; ; ; ; ; ; ; ; ; ; ; ,' ; ; ,' ', ; ; ; ; ; ', ',; ; ; ; ', ;, ,' ; ,' ; ,'; ; ; ; ; ,' ; ; ; ; ; ,' ; ,' ; ,' ; ,' ', ; ; ; ', ,' ', ,' ; ; ', ,' ', ; ;,' ',,,,,,' ;,,,'

Update: liverpole pointed out to Spiro Japh, his obfu that's also producing Lissajous curves.

Comment on Lissajous curves
Select or Download Code
Re: Lissajous curves
by merlyn (Sage) on Jun 14, 2007 at 15:04 UTC

      Sure you can, but atan2 has a branch cut there so you have to know that it returns pi, not minus pi which would also make sense to me (though the IEEE 754 committee might have had a reason).

      Update 2011-04-18: in fact, appendix F of the C99 standard states that atan2 with zero first argument and negative second argument gives pi with the sign copied from the zero. This guarantees that atan2(-1,0) must return positive pi. You can see that indeed perl will give negative pi for a negative zero first argument:

      $ perl -wE '$x = -1; $x/=2 for 1..9999; $,=" "; say $x, atan2($x,-1), +atan2(0,-1);' -0 -3.14159265358979 3.14159265358979
Re: Lissajous curves
by blazar (Canon) on Jun 22, 2007 at 09:25 UTC
    This script is a close variant of Re^2: [ASCII art graphs] Kisses. It's drawing Lissajous curves in ascii-art.

    Sorry for replying so late: since there you say "So here's a perl one, just to disprove blazar's statement" and my statement was that "those [Lissajous figures] would have required either ANSI sequences (and then are nice to be seen while being drawn - I wanted something to paste into email instead) or mangling with a buffer"... I've long wanted to reply: well done! Actually the basics of your approach are easy to understand: instead of drawing implicitly, just do so explicitly, taking slices. Had you asked me in advance wrt Lissajous figures, I would have told: oh yeah, certainly possible - an exercise of masochism, if one exists. But your code contradicts me, since it doesn't seem that overly complex after all. Yet in its minimality, it looks much like a macho algorithm master show off: to work out the details for the uninitiated and the less knowledgeable is certainly possible, but likely to take some time. So why don't you consider expanding it to a full tutorial or something like that? IMHO it will be certainly instructive and Perl is not generally considered for this "kinda stuff", but why not anyway?

Re: Lissajous curves
by ambrus (Abbot) on Feb 27, 2012 at 19:36 UTC

    Try to replace the main loop with the following:

    use Time::HiRes "sleep"; use List::Util qw"min max"; for (0 .. 19) { print "\n" x 4; my $r = sub { 1 + int(min(rand($_[0]), rand($_[0]-1))) }; my($m, $n) = (&$r(7), &$r(7)); my $p = rand(2*pie); for my $_c (1 .. 100) { liss $m, $n, $p; sleep 0.03; $p += 0.4 / (3 + max($m, $n)); } sleep 0.5; }

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: CUFP [id://621188]
Approved by marto
Front-paged by planetscape
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (8)
As of 2014-04-21 09:08 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    April first is:







    Results (492 votes), past polls