在 C# 中朝它所面对的方向移动 PerspectiveCamera
Moving PerspectiveCamera in the direction it is facing in C#
我目前正在使用具有 Viewport3D
摄像头的 wpf 应用程序。
我正在创建一个 3D 演练模块。
我希望我的 PerspectiveCamera
在 Look Directions 改变后根据它所面对的方向移动。
我正在使用我的键盘来控制移动,例如:
NUMPAD8
:前进
NUMPAD2
: 向后移动
NUMPAD4
:向左旋转
NUMPAD6
:向右旋转
下面这个方法是检测键盘事件:
private void button20_KeyDown(Object sender, KeyEventArgs e)
{
if (e.Key == Key.NumPad6)
{
Rotate(1);
}
else if (e.Key == Key.NumPad4)
{
Rotate(-1);
}
else if (e.Key == Key.NumPad8)
{
Move(-10);
}
else if (e.Key == Key.NumPad2)
{
Move(10);
}
}
这是计算旋转:
public void Rotate(double d)
{
double u = 0.05;
double angleD = u * d;
PerspectiveCamera camera = (PerspectiveCamera)Viewport3D.Camera;
Vector3D lookDirection = camera.LookDirection;
double L = lookDirection.Length;
double D = 2 * L * Math.Sin(angleD / 2);
double m = Math.Sqrt(lookDirection.X * lookDirection.X + lookDirection.Y * lookDirection.Y);
double angleA = 2 * Math.Asin(D / (2 * m));
double x = lookDirection.X;
double y = lookDirection.Y;
double angleB = Math.Atan2(y, x);
double angleG = angleB - angleA;
double newx = m * Math.Cos(angleG);
double newy = m * Math.Sin(angleG);
Vector3D NewlookDirection = new Vector3D(newx, newy, lookDirection.Z);
camera.LookDirection = NewlookDirection;
}
这是计算相机移动:
public void Move(double d)
{
double u = 0.05;
PerspectiveCamera camera = (PerspectiveCamera)Viewport3D.Camera;
Vector3D lookDirection = camera.LookDirection;
Point3D position = camera.Position;
//Point3D NewPosition = new Point3D();
position.Y += d;
//NewPosition.X = position.X + u * lookDirection.X * d;
//NewPosition.Y = position.Y + u * lookDirection.Y * d;
//NewPosition.Z = position.Z + u * lookDirection.Z * d;
//camera.Position = NewPosition;
camera.Position = position;
}
旋转计算完美,但移动似乎效果不佳,因为它根据相机位置而不是旋转后的朝向移动相机。
注释掉的代码看起来或多或少是正确的...你没有说它有什么问题。您是否尝试过标准化 lookDirection 向量?对向量进行归一化使其大小(长度)为 1。
public void Move(double d)
{
double u = 0.05;
PerspectiveCamera camera = (PerspectiveCamera)Viewport3D.Camera;
Vector3D lookDirection = camera.LookDirection;
Point3D position = camera.Position;
lookDirection.Normalize();
position = position + u * lookDirection * d;
camera.Position = position;
}
更新:
private void Window_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.NumPad6)
{
Rotate(10);
}
else if (e.Key == Key.NumPad4)
{
Rotate(-10);
}
else if (e.Key == Key.NumPad8)
{
Move(-10);
}
else if (e.Key == Key.NumPad2)
{
Move(10);
}
else if (e.Key == Key.PageUp)
{
RotateVertical(10);
}
else if (e.Key == Key.PageDown)
{
RotateVertical(-10);
}
}
public void Rotate(double d)
{
double u = 0.05;
double angleD = u * d;
PerspectiveCamera camera = (PerspectiveCamera)Viewport3D.Camera;
Vector3D lookDirection = camera.LookDirection;
var m = new Matrix3D();
m.Rotate(new Quaternion(camera.UpDirection, -angleD)); // Rotate about the camera's up direction to look left/right
camera.LookDirection = m.Transform(camera.LookDirection);
}
public void RotateVertical(double d)
{
double u = 0.05;
double angleD = u * d;
PerspectiveCamera camera = (PerspectiveCamera)Viewport3D.Camera;
Vector3D lookDirection = camera.LookDirection;
// Cross Product gets a vector that is perpendicular to the passed in vectors (order does matter, reverse the order and the vector will point in the reverse direction)
var cp = Vector3D.CrossProduct(camera.UpDirection, lookDirection);
cp.Normalize();
var m = new Matrix3D();
m.Rotate(new Quaternion(cp, -angleD)); // Rotate about the vector from the cross product
camera.LookDirection = m.Transform(camera.LookDirection);
}
我目前正在使用具有 Viewport3D
摄像头的 wpf 应用程序。
我正在创建一个 3D 演练模块。
我希望我的 PerspectiveCamera
在 Look Directions 改变后根据它所面对的方向移动。
我正在使用我的键盘来控制移动,例如:
NUMPAD8
:前进
NUMPAD2
: 向后移动
NUMPAD4
:向左旋转
NUMPAD6
:向右旋转
下面这个方法是检测键盘事件:
private void button20_KeyDown(Object sender, KeyEventArgs e)
{
if (e.Key == Key.NumPad6)
{
Rotate(1);
}
else if (e.Key == Key.NumPad4)
{
Rotate(-1);
}
else if (e.Key == Key.NumPad8)
{
Move(-10);
}
else if (e.Key == Key.NumPad2)
{
Move(10);
}
}
这是计算旋转:
public void Rotate(double d)
{
double u = 0.05;
double angleD = u * d;
PerspectiveCamera camera = (PerspectiveCamera)Viewport3D.Camera;
Vector3D lookDirection = camera.LookDirection;
double L = lookDirection.Length;
double D = 2 * L * Math.Sin(angleD / 2);
double m = Math.Sqrt(lookDirection.X * lookDirection.X + lookDirection.Y * lookDirection.Y);
double angleA = 2 * Math.Asin(D / (2 * m));
double x = lookDirection.X;
double y = lookDirection.Y;
double angleB = Math.Atan2(y, x);
double angleG = angleB - angleA;
double newx = m * Math.Cos(angleG);
double newy = m * Math.Sin(angleG);
Vector3D NewlookDirection = new Vector3D(newx, newy, lookDirection.Z);
camera.LookDirection = NewlookDirection;
}
这是计算相机移动:
public void Move(double d)
{
double u = 0.05;
PerspectiveCamera camera = (PerspectiveCamera)Viewport3D.Camera;
Vector3D lookDirection = camera.LookDirection;
Point3D position = camera.Position;
//Point3D NewPosition = new Point3D();
position.Y += d;
//NewPosition.X = position.X + u * lookDirection.X * d;
//NewPosition.Y = position.Y + u * lookDirection.Y * d;
//NewPosition.Z = position.Z + u * lookDirection.Z * d;
//camera.Position = NewPosition;
camera.Position = position;
}
旋转计算完美,但移动似乎效果不佳,因为它根据相机位置而不是旋转后的朝向移动相机。
注释掉的代码看起来或多或少是正确的...你没有说它有什么问题。您是否尝试过标准化 lookDirection 向量?对向量进行归一化使其大小(长度)为 1。
public void Move(double d)
{
double u = 0.05;
PerspectiveCamera camera = (PerspectiveCamera)Viewport3D.Camera;
Vector3D lookDirection = camera.LookDirection;
Point3D position = camera.Position;
lookDirection.Normalize();
position = position + u * lookDirection * d;
camera.Position = position;
}
更新:
private void Window_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.NumPad6)
{
Rotate(10);
}
else if (e.Key == Key.NumPad4)
{
Rotate(-10);
}
else if (e.Key == Key.NumPad8)
{
Move(-10);
}
else if (e.Key == Key.NumPad2)
{
Move(10);
}
else if (e.Key == Key.PageUp)
{
RotateVertical(10);
}
else if (e.Key == Key.PageDown)
{
RotateVertical(-10);
}
}
public void Rotate(double d)
{
double u = 0.05;
double angleD = u * d;
PerspectiveCamera camera = (PerspectiveCamera)Viewport3D.Camera;
Vector3D lookDirection = camera.LookDirection;
var m = new Matrix3D();
m.Rotate(new Quaternion(camera.UpDirection, -angleD)); // Rotate about the camera's up direction to look left/right
camera.LookDirection = m.Transform(camera.LookDirection);
}
public void RotateVertical(double d)
{
double u = 0.05;
double angleD = u * d;
PerspectiveCamera camera = (PerspectiveCamera)Viewport3D.Camera;
Vector3D lookDirection = camera.LookDirection;
// Cross Product gets a vector that is perpendicular to the passed in vectors (order does matter, reverse the order and the vector will point in the reverse direction)
var cp = Vector3D.CrossProduct(camera.UpDirection, lookDirection);
cp.Normalize();
var m = new Matrix3D();
m.Rotate(new Quaternion(cp, -angleD)); // Rotate about the vector from the cross product
camera.LookDirection = m.Transform(camera.LookDirection);
}