#!/usr/bin/perl use strict; use warnings; #This will let me handle the output as a simple matrix. # A simple screen abstraction, actually a long array package Screen; sub new { # Get a Screen of given sizes my ($class, $wx, $wy) = @_; my $self = {_wx => $wx, _wy => $wy, _data => [ ((' ') x $wx , "\n") x $wy ]}; bless $self, $class; } sub _index { # Find index of given coordinate into vector my ($self, $x, $y) = @_; return $x + ($y * (1 + $self->{_wx})); } # Public methods sub inbound { # Test if coordinates are within Screen bounds my ($self, $x, $y) = @_; return ($x >= 0 && $y >= 0 && $x < $self->{_wx} && $y < $self->{_wy +}); } sub set { # Set value $v at given coordinates, with clipping my ($self, $x, $y, $v) = @_; return undef unless $self->inbound($x, $y); $self->{_data}->[$self->_index($x, $y)] = $v; } sub to_string { # Dump Screen onto string return join('', @{$_[0]->{_data}}); } #Back to reality. The main cycle gets a new ASCII clock representation + every second and prints it. package main; use POSIX 'ceil'; my $pi2 = 2 * atan2(0, -1); # Useful to have around my ($wx, $wy) = @ARGV; # Accept sizes from command line while (1) { # Cycle forever, updating each second print "\e[2J", anaclock($wx, $wy); sleep(1); } #Accessor functions. The adjust function rounds numbers to have intege +r matrix indexes; # in the meanwhile, it also performs a translation by 1 cell - please +don't ask me why, # it works :) #The two drawing functions do what they declare. # Round and translate to better fit inside the screen sub adjust {return ceil($_[0] - 1.5);} sub draw_circle { my ($screen, $cx, $cy, $rx, $ry, $c) = @_; my $radius = ($rx > $ry) ? $rx : $ry; my $step = abs(1 / ($radius * $pi2)); for (my $a = 0.0; $a < 2 * $pi2; $a += $step) { $screen->set(adjust($cx + $rx * cos($a)), adjust($cy + $ry * sin($a)), $c); } } sub draw_line { my ($screen, $ax, $ay, $bx, $by, $c) = @_; my ($dx, $dy) = ($bx - $ax, $by - $ay); my ($adx, $ady) = (abs($dx), abs($dy)); my $delta = ($adx > $ady) ? $adx : $ady; $dx /= $delta; $dy /= $delta; for (; $delta > 0; $ax += $dx, $ay += $dy, --$delta) { $screen->set(adjust($ax), adjust($ay), $c); } } #The actual ASCII clock building function. It accepts width and heigth + even # if it increases them by 1 when building the screen- I hope you're re +ally not # going to be annoyed because of this. sub anaclock { my $width = shift || 45; my $height = shift || 23; --$width; --$height; # Too lazy to change code after... my ($rx, $ry) = ($width / 2, $height / 2); my ($cx, $cy) = (1 + $rx, 1 + $ry); # Get a virtual screen to write onto; get it a little larger # to cope with roundups my $screen = Screen->new($width + 1, $height + 1); # Draw the surronding circle draw_circle($screen, $cx, $cy, $rx, $ry, '.'); # Decrease radius to be strictly inside $rx *= 6/8; $ry *= 6/8; # What time is it? my ($sec, $min, $hour) = (localtime(time))[0 .. 2]; # Scale values to get angles. Note that $min is shifted by the # seconds, and $hour is shifted by the minutes. $sec *= $pi2 / 60; $min = ($min * $pi2 + $sec) / 60; $hour = (($hour % 12) * $pi2 + $min) / 12; # Draw lines. According to most clocks, hours are in background and # seconds in foreground. draw_line($screen, $cx, $cy, $cx + $rx * sin($hour) * 2 / 3, $cy - $ry * cos($hour) * 2 / 3, '#'); draw_line($screen, $cx, $cy, $cx + $rx * sin($min), $cy - $ry * cos($min), '+'); draw_line($screen, $cx, $cy, $cx + $rx * sin($sec), $cy - $ry * cos($sec), '.'); # Return a string representation return $screen->to_string(); }

In reply to ASCII analog clock by polettix

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.