Welcome to the Monastery PerlMonks

### Drawing lines and circles

by studymonkperl (Novice)
 on Oct 01, 2013 at 08:14 UTC Need Help??
studymonkperl has asked for the wisdom of the Perl Monks concerning the following question:

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";
}
}

Replies are listed 'Best First'.
Re: Drawing lines and circles
by RichardK (Parson) on Oct 01, 2013 at 08:35 UTC

Create A New User
Node Status?
node history
Node Type: perlquestion [id://1056450]
Approved by hdb
Front-paged by Corion
help
Chatterbox?
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (5)
As of 2018-01-23 22:23 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
How did you see in the new year?

Results (254 votes). Check out past polls.

Notices?