Zooming Topic is solved

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
FireMail
Earned some good credits
Earned some good credits
Posts: 122
Joined: Fri Jun 10, 2005 8:34 am
Location: Austria
Contact:

Zooming

Post by FireMail » Thu Sep 25, 2008 3:59 pm

hi there,

i'm currently working on a nice application that displays vectorized graphics. i want to zoom in and also, when the image is bigger than it can be displayed, i want to "scroll" around by drag and drop on the screen.

here the code how the image gets drawn:

Code: Select all

void MyFrame::OnPaint( wxPaintEvent &event )
{
	wxAutoBufferedPaintDC pdc( this );

	pdc.Clear();

		// draw the grid if needed
		DrawGrid( &pdc );

		// now print all objects and points to the gui
		SerializeToGUI( &pdc );

		pdc.SetUserScale( m_fZoomFactor, m_fZoomFactor );
		pdc.SetDeviceOrigin( m_pZoomPoint.x, m_pZoomPoint.y );
	event.Skip();
}
m_fZoomFactor is a floating point number that gets increased or decreased by the user to zoom in or out.
m_pZoomPoint is a wxPoint that gets changed when a drag'n'drop event occurs to move the zoomed image around.

Everything works fine except of two things:

1) When i move the "image" around and a position smaller than wxPoint(0,0) is rendered, the last colours on the 0 coordinates get copied (see attached picture). i cant stop this, not with pdc.Clear() and not with pdc.DrawRectangle(0,0,-2000,-2000)
2) i zoom in, move a little bit around and i'm now clicking on the screen (normal mouse event processing). i would need the coordinate of the position i clicked onto. with event.GetPosition() i do get a wxPoint, but that position is not in relation to the zooming factor or the device origin. so how can this position (its only the position i clicked on that wxPanel) be processed that it shows me the position without zooming or device origin?

hope you have answers,
regards j
Attachments
Unbenannt-1.jpg
Unbenannt-1.jpg (30.64 KiB) Viewed 1606 times
-----BEGIN GEEK CODE BLOCK-----
Version: 3.1
GB/CS/CM/IT !d++ s+:-- a-- C++++$ UBL*++++$ P--- L++++$ !E-- !W+++$? !N-- !o K--? w++()$ !O M$ !V !PS? !PE? !Y? !PGP !t !5 !X R+++ tv++ !b? DI D++ G e+++ h++ r++ y+
------END GEEK CODE BLOCK------

jmason1182
Earned some good credits
Earned some good credits
Posts: 149
Joined: Fri Dec 14, 2007 3:40 pm
Location: Midland, TX
Contact:

Re: Zooming

Post by jmason1182 » Fri Sep 26, 2008 4:37 pm

FireMail wrote: 1) When i move the "image" around and a position smaller than wxPoint(0,0) is rendered, the last colours on the 0 coordinates get copied (see attached picture). i cant stop this, not with pdc.Clear() and not with pdc.DrawRectangle(0,0,-2000,-2000)
2) i zoom in, move a little bit around and i'm now clicking on the screen (normal mouse event processing). i would need the coordinate of the position i clicked onto. with event.GetPosition() i do get a wxPoint, but that position is not in relation to the zooming factor or the device origin. so how can this position (its only the position i clicked on that wxPanel) be processed that it shows me the position without zooming or device origin?
FIrst off, you are going to have to have a BufferedDC that is larger than your image. That way you can have direct control of all the pixels that can be zoomed into. Really, you need to restrict movement so that the origin doesn't go negative. Then your problem #1 will be solved. Using the former method, you center your image in the BufferedDC with that infamous checkered pattern everywhere else. Then zooming in will always be on the "canvas" and then afterwards you can just pull off the BufferedDC the contents of your image. The Gimp does the latter method... you can't scroll away from the "image size"... so the x,y coorinates is always greater than 0. You get to pick.


Second of all, your coordinates are based on your zoom factor. It is the same for printing coordinates. If you get a DC and "scale" it to a PrinterDC, then you have to "scale" all your entities.

Check out this post: http://forums.wxwidgets.org/viewtopic.p ... highlight=
While it focuses on the printing scaling, it will give you an idea of how to scale ANY DC. The concept is the same.

With that in mind, all your "points" when zoomed in will change by a factor of the scale. AND when you pull data in, or put data on you'll have to scale up or scale down respectively ALL coordinate info, size measurements, etc.

Welcome to a Geometrical issue.
John A. Mason
Midland, TX

FireMail
Earned some good credits
Earned some good credits
Posts: 122
Joined: Fri Jun 10, 2005 8:34 am
Location: Austria
Contact:

Post by FireMail » Fri Sep 26, 2008 5:06 pm

