1

I'm building a map viewer and implemented rotating, panning and zooming with mouse just fine. The problem is when I try to pan after rotating the camera. If the user makes a vertical movement with mouse after the camera is rotated 30º, the camera will translade in that direction and not vertically.

This seems like it should have a simple solution, but I can't find anything. I can only think of recalculating the deltaX and deltaY according to the rotation angle, but this requires a lot of conditions depending on the quadrant I'll be on.

I did see this post with a very similar question, but I can't understand the answear.

Here's my code for panning:

public void pan (float startX, float startY, int screenX, int screenY) {
    float deltaX = (- screenX + startX) * this.zoom;
    float deltaY = (- startY + screenY) * this.zoom;
    this.translate(deltaX, deltaY);

    //Pan limits
    this.position.x = MathUtils.clamp(this.position.x, (float) (map.getMinX()-200),(float) (map.getMaxX()+200));
    this.position.y = MathUtils.clamp(this.position.y, (float) (map.getMinY()-200),(float) (map.getMaxY()+200));
}   

Is there something I'm missing? Thanks!


FOUND A SOLUTION:

I'll share my solution in case someone else comes looking for it. My math is not in great shape and I think this could be a lot more elegant. If someone comes up with a simpler aproach please let me know.

Basically, I take my deltaX and deltaY and recalculate them acoording to the new rotated axis.

When i apply my rotation, I calculate the angle of rotation from 0º to 360º, so it would be easier to understand and store it:

public void rotateScroll(int amount) {
    int direction = (amount > 0) ? 1 : -1; 
    this.rotate(direction *2.5f);

    float newAngle = (float) Math.atan2(this.up.x, this.up.y)*MathUtils.radiansToDegrees;

    newAngle = (newAngle <= 0 && newAngle < -180) ? -newAngle : 360 - newAngle;
    this.rotationAngle = (newAngle / 360 >= 1) ? newAngle - 360 * ((float) Math.floor(newAngle / 360)) : newAngle;

    this.update();
}

Then, I calculate the angle of the mouse pan direction with the rotated y axis (alpha), turn it into a oº to 360º format and calculate the new deltaX and deltaY:

public void pan (float startX, float startY, int screenX, int screenY) {
    float deltaX = (- screenX + startX) * this.zoom;
    float deltaY = (- startY + screenY) * this.zoom;

    float alpha = (float) Math.atan2(deltaX, deltaY)*MathUtils.radiansToDegrees;

    alpha = 180 + ((alpha / 360 >= 1) ? alpha - 360 * ((float) Math.floor(alpha / 360)) : alpha);

    float newAlpha = (this.rotationAngle <= alpha) ? alpha - this.rotationAngle : alpha - 360 - this.rotationAngle; 

    float length = (float) Math.sqrt(deltaX * deltaX + deltaY * deltaY);

    float nDX = length * (float) Math.sin(Math.toRadians(newAlpha));
    float nDY = length * (float) Math.cos(Math.toRadians(newAlpha));

    this.translate(-nDX, -nDY);

    //Pan limits
    this.position.x = MathUtils.clamp(this.position.x, (float) (map.getMinX()-200),(float) (map.getMaxX()+200));
    this.position.y = MathUtils.clamp(this.position.y, (float) (map.getMinY()-200),(float) (map.getMaxY()+200));

    this.update();

}

It works, but most of this code is just converting angle formats and I'm sure it could've been done in a simpler way. If anyone finds a way to simplify it, I'd apreciate if you'd let me know!

Community
  • 1
  • 1
Joins
  • 11
  • 2
  • When you rotate the camera you're doing just that, rotating the camera, NOT what is inside the camera. So if you rotate what is inside the camera (the map) you can move the camera around and view the rotated map. Another option would possibly be looking at the camera showing the map through a second camera. – John Cipponeri Dec 23 '14 at 04:29
  • Since I'm having enough problems as it is with coordinates, your second suggestion seems like an easier implementation. Isn't having multiple cameras expensive? – Joins Dec 23 '14 at 09:07

0 Answers0