Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (538)
Games in Android Showcase (132)
games submitted by our members
Games in WIP (601)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Pan / Zoom Algorithm  (Read 7572 times)
0 Members and 1 Guest are viewing this topic.
Offline Marksman Ken

Senior Newbie





« Posted 2010-05-23 12:01:58 »

Hi,

Im creating something that requires I pan and zoom some graphical data.
So below is the code I have come up with which almost works but Im really struggling to get my head around this whole thing.

So the idea of these methods is that I pop in some absolute coordinates and it gives me the position in which to draw the coordinate in the display (a JPanel).
Im sure you can guess what xScale and yScale are for and xOrigin and yOrigin are used to offset the drawing in relation to panning.

1  
2  
3  
4  
5  
6  
7  
8  
9  
public double getRelativeX(double x){
        double relativeX = (x* xScale) + xOrigin +(getWidth()/2);
        return relativeX;
}

public double getRelativeY(double y){
        double relativeY = (y * -yScale) - yOrigin+(getHeight()/2);
        return relativeY;
}



At the moment it does the job but when I zoom it zooms about the absolute point 0,0 when I want it to do it about the centre of the screen, any ideas how I need to change it?

Also this is my zooming/panning code:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
public void mousePressed(MouseEvent e) {
                if(SwingUtilities.isMiddleMouseButton(e)){
                    // capture starting point
                    lastOffsetX = e.getX();
                    lastOffsetY = e.getY();
                }
            }

            public void mouseDragged(MouseEvent e) {
                if(SwingUtilities.isMiddleMouseButton(e)){
                    // new x and y are defined by current mouse location subtracted
                    // by previously processed mouse location
                    int newX = e.getX() - lastOffsetX;
                    int newY = e.getY() - lastOffsetY;

                    // increment last offset to last processed by drag event.
                    lastOffsetX += newX;
                    lastOffsetY += newY;

                    // update the canvas locations
                    xOrigin += newX;
                    yOrigin -= newY;

                    // schedule a repaint.
                    repaint();
                }
            }


Quote
public void mouseWheelMoved(MouseWheelEvent e) {
                if(e.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL) {

                        xScale -= (mouseSensitivity * e.getWheelRotation());
                        yScale -= (mouseSensitivity * e.getWheelRotation());

                        xScale = Math.max(0.001, xScale);
                        yScale = Math.max(0.001, yScale);
                        repaint();
                }
            }

One last important note, you may notice the X and Y methods are slightly different, thats because I want the coordinate system to start from the bottom left and not the top left corner and increase as you move upwards not downwards.

Thanks for any help,

Ken.
Offline Karmington

Senior Devvie


Medals: 1
Projects: 1


Co-op Freak


« Reply #1 - Posted 2010-05-23 13:41:05 »

your position on the image has to be relative to the scaling as well?

1) you have image/graph whatever, you can move it around the screen
2) you want to zoom into center of screen

get position of screen center in image coords
scale
adjust the offset accordingly, with scale included

Offline Marksman Ken

Senior Newbie





« Reply #2 - Posted 2010-05-23 13:46:06 »

What do you mean?

Yes well If Im panning and then scroll with the mouse wheel I want the graphics to get larger from a base point of the middle of the screen, otherwise if its based on 0,0 then everything goes flying off the screen and I have to pan to find it again.....
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Karmington

Senior Devvie


Medals: 1
Projects: 1


Co-op Freak


« Reply #3 - Posted 2010-05-23 13:49:09 »

use percentages instead of pixels maybe.
ex:

Starting position
Center of screen is at Image position X 50%, Y 50%, scale is 100%

Moved and Scaled position
Center of screen is at Image position X 30%, Y 70%, scale is 150%

And use those to calc the draw offsets from the original width and height

this system will have to take into account if the image is completely off screen center

Offline Marksman Ken

Senior Newbie





« Reply #4 - Posted 2010-05-23 13:52:10 »

Hmm Im not quite sure what you mean. Im not drawing one pannable/scalable image although maybe I should be drawing to an image first.
Im drawing individual lines and points.
Offline Karmington

Senior Devvie


Medals: 1
Projects: 1


Co-op Freak


« Reply #5 - Posted 2010-05-23 14:01:21 »

You dont necessarily have to draw it to an image, but that could be a solution to make it clearer - but if you want to manipulate points in realtime definitely not.

I'm unclear as to whether you need to move only left and right on the track?

step back and separate clearly the system:

1) the original x and y coords are the raw data
2) the relative x and y coords are scaled coords
3) the final plotpoints are offset according to left/right scrolling?
If so,
Keep track of where you are on the scrolling as a % of the whole possibile scroll area, and the pixels it's taken to get there

