C#/ WPF / Math相对于相机定位3D模型

时间:2016-03-24 23:00:17

标签: c# wpf math 3d 3d-modelling

我正在使用WPF Viewport3d。观点来自飞机(称为AC1),它不断改变位置和方向。在这个视口中,我需要绘制另一架也改变位置和方向的飞机(称为Model2)。我得到以下作为输入:

  1. AC1的Lat / Lon / Alt,Heading / Pitch / Roll
  2. Model2的Lat / Lon / Alt,航向/俯仰/滚转,以及相对于AC1的方位角/高程/范围
  3. 如果我没有旋转/重新定位我的Perspective相机,那么定位Model2并不困难。相机朝向(0,0,-1)方向,向上(0,1,0)。通过该设置,我可以获得

    double X = range * Math.Cos(ConvertDegreesToRadians(elevation)) * Math.Sin(ConvertDegreesToRadians(mSATAzimDeg));
    double Y = range * Math.Sin(ConvertDegreesToRadians(elevation));
    double Z = range * Math.Cos(ConvertDegreesToRadians(elevation)) * Math.Cos(ConvertDegreesToRadians(azimuth));
    

    然后我可以使用X / Y / Z制作TranslateTransform3D并将模型移动到该位置。

    我遇到重大问题的地方是定位模型。我尝试将Lat / Lon / Alts转换为ECEF空间,然后计算该空间中的方向,但这会弄乱位置和方向。我也试过旋转视点的轴,然后围绕这些新轴旋转Model2,但这也不起作用。

    有没有人有一个简单的算法来适当地定位Model2?理想情况下,我们不会旋转相机,而是计算Model2应该如何相对于视点定向。如果我不想移动相机似乎很奇怪,那是因为WPF Viewport3d充当OpenGL窗口之上的叠加层,所以我只需要将Model2相对于WPF视口定位和定向并且根本不需要移动视点(但如果这更容易,我可以)。

    希望这是有道理的。如果没有,我会尽力详细说明。感谢您提供的任何帮助。

1 个答案:

答案 0 :(得分:0)

所以我最终让它工作,就像我想要的那样......在xaml中我为相机设置了这个旋转

<Transform3DGroup x:Name="CameraTransformGroup">
  <RotateTransform3D>
    <RotateTransform3D.Rotation>
      <AxisAngleRotation3D Axis="0,0,1" Angle="{Binding AC1Roll, ElementName=UserControl}" />
    </RotateTransform3D.Rotation>
  </RotateTransform3D>
  <RotateTransform3D>
    <RotateTransform3D.Rotation>
      <AxisAngleRotation3D Axis="1,0,0" Angle="{Binding AC1Pitch, ElementName=UserControl}" />
     </RotateTransform3D.Rotation>
   </RotateTransform3D>
   <RotateTransform3D>
     <RotateTransform3D.Rotation>
       <AxisAngleRotation3D Axis="0,-1,0" Angle="{Binding AC1Heading, ElementName=UserControl}" />
     </RotateTransform3D.Rotation>
   </RotateTransform3D>
 </Transform3DGroup>

对于Model2,我做了这个轮换

<Transform3DGroup>
  <RotateTransform3D>
    <RotateTransform3D.Rotation>
      <AxisAngleRotation3D Axis="0,0,-1" Angle="{Binding Roll, ElementName=UserControl, Converter={StaticResource RadToDegConverter}}" />
    </RotateTransform3D.Rotation>
  </RotateTransform3D>
  <RotateTransform3D>
    <RotateTransform3D.Rotation>
      <AxisAngleRotation3D Axis="1,0,0" Angle="{Binding Pitch, ElementName=UserControl, Converter={StaticResource RadToDegConverter}}" />
    </RotateTransform3D.Rotation>
  </RotateTransform3D>
  <RotateTransform3D>
    <RotateTransform3D.Rotation>
      <AxisAngleRotation3D Axis="0,-1,0" Angle="{Binding Heading, ElementName=UserControl, Converter={StaticResource RadToDegConverter}}" />
    </RotateTransform3D.Rotation>
  </RotateTransform3D>
  <TranslateTransform3D OffsetZ="{Binding RelativeOffsetZ, ElementName=UserControl}" 
                        OffsetX="{Binding RelativeOffsetX, ElementName=UserControl}" 
                        OffsetY="{Binding RelativeOffsetY, ElementName=UserControl}" />
</Transform3DGroup>

然后在RelativeOffsetX / Y / Z后面的代码由

计算
double wXOffset = mRng * Math.Cos(mElevation * GeoConstants.DEG2RAD) * Math.Sin(mAzimuth * GeoConstants.DEG2RAD);
double wYOffset = mRng * Math.Sin(mElevation * GeoConstants.DEG2RAD);
double wZOffset = mRng * Math.Cos(mElevation * GeoConstants.DEG2RAD) * Math.Cos(mAzimuth * GeoConstants.DEG2RAD);

Matrix3D wCameraRotation = CameraTransformGroup.Value;

Vector3D wNewXyz = Vector3D.Multiply(new Vector3D(wXOffset, wYOffset, wZOffset, wCameraRotation);
this.RelativeOffsetX = wNewXyz.X;
this.RelativeOffsetY = wNewXyz.Y;
this.RelativeOffsetZ = wNewXyz.Z;

在没有旋转相机的情况下我没有弄清楚如何做到这一点,但是通过旋转相机和模型,然后通过旋转矩阵CameraTransformGroup.Value和向量乘法运行计算点,您可以计算相对于相机朝向的方向,从而正确定位和定向Model2。