Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Lissajous curves

by ambrus (Abbot)
on Jun 14, 2007 at 08:46 UTC ( [id://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.

Replies are listed 'Best First'.
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
Domain Nodelet?
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?Last hourOther CB clients
Other Users?
Others perusing the Monastery: (7)
As of 2024-03-28 19:02 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found