我正在构建地图查看器并使用鼠标实现旋转,平移和缩放。 问题是当我在旋转相机后尝试平移时。如果用户在相机旋转30º后使用鼠标进行垂直移动,则相机将朝该方向移动,而不是垂直移动。
这似乎应该有一个简单的解决方案,但我找不到任何东西。我只能想到根据旋转角度重新计算deltaX和deltaY,但这需要很多条件,具体取决于我将要使用的象限。
我确实看到this post有一个非常相似的问题,但我无法理解这个问题。
这是我的平移代码:
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));
}
有什么我想念的吗?谢谢!
找到解决方案:
我会分享我的解决方案以防其他人来寻找它。 我的数学形态并不好,我认为这可能更优雅。如果有人提出更简单的方法,请告诉我。
基本上,我接受deltaX和deltaY并根据新的旋转轴重新计算它们。
当我应用旋转时,我会计算从0º到360º的旋转角度,因此更容易理解和存储:
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();
}
然后,我用旋转的y轴(alpha)计算鼠标摇摄方向的角度,将其转换为oº到360º格式并计算新的deltaX和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();
}
它有效,但是大部分代码只是转换角度格式,我确信它可以用更简单的方式完成。如果有人找到简化它的方法,如果你让我知道的话,我会感到满意!