great ideas - thanks. i will try them tomorrow and post my results
-----BEGIN GEEK CODE BLOCK-----
Version: 3.1
GB/CS/CM/IT !d++ s+:-- a-- C++++$ UBL*++++$ P--- L++++$ !E-- !W+++$? !N-- !o K--? w++()$ !O M$ !V !PS? !PE? !Y? !PGP !t !5 !X R+++ tv++ !b? DI D++ G e+++ h++ r++ y+
------END GEEK CODE BLOCK------

FireMail
Earned some good credits
Earned some good credits
Posts: 122
Joined: Fri Jun 10, 2005 8:34 am
Location: Austria
Contact:

Post by FireMail » Tue Sep 30, 2008 6:52 am

hi,

zooming works well - was easy. but now i have a big problem with moving around inside the zoomed image (the zoomed image is bigger then the rendering area, so moving is done with drag and drop).

for moving i react on drag and drop events and increment/decrement a wxPoint. with this wxPoint i use SetDeviceOrigin(..) inside the OnPaint Event.

i need to calculate the right coordinates where it originally would have been clicked, if the image was not zoomed. and here is the problem!

when having a zoomfactor (setuserscale) of 1 (not zoomed) i need SetDeviceOrigin( wxPoint(700000,0) ) to be moved to the MaxX Point.
Having zoomfactor of 0,98 i need wxPoint(41581,0)
Having zoomfactor of 0,81 i need wxPoint(4292,0)

Max X = 823
H = 1004
W = 1212
PPI = (96/96)

maybe you see any connections that i missed?
-----BEGIN GEEK CODE BLOCK-----
Version: 3.1
GB/CS/CM/IT !d++ s+:-- a-- C++++$ UBL*++++$ P--- L++++$ !E-- !W+++$? !N-- !o K--? w++()$ !O M$ !V !PS? !PE? !Y? !PGP !t !5 !X R+++ tv++ !b? DI D++ G e+++ h++ r++ y+
------END GEEK CODE BLOCK------

FireMail
Earned some good credits
Earned some good credits
Posts: 122
Joined: Fri Jun 10, 2005 8:34 am
Location: Austria
Contact:

Post by FireMail » Tue Sep 30, 2008 7:12 am

got it
-----BEGIN GEEK CODE BLOCK-----
Version: 3.1
GB/CS/CM/IT !d++ s+:-- a-- C++++$ UBL*++++$ P--- L++++$ !E-- !W+++$? !N-- !o K--? w++()$ !O M$ !V !PS? !PE? !Y? !PGP !t !5 !X R+++ tv++ !b? DI D++ G e+++ h++ r++ y+
------END GEEK CODE BLOCK------

jmason1182
Earned some good credits
Earned some good credits
Posts: 149
Joined: Fri Dec 14, 2007 3:40 pm
Location: Midland, TX
Contact:

Post by jmason1182 » Tue Sep 30, 2008 1:02 pm

Well what did you do? What did you figure out? I'm curious as to some of your code!
John A. Mason
Midland, TX

FireMail
Earned some good credits
Earned some good credits
Posts: 122
Joined: Fri Jun 10, 2005 8:34 am
Location: Austria
Contact:

Post by FireMail » Tue Sep 30, 2008 1:40 pm

its relatively easy. the way how to zoom by using SetUserScale is known (link above), also moving inside a zoomed image (drag and drop event, SetDeviceOrigin).

To calculate backwars what position a click originally had i came to this conclusion:

Code: Select all

eventPoint = event.GetPosition();
eventPoint.x *= m_fZoomFactor;
eventPoint.y *= m_fZoomFactor;
movedPoint = eventPoint;
movedPoint.x += (1-m_fZoomFactor)*m_pZoomPoint.x;
movedPoint.y += (1-m_fZoomFactor)*m_pZoomPoint.y;
first of all we need to multiply our click position with the zoomfactor we use for SetUserScale. This calculates the coordinates right for zooming, but not when moved inside of the zoomed image.
To get this coordinate right we simply add (1-ZoomFactor)*ZoomPoint. ZoomPoint is the value we use for SetDeviceOrigin

This calculates the coordinates correctly :)
-----BEGIN GEEK CODE BLOCK-----
Version: 3.1
GB/CS/CM/IT !d++ s+:-- a-- C++++$ UBL*++++$ P--- L++++$ !E-- !W+++$? !N-- !o K--? w++()$ !O M$ !V !PS? !PE? !Y? !PGP !t !5 !X R+++ tv++ !b? DI D++ G e+++ h++ r++ y+
------END GEEK CODE BLOCK------

jmason1182
Earned some good credits
Earned some good credits
Posts: 149
Joined: Fri Dec 14, 2007 3:40 pm
Location: Midland, TX
Contact:

Post by jmason1182 » Tue Sep 30, 2008 1:48 pm

Nice work. Thanks
John A. Mason
Midland, TX

Post Reply