Monks,

I'm trying to learn graphics algorithms. But before that I'm learning how to draw simple shapes like lines, circles etc, On the console. I know this sort of thing can be achieved easily using some graphics library, But I want to first learn how to draw it on the console.

The idea is to imagine each pixel as separated by a space horizontally and a line break vertically. The issue is you can never get a perfectly straight line. Basically the co ordinates you generate rarely match the integer points on the grid. I realize the same thing happens on the monitor screen too, except the pixels are too small for us to notice.

I wrote this code today morning, is there a nice way to do this?

use strict; use warnings; use Data::Dumper; my $gridx = 10; my $gridy = 10; my $pixel = '.'; my $x1 = 1; my $y1 = 2; my $x2 = 8; my $y2 = 2; my $gr = draw_line( $x1 , $y1 , $x2 , $y2 , 0 , $pixel , $gridx , $gri +dy ); draw_pixels_on_screen( $gr , $gridx , $gridy ); $x1 = 3; $y1 = 1; $x2 = 3; $y2 = 7; $gr = draw_line( $x1 , $y1 , $x2 , $y2 , 0 , $pixel , $gridx , $gridy +); draw_pixels_on_screen( $gr , $gridx , $gridy ); $x1 = 2; $y1 = 3; $x2 = 7; $y2 = 9; $gr = draw_line( $x1 , $y1 , $x2 , $y2 , 0 , $pixel , $gridx , $gridy +); draw_pixels_on_screen( $gr , $gridx , $gridy ); sub draw_line{ my ( $x1 , $y1 , $x2 , $y2 , $yaxisintercept , $pixel , $gridx , $gridy ) = @_; my @grid; my $i = 0; my $j = 0; for( $i = 0 ; $i <= $gridx ; $i++ ){ for( $j = 0 ; $j <= $gridy ; $j++ ){ $grid[$i][$j] = " "; } } if( ( $x2 == $x1 ) && ( $y2 == $y1 ) ){ $grid[$x2][$y2] = $pixel; }elsif( $x2 == $x1 ){ #for a vertical line slope is undefined while( $y2 != $y1 ){ $grid[$x1][$y1] = $pixel; $y1++; } }elsif( $y2 == $y1 ){ $yaxisintercept = $y2; while( $x2 != $x1 ){ $grid[$x1][$y1] = $pixel; $x1++; } }else{ my $slope = find_slope( $x1 , $y1 , $x2 , $y2 ); #$slope = int( $slope + 0.5 ); #breaks when this line is comme +nted while( $x1 != $x2 ){ my $x = $x1; my $y = ( $slope * $x ) + $yaxisintercept; $grid[$x][$y] = $pixel; $x1++; } } return \@grid; } sub find_slope{ my ( $x1 , $y1 , $x2 , $y2 ) = @_; #Note y = mx + c is the equation of a line # Given two equations (y1) = m(x1) + c and (y2) = m(x2) + c # Subtracting second equation from first you get m as my $m = ( $y2 - $y1 ) / ( $x2 - $x1 ) ; return $m; } sub draw_pixels_on_screen{ my ( $grid_values , $x_axis_limit , $y_axis_limit ) = @_; my @grid = @$grid_values; my $x = 0; my $y = 0; for( $x = $x_axis_limit ; $x >= 0 ; $x-- ){ for( $y = 0 ; $y <= $y_axis_limit ; $y++ ){ print $grid[$y][$x]; } print "\n"; } }

In reply to Drawing lines and circles by studymonkperl

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.