New topic: 

Canvas.Mousedrag too slow?

<http://forums.realsoftware.com/viewtopic.php?t=46558>

         Page 1 of 1
   [ 9 posts ]                 Previous topic | Next topic          Author  
Message        alexvs          Post subject: Canvas.Mousedrag too slow?Posted: 
Mon Jan 14, 2013 11:52 am                         
Joined: Fri Feb 12, 2010 1:32 pm
Posts: 219
Location: Switzerland                Hey there

To try something for another project I quickly came up with a canvas that 
mimiks a chalkboard.

In the mousedown/-drag events I record the mouse position, call the canvas to 
refresh and return true. In the respective paint event I then draw the recorded 
points. Basically everything works fine except that it's to slow. Instead of a 
line it paints single points when moving the mouse at normal speed. Only when 
moving slowly, a line is being drawn (see example screenshot below). My guess 
is that the mousedrag event is called too infrequently - or what might be the 
issue in your opinion?

Thanks,
Alex

     

    Last edited by alexvs on Mon Jan 14, 2013 12:03 pm, edited 1 time in total. 
  
                             Top                DaveS          Post subject: 
Re: Canvas toh slow?Posted: Mon Jan 14, 2013 12:02 pm                           
      
Joined: Sun Aug 05, 2007 10:46 am
Posts: 4412
Location: San Diego, CA                A lot has to do with exactly how you are 
implementing this....

I have a drawing program that works just fine...... except when you move the 
mouse at super-speed.  but for normal to quick drawing activities it produces a 
nice line.

It has to do with how are you keeping track of the mouse points?  are you 
calling REFRESH or INVALIDATE?

And no matter what... your best bet is to connect the dots..... because it will 
be near impossible to catch a single pixel movement, store the data and redraw 
the screen .

Of course you can get really fancy, and apply a Bezier function to your points 
and get a mathematically smoothed line as well.      
_________________
Dave Sisemore
MacPro, OSX Lion 10.7.4 RB2012r1
Note : I am not  interested in any solutions that involve custom Plug-ins of 
any kind  
                             Top                alexvs          Post subject: 
Re: Canvas toh slow?Posted: Mon Jan 14, 2013 12:11 pm                         
Joined: Fri Feb 12, 2010 1:32 pm
Posts: 219
Location: Switzerland                Thanks for your reply, Dave.

DaveS wrote:It has to do with how are you keeping track of the mouse points?  
are you calling REFRESH or INVALIDATE?


I went for invalidate, however I also tried refresh with no difference.
For keeping track of the dots I have a very simple class ("stroke") that has an 
array with the dots (of type Realbasic.Point), since I want to be able to keep 
track of the single strokes the user does. In the mousedown event I create an 
instance of that class, add the first point, call invalidate and return true:

Function MouseDown(X As Integer, Y As Integer) As Boolean
  dim s as new stroke
  
  s.StrokeColor = ForegroundColor
  s.LineThickness = LineThinkness
  s.AddPoint(x,y)
  
  History.append s
  
  me.invalidate
  
  return true
End Function


In the mousedrag event I pick up the latest instance in the array and add the 
point handed over by the event and do the same again:

Sub MouseDrag(X As Integer, Y As Integer)
  dim s as stroke
  
  s = history(history.Ubound)
  s.AddPoint(x,y)
  
  me.Invalidate
End Sub



In the paint event, I then loop through the points and draw them:

Sub Paint(g As Graphics, areas() As REALbasic.Rect)
  //paint Background
  
  g.ForeColor = me.BackgroundColor
  g.FillRect 0,0,me.Width,me.Height
  
  
  //paint the points in the history array
  
  for i as integer = 0 to history.Ubound
  dim s as stroke = history(i)
  g.ForeColor = s.StrokeColor
  for j as integer = 0 to s.PointCount-1
  dim p as realbasic.point = s.Point(j)
  g.FillOval p.X,p.y,s.LineThickness,s.LineThickness
  next
  next
End Sub


Some methods and properties refer to the Stroke and or my custom Canvas class.

DaveS wrote:
And no matter what... your best bet is to connect the dots..... because it will 
be near impossible to catch a single pixel movement, store the data and redraw 
the screen .

Of course you can get really fancy, and apply a Bezier function to your points 
and get a mathematically smoothed line as well.

Well, in the screenshot attached above, I moved the mouse quite slowly. Moving 
it at normal speed results in even bigger gaps. I do consider connecting the 
dots, however I think the dots need to be closer to each other first. Otherwise 
the results won't be very satisfying. How are you doing this in your paint app?

Thanks,
Alex

Edit: The "Stroke" class:

Class Stroke
  
  Stroke.AddPoint:
  Sub AddPoint(x as integer, y as integer)
  points.append new REALbasic.Point(x, y)
  End Sub
  
  Stroke.LastPoint:
  Function LastPoint() As REALbasic.Point
  return Points(Points.Ubound)
  End Function
  
  Stroke.Point:
  Function Point(index as integer) As REALbasic.Point
  return Points(index)
  End Function
  
  Stroke.PointCount:
  Function PointCount() As integer
  return Points.Ubound+1
  End Function
  
  Properties:
  LineThickness As Integer = 5
  Points() As REALbasic.Point
  StrokeColor As Color = &cFFFFFF
  
End Class
   
                             Top                doofus          Post subject: 
Re: Canvas toh slow?Posted: Mon Jan 14, 2013 1:19 pm                            
     
