1

One of my projects contains a working custom coordinate system, which different objects are placed on. The coordinate system class stores the scale and the offset, which in turn affects the scale and location of all the objects in the coordinate system. While it works correctly, I am stumped on using the mouse to interact with the coordinate system. Specifically, dragging the mouse should pan the coordinate system, so that the coordinate system moves at the same rate as the mouse, which means that the amount the mouse changes the offset is multiplied by a factor relating to the zoom. What formula/algorithm would accomplish this?

I have provided two functions in my program: c(), which converts an object's coordinates into the canvas coordinate system coordinates (which takes into account scale and offset), and cRev(), which does the reverse. These appear to be in order:

    def c(self,pos): # canvas to screen coords.
    x = pos[0]+self.xOffset # change offsets
    y = pos[1]+self.yOffset

    x = (x - CENTER_X) * self.scale + CENTER_X # change scales
    y = (y - CENTER_Y) * self.scale + CENTER_Y

    return [int(x),int(y)]

def cRev(self,pos): # screen coords to canvas
    x = pos[0]
    y = pos[1]

    x = (x-CENTER_X) / float(self.scale) + CENTER_X
    y = (y-CENTER_Y) / float(self.scale) + CENTER_Y

    x -= self.xOffset
    y -= self.yOffset

    return [int(x),int(y)]

I have a version of the mouse algorithm that does not work as intended - the mouse does move at the same rate as the coordinate system; however, it "jumps" every time the mouse just starts to be dragged.

A shortened version is provided below: (Keep in mind that all the variables are global)

for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN:
    orig_x, orig_y = event.pos
    origXOffset = d.xOffset
    origYOffset = d.yOffset
    mouseDown = True

elif event.type == pygame.MOUSEMOTION:
    x = event.pos[0]
    y = event.pos[1]
    if mouseDown: # dragging
        xa,ya = d.cRev(event.pos)
        mousex,mousey = origXOffset + xa - orig_x,origYOffset + ya - orig_y
        d.xOffset += mousex
        d.yOffset += mousey
elif event.type == pygame.MOUSEBUTTONUP:
    mouseDown = False
Ansel Chang
  • 183
  • 1
  • 1
  • 9
  • 1
    see [Zooming graphics based on current mouse position](https://stackoverflow.com/a/37269366/2521214) for some ideas. You should convert the mouse difference into same coordinate system as you are using for the panning of the view and just add/sub it to/from the pan offset. You got two offsets: `CENTER, self.?Offsey` so its a bit confusing which is which I am used to single offset zoom/pan equations for 2D – Spektre Oct 06 '18 at 06:10
  • @Spektre Thanks for the help! I've read the post you linked. Just to clarify, (CENTER_X,CENTER_Y) is defined for the coordinates of the center of the screen, and were used in the program to zoom from the center. Are you suggesting to find the x and y difference of cRev(old mouse pos) and cRev(new mouse pos), and use those values to increment d.xOffset and d.yOffset? – Ansel Chang Oct 07 '18 at 00:33
  • yes that would do it. btw I do not use CENTER as its value is a part of my offset instead. which makes the transformation easier but zooming is a bit more complicated as you can see (but not much) – Spektre Oct 07 '18 at 07:56
  • 1
    Thanks! Just fixed the bug, works well now. – Ansel Chang Oct 09 '18 at 19:21
  • 1
    well then you can write an answer with your solution to help others facing the same problem... – Spektre Oct 09 '18 at 20:50

0 Answers0