[RESOLVED] Vector graphics and Zooming math...
I'm writing a CAD drawing application and I've got most of the drawing system figured out apart from a bug in th zoom in/out code. I think is a bug in my maths or a floating point error.
I'm using the mousewheel to alter the zoom factor... Point mouse is the x,y coordinate of the mouse when the wheel was rolled. ClientSize is the size of the picture box tha i'm drawingon an that captures the mouse events.
PHP Code:
public PointF MouseToWorld( Point mouse, Size clientSize )
{
PointF fp = _viewSettings.FocalPoint;
float zf = _viewSettings.ZoomFactor;
float w = (float)(clientSize.Width);
float h = (float)(clientSize.Height);
float propX = (float)mouse.X / (w - 1f);
float propY = (float)mouse.Y / (h - 1f);
propX -= 0.5f;
propY -= 0.5f;
propX *= (w / zf);
propY *= (h / zf);
return new PointF( fp.X + propX, fp.Y + propY );
}
This returned point is supposed to be the mouse coordinate recalculated into WORLD coordinates.
THE PROBLEM:
During debugging I put the mouse in the dead-centre of the screen and zoom in a couple of times. But the drawing slides off to the right the more I zoom in. If the zoom factor is 256x then the drawing will be 256 pixels to the right of where it should be.
I get the feeling that simply subtractinf the zoom factor from the x,y coordinates of th translation would be a dirty fix and I don't want to do that without some justification.
Has anyone else done anything like this before and had similar results?
*perplexed*
Re: Vector graphics and Zooming math...
I don't know if this is anywhere near what you need. I post it just in case it can shed some light...
I have copied this from an app of mine. I have a (funcion) plot on Picture1 and the user scale is such that, always, (x1,y2) are the coordinates of the upper left corner and (x2,y1) those of the lower right corner. A rectangular area to zoom in to is selected by dragging the mouse.
VB Code:
Private Sub Picture1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
'Select a rectangular area to zoom in to
'Initial point
xini = X: yini = Y
End Sub
'
Private Sub Picture1_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
'Coordinates of the current corner opposite to the initial point
'(Probably you don't need this code, I've just realized...)
xcorner = X
ycorner = Y
End Sub
'
Private Sub Picture1_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
'
X = xcorner
Y = ycorner
test1 = (xini - x1) / (x2 - x1)
test2 = (X - x1) / (x2 - x1)
If test1 < test2 Then
x1 = xini: x2 = X
Else
x1 = X: x2 = xini
End If
test1 = (yini - y1) / (y2 - y1)
test2 = (Y - y1) / (y2 - y1)
If test1 > test2 Then
y1 = Y: y2 = yini
Else
y1 = yini: y2 = Y
End If
'Redefine the scale using the coordinates of
'the 2 opposite corners of the rectangle
'defined by dragging the mouse
Picture1.Scale (x1, y2)-(x2, y1)
'
'Refresh the plot here
'
End If
End Sub
Re: Vector graphics and Zooming math...
How are you drawing your plots? I'm starting to suspect my drawing libraries may be at fault. Is that Vb6 or VB.net code?
Re: Vector graphics and Zooming math...
This is VB6 code.
The way I draw the graph on the picturebox is quite straightforward: because it's a plot of y = f(x) for some f, all I have to do is loop over x values from x1 to x2 (step whatever), calculate the corresponding y's and plot the points, e.g. using the Line method, since in this case execution speed is definitely not an issue.
The cut this story short: you plot within a rectangle defined by x1,x2,y1,y2, and every time you select a new rectangle (dragging the mouse or typing the vertices in textboxes) you change the scale of the picturebox, re-calculate the function and plot it again (with an appropriate resolution)
Re: Vector graphics and Zooming math...
Its not a million miles away from mine.
I'm using GDI+ under mono (linux) to draw my items. The centre of the screen is moved to the mouse coords and then the zoom factor is either doubled or halved depending on the mousewheel movement.
If i keep the mouse at 0,0 then zoom in then the graphics are drawn off to one side but the mouse position is still being reported correctly, this tends to make me think that something is amiss with either mono or my transform code.
This is really quite odd.
Re: Vector graphics and Zooming math...
Quote:
Originally Posted by wossname
Its not a million miles away from mine.
That's a ridiculous 0.17 micro-light years, isn't it? :D
I don't think I understand all of your code and variables. What is f? Do '-=' and '*=' mean the same as in c language? Still it's hard to understand what may be happening, I suppose you'll end up finding out after some fooling around with the code...
Re: Vector graphics and Zooming math...
= 0.5f;
is the same as
= (float)0.5;
And yeah those operators are just like they are in C.
What my code does is, it finds how far the mouse is across the picturebox this gives us a number less than 1, then subtracts 0.5 from it and multiplies it by the zoom factor. Then you add this coordinate to the current focal point and then you move the centre of the screen to that position. Then you zoom in a bit and re-draw everything.
Its a bit like yours, the difference being that i use a single point (the mouse) and a float to define the new view, whereas you use a pair of points.
If I zoom in 256 times then the drawing is 256 pixels from where it should be. This is a showstopper until I get it fixed.
Re: Vector graphics and Zooming math...
A question: why when you are working out propX and propY do you subtract 1 from w and h before dividing?
Code:
float propX = (float)mouse.X / (w - 1f);
float propY = (float)mouse.Y / (h - 1f);
It means that your mouse.x and your width.x are not quite to the same scale - 1 pixel out in fact. After the subsequent subtraction, which has no effect on the scaling, you then multiply by the zoom factor which, unsurprisingly, would lead to a 256 pixel error on a zoom of x256.
Maybe I'm missing something?
Re: Vector graphics and Zooming math...
It has to do with the fact that mouse coords are integers and not floats. Subtracting 1 first will give you a range of 0 to 1 instead of 0 to 0.999.
Regardless, even then not subtracting the 1, the effect is still present, the graphics drawing routines seem to lose accuracy when zomed in. But the effect is noticeable even with small zoom factors of 4x or 16x.
Re: Vector graphics and Zooming math...
Re: Vector graphics and Zooming math...
FP is the "focal point" which basically means the real-world point which the screen is centred at. Its a PointF and by default its at (0.0, 0.0).
Re: Vector graphics and Zooming math...
What I meant by that is: how do you decide where fp is? An error in the calculation of fp will also give rise to the drift in your coordinates, because in the final line you are adding fp.x to propx (etc) to generate your new coordinate set. If your mouse point is at the centre of the screen but for some reason fp is not, then you will see drift.
Re: Vector graphics and Zooming math...
The re-calculated mouse coords are added to FP in order to let the zooming go towards the mouse pointer.
This is really hard to demonstrate without a live demo. Users of AutoCad will know how the zooming works, I'm trying to simulate the exact same effect.
Re: Vector graphics and Zooming math...
OK, I understand what you mean. I can't see any problems with this code insofar as returning the new fp coordinates then, particularly if the mouse is at (0,0) and fp is at (0,0) so are you sure that the bug is in here? If, for example, you set propx=0 and propy=0 before the last line, do you still get the drifting? If so, then the problem is not in this bit of code.
Re: Vector graphics and Zooming math...
Not to sound unhelpful, but you said you're using Linux for this? Is it not a known fact .NET is a tad buggy on Linux still? Perhaps theres nothing wrong at all with your calculations, but more the above fact(?) ..
chem
Re: Vector graphics and Zooming math...
I can't imagine it be so buggy that you can't do simple drawing operations, after all usercontrols show up fine.
Re: Vector graphics and Zooming math...
However, having tried a particular test binary on both windows and mono, the windows one works as expected but the mono exhibits the same behaviour as my CAD app.
How annoying.
Re: [RESOLVED] Vector graphics and Zooming math...
!
FIXED
!
Code:
m.Translate(-zf, -zf / 2);
Calling this just before any other transformations seems to cure the mono bug.
I used Mono 1.1.17.1 to build.
Re: [RESOLVED] Vector graphics and Zooming math...
That might be worth linking in your sig then :p I'm sure a few other people might run into this bug :)
chem
Re: [RESOLVED] Vector graphics and Zooming math...