Joined: Thu Sep 10, 2009 2:50 am
Posts: 335
Location: Santa Cruz, CA, USA                alexvs wrote:I went for 
invalidate, however I also tried refresh with no difference.
me.invalidate
In the paint event, I then loop through the points and draw them:

You're redrawing the entire canvas every time, instead only repaint the 
necessary region using invalidate(x,y,w,h) or refreshRect.
You should only be drawing the latest dot. I think this may need a buffer 
picture or the backdrop may work.   
                             Top                kermit          Post subject: 
Re: Canvas.Mousedrag too slow?Posted: Mon Jan 14, 2013 2:04 pm                  
       
Joined: Mon May 30, 2011 12:56 am
Posts: 590                consider adding a Group2D object to the visible 
graphic.
Instead of adding points to your list, .append curve shapes  (probably just 
straight lines) to the group.
(These lines start at previousx,previousy and end at x,y )

The group will redraw itself automatically when the picture is refreshed.
You dont need to iterate through the points array every time, and you dont need 
to explicitly draw the dots.
Using lines means you get no gaps, but feel free to add dots instead if you 
like   
                             Top                timhare          Post subject: 
Re: Canvas.Mousedrag too slow?Posted: Mon Jan 14, 2013 6:04 pm                  
       
Joined: Fri Jan 06, 2006 3:21 pm
Posts: 11982
Location: Portland, OR  USA                Use a buffer picture.  Your Paint 
event is doing way too much work and slowing you down.   
                             Top                npalardy          Post subject: 
Re: Canvas.Mousedrag too slow?Posted: Mon Jan 14, 2013 6:21 pm                  
     Real Software Engineer          
Joined: Sat Dec 24, 2005 8:18 pm
Posts: 7674
Location: Canada, Alberta, Near Red Deer                alexvs wrote:Hey there

To try something for another project I quickly came up with a canvas that 
mimiks a chalkboard.

In the mousedown/-drag events I record the mouse position, call the canvas to 
refresh and return true. In the respective paint event I then draw the recorded 
points. Basically everything works fine except that it's to slow. Instead of a 
line it paints single points when moving the mouse at normal speed. Only when 
moving slowly, a line is being drawn (see example screenshot below). My guess 
is that the mousedrag event is called too infrequently - or what might be the 
issue in your opinion?

Thanks,
Alex



1) just have the code update some internal class that represents the item being 
drawn as long as the mouse stays down (so just have  "line" class that has a 
start & end points & update the end point based on the current position)
2) invalidate instead of refresh
3) in the pain redraw the line based on the start & end points      
_________________
My web site Great White Software
RBLibrary.com REALbasic learning  
                             Top                alexvs          Post subject: 
Re: Canvas toh slow?Posted: Tue Jan 15, 2013 5:19 am                         
Joined: Fri Feb 12, 2010 1:32 pm
Posts: 219
Location: Switzerland                Guys, you're awesome. I'm overwhelmed by 
the number of replies and the support I get in these forums. Let me go through 
your answers post by post:

doofus wrote:You're redrawing the entire canvas every time, instead only 
repaint the necessary region using invalidate(x,y,w,h) or refreshRect.
You should only be drawing the latest dot. I think this may need a buffer 
picture or the backdrop may work.
timhare wrote:Use a buffer picture.  Your Paint event is doing way too much 
work and slowing you down.

I added a buffer and things got waaay better, though still gaps exist. I also 
went for invalidate(x,y,w,h), which makes sense. However, in the paint event, 
the areas() parameter always seems to be empty, thus requiring repainting of 
the whole graphics. How comes? I'd rather just repaint what needs to be 
repainted.

npalardy wrote:1) just have the code update some internal class that represents 
the item being drawn as long as the mouse stays down (so just have  "line" 
class that has a start & end points & update the end point based on the current 
position)
2) invalidate instead of refresh
3) in the pain redraw the line based on the start & end points

1) But with lines - I'd get straight lines only, nothing like shown in my 
screenshot. Maybe I do misunderstand you?
2) Already doing
3) see 1)

kermit wrote:consider adding a Group2D object to the visible graphic.
Instead of adding points to your list, .append curve shapes  (probably just 
straight lines) to the group.
(These lines start at previousx,previousy and end at x,y )

The group will redraw itself automatically when the picture is refreshed.
You dont need to iterate through the points array every time, and you dont need 
to explicitly draw the dots.
Using lines means you get no gaps, but feel free to add dots instead if you like

That seems like an interesting approach, will give it a try!

Alex   
                             Top                alexvs          Post subject: 
Re: Canvas.Mousedrag too slow?Posted: Tue Jan 15, 2013 5:43 am                  
       
Joined: Fri Feb 12, 2010 1:32 pm
Posts: 219
Location: Switzerland                Painting a line between the dots made it 
pretty perfect. The only thing I don't like so far (I'm an esthete...) is that 
I don't get rounded corners at the start and the end of a stroke which I 
initially planned by using the oval shape for the points. But that's peanuts    
                             Top             Display posts from previous: All 
posts1 day7 days2 weeks1 month3 months6 months1 year Sort by AuthorPost 
timeSubject AscendingDescending          Page 1 of 1
   [ 9 posts ]      
-- 
Over 1500 classes with 29000 functions in one REALbasic plug-in collection. 
The Monkeybread Software Realbasic Plugin v9.3. 
http://www.monkeybreadsoftware.de/realbasic/plugins.shtml

[email protected]

Reply via email to