我创建了一个NASA Worldwind的输入处理程序,并尝试复制Google Earth的缩放效果。我想让缩放朝着鼠标光标缩放,而不是屏幕中心(默认情况下)。我已经有了一些成果--但它没有一致地向鼠标光标下的纬度/经度缩放,似乎漂移太远。我希望在缩放过程中同样的纬度/经度在鼠标光标下保持不变。因此,例如,如果您将光标悬停在特定地标(如水域)上,则在滚动滚轮时它将保持在光标下方。我使用的代码基于这个: https://forum.worldwindcentral.com/forum/world-wind-java-forums/development-help/11977-zoom-at-mouse-cursor?p=104793#post104793 这是我的输入处理程序:
import java.awt.event.MouseWheelEvent;
import gov.nasa.worldwind.awt.AbstractViewInputHandler;
import gov.nasa.worldwind.awt.ViewInputAttributes;
import gov.nasa.worldwind.geom.Position;
import gov.nasa.worldwind.geom.Vec4;
import gov.nasa.worldwind.view.orbit.BasicOrbitView;
import gov.nasa.worldwind.view.orbit.OrbitViewInputHandler;
public class ZoomToCursorViewInputHandler extends OrbitViewInputHandler {
protected class ZoomActionHandler extends VertTransMouseWheelActionListener {
@Override
public boolean inputActionPerformed(AbstractViewInputHandler inputHandler, MouseWheelEvent mouseWheelEvent,
ViewInputAttributes.ActionAttributes viewAction) {
double zoomInput = mouseWheelEvent.getWheelRotation();
Position position = getView().computePositionFromScreenPoint(mousePoint.x, mousePoint.y);
// Zoom toward the cursor if we're zooming in. Move straight out when zooming
// out.
if (zoomInput < 0 && position != null)
return this.zoomToPosition(position, zoomInput, viewAction);
else
return super.inputActionPerformed(inputHandler, mouseWheelEvent, viewAction);
}
protected boolean zoomToPosition(Position position, double zoomInput,
ViewInputAttributes.ActionAttributes viewAction) {
double zoomChange = zoomInput * getScaleValueZoom(viewAction);
BasicOrbitView view = (BasicOrbitView) getView();
System.out.println("================================");
System.out.println("Center Position: \t\t"+view.getCenterPosition());
System.out.println("Mouse is on Position: \t\t"+position);
Vec4 centerVector = view.getCenterPoint();
Vec4 cursorVector = view.getGlobe().computePointFromLocation(position);
Vec4 delta = cursorVector.subtract3(centerVector);
delta = delta.multiply3(-zoomChange);
centerVector = centerVector.add3(delta);
Position newPosition = view.getGlobe().computePositionFromPoint(centerVector);
System.out.println("New Center Position is: \t"+newPosition);
setCenterPosition(view, uiAnimControl, newPosition, viewAction);
onVerticalTranslate(zoomChange, viewAction);
return true;
}
}
public ZoomToCursorViewInputHandler() {
ViewInputAttributes.ActionAttributes actionAttrs = this.getAttributes()
.getActionMap(ViewInputAttributes.DEVICE_MOUSE_WHEEL)
.getActionAttributes(ViewInputAttributes.VIEW_VERTICAL_TRANSLATE);
actionAttrs.setMouseActionListener(new ZoomActionHandler());
}
}
要启用,请在worldwind.xml中设置此属性,指向该类:
<Property name="gov.nasa.worldwind.avkey.ViewInputHandlerClassName"
value="gov.nasa.worldwindx.examples.ZoomToCursorViewInputHandler"/>
delta = cursorVector - centerVector
,当计算新的delta时,应该找到新的centerVector是centerVector = cursorVector - delta
吗?这将保持cursorVector不变。如果我理解正确,使centerVector = centerVector + delta
会将中心移向光标位置,并根据delta的大小超调或欠调。 - Michael McKay