popp0102 has asked for the wisdom of the Perl Monks concerning the following question:

Hello Monks, I'm new to this forum. I'm currently trying to create something akin to paint. I've created a grid of pixels. Everything seems to be working just fine except when i draw something too quickly the pixels in between seem to be getting skipped. It is as if the mouse is too fast for the perl program. How can I deal with this? Here is my code: (left click will start the drawing process)
use Tk; use strict; use warnings;
###Configurable Variables### my $pixel_size = 20; my $window_width = 1800; my $window_height = 1000;
#####create the Main Window##### my $mw = new MainWindow(-title => "BACnet Brush 1.0"); $mw -> geometry("1800x1000"); #resize the main window
#####Clear Button##### # This button clears the screen my $clear_button = $mw -> Button(-text => "Clear",-command => \&clear) + -> place(-x => $window_width*.5, -y => $window_height*.05);
#####create the canvas##### my $canv_width = .75*$window_width; my $canv_height = .8*$window_height; my $canvas = $mw -> Canvas(-width => $canv_width, -height => $canv_hei +ght, -relief => "sunken"); $canvas -> place(-x => .1*$window_width, -y => .1*$window_height);
#####creating the pixel grid on the canvas##### #pixel size> my $pixel_width = $pixel_size;> my $pixel_height = $pixel_size;>
#position variables for the grid> my $init_x = 0; my $init_y = 0; my $next_x = $pixel_width; my $next_y = $pixel_height;
#the pixel grid my @pixel_id; # this array stores all of the unique ids for each pixel $pixel_counter = 0; for(my $j = $init_y; $j < $canv_height; $j = $j + $pixel_height) { <for(my $i = $init_x; $i < $canv_width;$i = $i + $pixel_width) { $pixel_id[$pixel_counter] = $canvas -> createRectangle($init_x,$ +init_y,$next_x,$next_y,-fill => "white",-outline => "gray"); $init_x = $next_x; $next_x = $next_x + $pixel_width; $pixel_counter++; } $init_x = 0; $next_x = $pixel_width; $init_y = $next_y; $next_y = $next_y + $pixel_height; }
#####configuring the pixel grid #### for( my $k = 1; $k <= scalar(@pixel_id); $k++) { my $l = $k; $canvas->bind($k, "<M1-Enter>", sub { $canvas->itemconfigure($l, -fill => "blue"); }); }
##### Functions ##### ###Clear Function### sub clear { <$canvas -> itemconfigure('all', -fill => "white"); } MainLoop();

Replies are listed 'Best First'.
Re: Event Recognition seems to be too slow
by jethro (Monsignor) on May 18, 2009 at 22:03 UTC
Re: Event Recognition seems to be too slow
by boblawblah (Scribe) on May 18, 2009 at 22:03 UTC
Re: Event Recognition seems to be too slow
by AnomalousMonk (Archbishop) on May 19, 2009 at 01:40 UTC
    In addition to How do I post a question effectively?, please also take a look at Markup in the Monastery and Perl Monks Approved HTML tags.
    I'm sorry if this isn't the correct format you need.
    Is it the format you need? Did your post look comprehensible to you when you previewed it? (You did preview it, didn't you?) If you could not understand it, we cannot.

    I realize that there may seem to be a lot of fussy and needless rules associated with this site: I was a bit frustrated myself when I first started posting here. But please know that learning and using a fairly small subset of the rules will make life a lot easier for everyone, including yourself.

    It seems that you went to a lot of trouble to post something that no one, not even you, can understand. Please go back and Update your post using  <c> ... </c> tags – and please get rid of all those < and > signs!

      I hope this is better. Sorry about before. Like I said I'm new to this forum.
Re: Event Recognition seems to be too slow
by BrowserUk (Patriarch) on May 20, 2009 at 00:15 UTC
    It is as if the mouse is too fast for the perl program.

    If you start up MSPaint (or any other paint program probably), and doodle circles or spirals very quickly, you'll notice that instead of smooth arcs, they are made up of a series of short straight lines.

    This is because you can move the mouse far faster than even a compiled C program can keep up with. What the authors of MSPaint do is to remember the last mouse position, and each time they get a new one, the join the old position to the new one with a straight line. At slow speeds, this gives the appearance of smooth arcs as the lines are very short, just 2 or 3 pixels. As the mouse speed increases, so the events are further and further apart, and the straight lines become more and more obvious.

    You could do a similar thing within your program. Draw a line from the last position (set when drawing is initiated), to the current position; and then overwrite the last position with the current before leaving the bound sub in preparation for the next.

    The are a couple of problems with doing this as your program is currently written.

    1. As you are storing and laballing your 'pixels' as a single 1D array, calculating the line between the two positions becomes unnecessarially complex.

      You could simplify this by storing and labelling your grid using a 2D array/labels.

    2. The second problem is more intractable. Using a whole canvas item object for each pixel in a paint-type app is a rather heavyweight solution Both in memory consumption and processor use.

      The solution is a lot more complex than what you currently have. Basically it involves building up the item line by line in an (normal perl) array and drawing it as a single Line item, adding each new set of coordinates as the mouse moves and deleting the old one.

      In this way, once a line is drawn, it can be selected and manipulated--highlighted; color changed; deleted etc.--as a single item rather than a collection of pixels. But, its quite a lot of work.

    Anyway, maybe this will inspire you to move forward with what you are doing.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.