我创建了一个立方体。现在,我想让用户可以使用鼠标围绕其中心旋转它。我成功实现了左右旋转:
private class MouseButtonInfo
{
public MouseButtonInfo()
{
prevPosition = new Point();
isDown = false;
}
public MouseButtonInfo(Point p, bool b)
{
prevPosition = p;
isDown = b;
}
public Point prevPosition;
public bool isDown;
}
// right mouse button info
private MouseButtonInfo rmbInfo = new MouseButtonInfo();
private AxisAngleRotation3D cubeRotation = new AxisAngleRotation3D();
// rotation of the cube is bound to this
public AxisAngleRotation3D CubeRotation
{
get => cubeRotation;
set
{
if(cubeRotation == value) { return;}
cubeRotation = value;
OnPropertyChanged(nameof(CubeRotation));
}
}
private void viewport3d_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
this.rmbInfo.isDown = true;
this.rmbInfo.prevPosition = e.GetPosition(this.viewport3d);
this.Cursor = Cursors.Hand;
var el = (UIElement)sender;
if (!el.CaptureMouse())
{
throw new SystemException("Unable to capture the mouse");
}
}
private void viewport3d_MouseRightButtonUp(object sender, MouseButtonEventArgs e)
{
this.rmbInfo.isDown = false;
this.Cursor = null;
var el = (UIElement)sender;
el.ReleaseMouseCapture();
}
private void viewport3d_MouseMove(object sender, MouseEventArgs e)
{
if (this.rmbInfo.isDown)
{
double currentAngle = this.CubeRotation.Angle;
Point currentPos = e.GetPosition(this.viewport3d);
double offset = currentPos.X - this.rmbInfo.prevPosition.X;
this.CubeRotation = new AxisAngleRotation3D(new Vector3D(0, 1, 0), currentAngle + (offset*0.4)%360);
this.rmbInfo.prevPosition = currentPos;
}
}
但我无法将其与自下而上的旋转结合起来。我认为最大的问题是旋转向量。在左右情况下很简单,但是当 X 轴和 Y 轴组合在一起时,它对我来说变得难以理解。
管理旋转以及旋转组合的最佳方法是使用四元数。 我不会在这里发布代码,因为它太长了,但你应该看一下 Helix 工具包(它位于 GitHub 上)。 他们已经实现了您需要的所有功能,(我认为有一个类“RotateHandler”和“CameraControl”您会特别感兴趣)