最近在做毕业设计,需要在导入WPF中的茶壶模型上做一些鼠标控制,Grid_MouseLeftButtonDown和Grid_MouseLeftButtonUp是用鼠标左键转换视角,Grid_MouseWheel是鼠标滚轮放大缩小,Grid_MouseRightButtonDown和Grid_MouseRightButtonUp是用鼠标右键旋转模型,但现在在运行时,左键和滚轮事件都好用,只是一点击鼠标右键的时候,就提示报错,报的错是关于Grid_MouseMove()这个函数中的倒数第二行代码:group.Children.Add(new RotateTransform3D(r))————未处理NullReferenceException(未将对象引用设置到对象的实例)不知道怎么回事,求老师们指教,后面附上事件处理代码,麻烦帮忙看一下:
注意:在WPF窗体中点击鼠标右键时提示第88行有错!
namespace teapot
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
///
public partial class MainWindow : Window
{ private bool lflag = false;
private bool rflag = false;
private Point mLastPos;
private Point3D postion = new Point3D(0, 0, 0); public MainWindow()
{
this.InitializeComponent(); // 在此点下面插入创建对象所需的代码。
} private void Grid_MouseWheel(object sender, MouseWheelEventArgs e)
{
double dx = 0;
double dy = 0;
double dz = 0;
double length = Math.Sqrt(Math.Pow(camera.LookDirection.X, 2) + Math.Pow(camera.LookDirection.Y, 2) + Math.Pow(camera.LookDirection.Z, 2));
dx = camera.LookDirection.X / length * e.Delta / 10D;
dy = camera.LookDirection.Y / length * e.Delta / 10D;
dz = camera.LookDirection.Z / length * e.Delta / 10D; camera.Position = new Point3D(camera.Position.X + dx, camera.Position.Y + dy, camera.Position.Z + dz);
} private void Grid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
lflag = true;
//得到视角在显示屏幕的坐标
Point pos = Mouse.GetPosition(viewport); mLastPos = new Point(pos.X - viewport.ActualWidth / 2, viewport.ActualHeight / 2 - pos.Y);
} private void Grid_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
lflag = false;
} private void Grid_MouseMove(object sender, MouseEventArgs e)
{
if (lflag)
{
Point pos = Mouse.GetPosition(viewport);
Point actualPos = new Point(pos.X - viewport.ActualWidth / 2, viewport.ActualHeight / 2 - pos.Y);
double dx = actualPos.X - mLastPos.X, dy = actualPos.Y - mLastPos.Y; camera.Position = new Point3D(camera.Position.X + dx, camera.Position.Y, camera.Position.Z); mLastPos = actualPos;
}
else if (rflag)
{ Point pos = Mouse.GetPosition(viewport);
Point actualPos = new Point(pos.X - viewport.ActualWidth / 2, viewport.ActualHeight / 2 - pos.Y);
double dx = actualPos.X - mLastPos.X, dy = actualPos.Y - mLastPos.Y; double mouseAngle = 0;
if (dx != 0 && dy != 0)
{
mouseAngle = Math.Asin(Math.Abs(dy) / Math.Sqrt(Math.Pow(dx, 2) + Math.Pow(dy, 2)));
if (dx < 0 && dy > 0) mouseAngle += Math.PI / 2;
else if (dx < 0 && dy < 0) mouseAngle += Math.PI;
else if (dx > 0 && dy < 0) mouseAngle += Math.PI * 1.5;
}
else if (dx == 0 && dy != 0) mouseAngle = Math.Sign(dy) > 0 ? Math.PI / 2 : Math.PI * 1.5;
else if (dx != 0 && dy == 0) mouseAngle = Math.Sign(dx) > 0 ? 0 : Math.PI; double axisAngle = mouseAngle + Math.PI / 2; Vector3D axis = new Vector3D(Math.Cos(axisAngle) * 4, Math.Sin(axisAngle) * 4, 0); double rotation = 0.01 * Math.Sqrt(Math.Pow(dx, 2) + Math.Pow(dy, 2));
Transform3DGroup group = World.Transform as Transform3DGroup;
QuaternionRotation3D r = new QuaternionRotation3D(new Quaternion(axis, rotation * 180 / Math.PI));
group.Children.Add(new RotateTransform3D(r));//这一行有错!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
mLastPos = actualPos;
}
}
private void Grid_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
rflag = true;
Point pos = Mouse.GetPosition(viewport);
mLastPos = new Point(pos.X - viewport.ActualWidth / 2, viewport.ActualHeight / 2 - pos.Y);
}
private void Grid_MouseRightButtonUp(object sender, MouseButtonEventArgs e)
{
rflag = false;
}
}
}
3DWPF鼠标
注意:在WPF窗体中点击鼠标右键时提示第88行有错!
namespace teapot
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
///
public partial class MainWindow : Window
{ private bool lflag = false;
private bool rflag = false;
private Point mLastPos;
private Point3D postion = new Point3D(0, 0, 0); public MainWindow()
{
this.InitializeComponent(); // 在此点下面插入创建对象所需的代码。
} private void Grid_MouseWheel(object sender, MouseWheelEventArgs e)
{
double dx = 0;
double dy = 0;
double dz = 0;
double length = Math.Sqrt(Math.Pow(camera.LookDirection.X, 2) + Math.Pow(camera.LookDirection.Y, 2) + Math.Pow(camera.LookDirection.Z, 2));
dx = camera.LookDirection.X / length * e.Delta / 10D;
dy = camera.LookDirection.Y / length * e.Delta / 10D;
dz = camera.LookDirection.Z / length * e.Delta / 10D; camera.Position = new Point3D(camera.Position.X + dx, camera.Position.Y + dy, camera.Position.Z + dz);
} private void Grid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
lflag = true;
//得到视角在显示屏幕的坐标
Point pos = Mouse.GetPosition(viewport); mLastPos = new Point(pos.X - viewport.ActualWidth / 2, viewport.ActualHeight / 2 - pos.Y);
} private void Grid_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
lflag = false;
} private void Grid_MouseMove(object sender, MouseEventArgs e)
{
if (lflag)
{
Point pos = Mouse.GetPosition(viewport);
Point actualPos = new Point(pos.X - viewport.ActualWidth / 2, viewport.ActualHeight / 2 - pos.Y);
double dx = actualPos.X - mLastPos.X, dy = actualPos.Y - mLastPos.Y; camera.Position = new Point3D(camera.Position.X + dx, camera.Position.Y, camera.Position.Z); mLastPos = actualPos;
}
else if (rflag)
{ Point pos = Mouse.GetPosition(viewport);
Point actualPos = new Point(pos.X - viewport.ActualWidth / 2, viewport.ActualHeight / 2 - pos.Y);
double dx = actualPos.X - mLastPos.X, dy = actualPos.Y - mLastPos.Y; double mouseAngle = 0;
if (dx != 0 && dy != 0)
{
mouseAngle = Math.Asin(Math.Abs(dy) / Math.Sqrt(Math.Pow(dx, 2) + Math.Pow(dy, 2)));
if (dx < 0 && dy > 0) mouseAngle += Math.PI / 2;
else if (dx < 0 && dy < 0) mouseAngle += Math.PI;
else if (dx > 0 && dy < 0) mouseAngle += Math.PI * 1.5;
}
else if (dx == 0 && dy != 0) mouseAngle = Math.Sign(dy) > 0 ? Math.PI / 2 : Math.PI * 1.5;
else if (dx != 0 && dy == 0) mouseAngle = Math.Sign(dx) > 0 ? 0 : Math.PI; double axisAngle = mouseAngle + Math.PI / 2; Vector3D axis = new Vector3D(Math.Cos(axisAngle) * 4, Math.Sin(axisAngle) * 4, 0); double rotation = 0.01 * Math.Sqrt(Math.Pow(dx, 2) + Math.Pow(dy, 2));
Transform3DGroup group = World.Transform as Transform3DGroup;
QuaternionRotation3D r = new QuaternionRotation3D(new Quaternion(axis, rotation * 180 / Math.PI));
group.Children.Add(new RotateTransform3D(r));//这一行有错!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
mLastPos = actualPos;
}
}
private void Grid_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
rflag = true;
Point pos = Mouse.GetPosition(viewport);
mLastPos = new Point(pos.X - viewport.ActualWidth / 2, viewport.ActualHeight / 2 - pos.Y);
}
private void Grid_MouseRightButtonUp(object sender, MouseButtonEventArgs e)
{
rflag = false;
}
}
}
3DWPF鼠标
改为:
World.Transform = new Transform3DGroup();
Transform3DGroup group = World.Transform as Transform3DGroup;
或者在XAML中设置好World的Transform属性。
<xxx.Transform>
<Transform3DGroup/>
</xxx.Transform>