eg you have a 100 pixel wide graph, it fits on the screen.
center pos is 50%
zoom 100x its 10000 pixels wide
selected position is 5000
and finally fit that to screen center depending on screenwidth

Offline Karmington

Senior Devvie


Medals: 1
Projects: 1


Co-op Freak


« Reply #6 - Posted 2010-05-23 14:14:00 »

I'm having a bad day explaining clearly, i try once more in c++ :p

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
pointAmount = dataSize - valuesStartIndex;
   //printf("point amount %d\n",pointAmount);
   m_plotpoints = new float* [pointAmount];
   for(unsigned int i=0;i<pointAmount;i++)
      *(m_plotpoints+i)=new float[2];

   //get positions of samples in graph, in screen coords
   float valuerange = (float)(valueMax - valueMin);

   // if only one value, center the point
   float ratioX = (float)(width / 2);
   float ratioY = (float)(height / 2);

   if(pointAmount > 1){
      ratioY = (float)(height / valuerange);
      ratioX = (float)(width / (pointAmount-1));
   }

   for (unsigned int i=0; i<pointAmount; i++){
      // place the plot points x,y in screen space
      //printf("setting point at %f,%f\n",(i * ratioX),((m_data[i+valuesStartIndex]-valueMin) * ratioY));

      m_plotpoints[i][0]  = i * ratioX;
      m_plotpoints[i][1]  = (m_data[i+valuesStartIndex]-valueMin) * ratioY;
   }


this one has no panning but the idea is to first plot the coordinates into
a new copy according to scale, then work with those

Offline Marksman Ken

Senior Newbie





« Reply #7 - Posted 2010-05-23 14:16:46 »

What you say makes sense but Im just trying to think how to implement it.

Here is an example of what I mean:
I have a point at 1000,1000, of course this would be off screen if the screen is 500,500 lets say.
So as we pan towards the point the x & y origin value will increase (or decrease depending on hows it done) and for example f we pan 500 pixels to the right then the equation for relative x is:
x = 1000 + (- 500) = 500
so the point would be drawn at 500,1000.

Of course then you have the scale so currently I am doing this:
(1000 * 1) + (-500) + (500/2) = 750

I add half screen width because I want it based on the centre of the screen and not the bottom conrer.

You can test it in excel but right now my brain is fried as I've been trying to work this out for ages...
Offline Karmington

Senior Devvie


Medals: 1
Projects: 1


Co-op Freak


« Reply #8 - Posted 2010-05-23 14:23:42 »

(1000 * 1) + (-500) + (500/2) = 750

where the multiplication is scaling,
scale 1, use the multiplier for the offset also:
(1000 * 1) + ( -500 * 1 ) + (500/2) = 750

scale 1.5
(1000 * 1.5) + ( -500 * 1.5 ) + (500/2) = 1000

scale .5
(1000 * .5) + ( -500 * .5 ) + (500/2) = 500

maybe on the right track?

Offline Marksman Ken

Senior Newbie





« Reply #9 - Posted 2010-05-23 14:34:36 »

Omg man I think you have it! How the heck have I missed that....

I was considering if I could do it about the mouse X & Y also but I dont think it would be as easy as the centre of the screen.

Thanks for the help Karmington its been a big help!
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Red27

Junior Devvie


Medals: 2
Projects: 2



« Reply #10 - Posted 2010-09-27 21:30:36 »

This may be a slightly out of date thread, but I created a Ken Burns style Pan & Zoom algorithm for the animated menu system used in Awesome Soccer.

Idoes a couple of clever things to determine image resize performance levels achieved and adjusts the "quality" of the resize accordingly.

The code requires some other utility libraries of mine (otherwise I would have posted the code here), but if someone genuinely needs it, PM me and I can look to extract it...  Smiley

Cheers,

Pete.

Awesome Soccer World 2010 | Red27 Studios | Blog

[IMG]http://www.red27studios.com/images/footer4.png
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

rwatson462 (29 views)
2014-12-15 09:26:44

Mr.CodeIt (20 views)
2014-12-14 19:50:38

BurntPizza (42 views)
2014-12-09 22:41:13

BurntPizza (76 views)
2014-12-08 04:46:31

JscottyBieshaar (37 views)
2014-12-05 12:39:02

SHC (50 views)
2014-12-03 16:27:13

CopyableCougar4 (47 views)
2014-11-29 21:32:03

toopeicgaming1999 (114 views)
2014-11-26 15:22:04

toopeicgaming1999 (102 views)
2014-11-26 15:20:36

toopeicgaming1999 (30 views)
2014-11-26 15:20:08
Resources for WIP games
by kpars
2014-12-18 10:26:14

Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!