Hello there,
Long time ago i could not find a drawing program that i liked for Windows so i created one that could do things that i wanted a drawing program to do and be able to update it anytime with new features that would aide in drawing various things including schematics but also fine art. Recently however i noticed a problem that for some reason i never noticed before or didnt pay enough attention to in order to figure out that there was something actually very strange about drawing with the mouse.
Many drawing problems have a Zoom capability, and mine is no different. You can zoom in, you can zoom out. There is an interesting difference though in the way these two are related to the mouse movement.
When you zoom *IN* 2x (and this would be with any drawing program) the image gets 2 times larger and so when you move the mouse say one pixel to the right your graphic pixel position is really only 1/2 pixel to the right in the actual bitmap image. This doesnt seem to present any problem. However, when you zoom *OUT* and move the mouse one pixel to the right the distance the mouse pointer travels relative to the image is now 2 pixels. This creates a bit of a problem because if you draw one pixel for every mouse pixel movement, the line created by the mouse then appears as a dotted line with every other pixel remaining whatever color it was before the mouse was moved. So a black pixel color on a white background looks like a dotted black line with dots spaced 1 pixel apart. That is a problem because we dont want a dotted line when we want to draw a solid line. What is even worse is if we zoom out another time (like to 4x out) then the dots are even farther apart because now one mouse pixel movement spans 4 pixels on the actual bitmap image. I think i never noticed this before because i usually draw when the image is zoomed in, and that means that if i zoom in by 2x one pixel mouse movement covers just 1/2 pixel and so that means that each pixel gets drawn twice, which isnt really too much of a problem except with blend operations where the blend will occur twice. I am not so worried about that though because that's easy to fix by adjusting the blend ratio.
To make matters worse, WM_MOUSEMOVE only reports every 2 pixels but that is probably a separate issue.
So how to handle this. In the image attached i have drawn four circles. The four circles are drawn in a commercial program known as MSPaint that comes with most versions of the Windows operating system. I wanted to see how they handled this, even though i know they dont do the best with drawing programs.
The four difference circles are drawn with the following zoom levels:
1: zoom in 200 percent.
2: zoom standard, 100 percent (no zooming).
3: zoom out 200 percent.
4: zoom out 400 percent.
With these four different zoom levels i draw a circle for each one as close as possible to a free hand circle. The fact that they are not exact circles have nothing to do with this issue so it does not matter that they are not perfect circles. What is interesting though is that we can see that from 1 to 4 the circles get increasingly jagged, and i can guess why.
My guess is that when they get a WM_MOUSEMOVE message they detect current zoom level and the slope of the mouse movement (one of four possible values) and generate more pixel draw operations accordingly. For example, if the user moves the mouse one pixel to the right they fill in the second pixel to the right and also one pixel to the right if the zoom level is such that one pixel is skipped for that zoom level (that would be 100 percent in the drawing with teh circles as strange as that sounds, because the message only reports every 2nd pixel mouse movement as stupid as that is). So as the zoom is changed to 400 percent out, they have to fill in an additional 3 pixels, and the only way to get those locations from one mouse move report is to assume that they all have the same slope. That means either +1, -1, or 0 or completely vertical, and that is with any zoom level because there are no other mouse reports to use in the calculation. Perhaps we can calculate a better response using three mouse reports if there are that many that is. This may or may not work i havent thought about it much yet.
So i think that describes the issues associated with drawing with the mouse, at least with one pixel wide draw operations. OF course 2 pixel wide (2x2 pixels) doesnt have a problem when zooming in 2x but perhaps zooming in 4x will. Also, drawing complete lines is not a problem because there we naturally fill in pixels from one coordinate pair to another such as (1,1) to (5,5) or even (1,2) to (9,4); those pixel fills are all calculated pixel by pixel regardless of the zoom level.
So any ideas or comments would be interesting i think. Remember this issue is mainly only a problem when drawing with a single pixel wide line using the mouse where the mouse is moved across (or up and down) the screen where we would expect every pixel scanned by the pointer would be filled in. Also note that moving the mouse too fast skips pixels also, but that is not an issue. That occurs because Windows does not send more WM_MOUSEMOVE messages to the window than it can accept in a given time, but i have no problem with that.
Long time ago i could not find a drawing program that i liked for Windows so i created one that could do things that i wanted a drawing program to do and be able to update it anytime with new features that would aide in drawing various things including schematics but also fine art. Recently however i noticed a problem that for some reason i never noticed before or didnt pay enough attention to in order to figure out that there was something actually very strange about drawing with the mouse.
Many drawing problems have a Zoom capability, and mine is no different. You can zoom in, you can zoom out. There is an interesting difference though in the way these two are related to the mouse movement.
When you zoom *IN* 2x (and this would be with any drawing program) the image gets 2 times larger and so when you move the mouse say one pixel to the right your graphic pixel position is really only 1/2 pixel to the right in the actual bitmap image. This doesnt seem to present any problem. However, when you zoom *OUT* and move the mouse one pixel to the right the distance the mouse pointer travels relative to the image is now 2 pixels. This creates a bit of a problem because if you draw one pixel for every mouse pixel movement, the line created by the mouse then appears as a dotted line with every other pixel remaining whatever color it was before the mouse was moved. So a black pixel color on a white background looks like a dotted black line with dots spaced 1 pixel apart. That is a problem because we dont want a dotted line when we want to draw a solid line. What is even worse is if we zoom out another time (like to 4x out) then the dots are even farther apart because now one mouse pixel movement spans 4 pixels on the actual bitmap image. I think i never noticed this before because i usually draw when the image is zoomed in, and that means that if i zoom in by 2x one pixel mouse movement covers just 1/2 pixel and so that means that each pixel gets drawn twice, which isnt really too much of a problem except with blend operations where the blend will occur twice. I am not so worried about that though because that's easy to fix by adjusting the blend ratio.
To make matters worse, WM_MOUSEMOVE only reports every 2 pixels but that is probably a separate issue.
So how to handle this. In the image attached i have drawn four circles. The four circles are drawn in a commercial program known as MSPaint that comes with most versions of the Windows operating system. I wanted to see how they handled this, even though i know they dont do the best with drawing programs.
The four difference circles are drawn with the following zoom levels:
1: zoom in 200 percent.
2: zoom standard, 100 percent (no zooming).
3: zoom out 200 percent.
4: zoom out 400 percent.
With these four different zoom levels i draw a circle for each one as close as possible to a free hand circle. The fact that they are not exact circles have nothing to do with this issue so it does not matter that they are not perfect circles. What is interesting though is that we can see that from 1 to 4 the circles get increasingly jagged, and i can guess why.
My guess is that when they get a WM_MOUSEMOVE message they detect current zoom level and the slope of the mouse movement (one of four possible values) and generate more pixel draw operations accordingly. For example, if the user moves the mouse one pixel to the right they fill in the second pixel to the right and also one pixel to the right if the zoom level is such that one pixel is skipped for that zoom level (that would be 100 percent in the drawing with teh circles as strange as that sounds, because the message only reports every 2nd pixel mouse movement as stupid as that is). So as the zoom is changed to 400 percent out, they have to fill in an additional 3 pixels, and the only way to get those locations from one mouse move report is to assume that they all have the same slope. That means either +1, -1, or 0 or completely vertical, and that is with any zoom level because there are no other mouse reports to use in the calculation. Perhaps we can calculate a better response using three mouse reports if there are that many that is. This may or may not work i havent thought about it much yet.
So i think that describes the issues associated with drawing with the mouse, at least with one pixel wide draw operations. OF course 2 pixel wide (2x2 pixels) doesnt have a problem when zooming in 2x but perhaps zooming in 4x will. Also, drawing complete lines is not a problem because there we naturally fill in pixels from one coordinate pair to another such as (1,1) to (5,5) or even (1,2) to (9,4); those pixel fills are all calculated pixel by pixel regardless of the zoom level.
So any ideas or comments would be interesting i think. Remember this issue is mainly only a problem when drawing with a single pixel wide line using the mouse where the mouse is moved across (or up and down) the screen where we would expect every pixel scanned by the pointer would be filled in. Also note that moving the mouse too fast skips pixels also, but that is not an issue. That occurs because Windows does not send more WM_MOUSEMOVE messages to the window than it can accept in a given time, but i have no problem with that.
Attachments
-
3.3 KB Views: 5