繁体   English   中英

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

[英]C#/WPF/Math Orienting a 3D model relative to the camera

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

  1. AC1 的 Lat/Lon/Alt, Heading/Pitch/Roll
  2. Model2 的 Lat/Lon/Alt、航向/俯仰/横滚,以及相对于 AC1 的方位角/仰角/范围

只要我不旋转/重新定位我的透视相机,定位 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 视口进行定位和定向,然后不要根本不需要移动视点(但如果更容易的话,我可以)。

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

所以我最终让它工作,只是不像我想要的那样......在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。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM