简体   繁体   English

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

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

I am working with a WPF Viewport3d.我正在使用 WPF Viewport3d。 The viewpoint is from an aircraft (call it AC1) that is constantly changing position and orientation.视点来自一架不断改变位置和方向的飞机(称为 AC1)。 In this viewport I need to draw another aircraft (call it Model2) that also changes position and orientation.在这个视口中,我需要绘制另一架同样改变位置和方向的飞机(称为 Model2)。 I am given the following as inputs:我得到以下内容作为输入:

  1. AC1's Lat/Lon/Alt, Heading/Pitch/Roll AC1 的 Lat/Lon/Alt, Heading/Pitch/Roll
  2. Model2's Lat/Lon/Alt, Heading/Pitch/Roll, and Azimuth/Elevation/Range relative to AC1 Model2 的 Lat/Lon/Alt、航向/俯仰/横滚,以及相对于 AC1 的方位角/仰角/范围

To position Model2 is not difficult provided I don't rotate/reposition my Perspective camera.只要我不旋转/重新定位我的透视相机,定位 Model2 并不困难。 The camera looks in the direction (0,0,-1) and up is (0,1,0).相机朝 (0,0,-1) 方向看,向上是 (0,1,0)。 With that setup I can get有了这个设置,我可以得到

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));

I can then use that X/Y/Z to make a TranslateTransform3D and move the model to that position.然后我可以使用该 X/Y/Z 制作 TranslateTransform3D 并将模型移动到该位置。

Where I'm running into major problems is orienting the model.我遇到的主要问题是模型的定位。 I've tried converting the Lat/Lon/Alts to ECEF space and then calculating the orientation in that space, but that messes up the position and the orientation.我尝试将 Lat/Lon/Alts 转换为 ECEF 空间,然后计算该空间中的方向,但这会弄乱位置和方向。 I've also tried rotating the axes of the viewpoint, and then rotating Model2 around those new axes, but that isn't working either.我还尝试旋转视点的轴,然后围绕这些新轴旋转 Model2,但这也不起作用。

Does anyone have a simple algorithm to orient Model2 appropriately?有没有人有一个简单的算法来适当地定位 Model2? Ideally we wouldn't be rotating the camera, but rather calculate how Model2 should be oriented relative to the viewpoint.理想情况下,我们不会旋转相机,而是计算 Model2 相对于视点的方向。 If it seems weird that I don't want to move the camera it is because the WPF Viewport3d is acting as an overlay on top of an OpenGL window, so really I just need Model2 to be positioned and oriented relative to the WPF Viewport and don't need to move the viewpoint at all (but I can if that is easier).如果我不想移动相机看起来很奇怪,那是因为 WPF Viewport3d 充当了 OpenGL 窗口顶部的叠加层,所以实际上我只需要 Model2 相对于 WPF 视口进行定位和定向,然后不要根本不需要移动视点(但如果更容易的话,我可以)。

Hopefully that makes sense.希望这是有道理的。 If not I will try to elaborate.如果没有,我会尝试详细说明。 Thanks for any help you can provide.感谢您的任何帮助,您可以提供。

So I ended up making it work, just not quite the way I wanted to...in xaml I set up this rotation for the camera所以我最终让它工作,只是不像我想要的那样......在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>

And for Model2 I did this rotation对于 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>

Then in the code behind RelativeOffsetX/Y/Z are calculated by然后在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;

I didn't work out how to do it without rotating the camera, but by rotating the camera and the model and then running the calculated point through the rotation matrix CameraTransformGroup.Value and vector multiplication you can calculate a new offset relative to the direction the camera is facing, thus properly positioning and orienting Model2.我不知道如何在不旋转相机的情况下做到这一点,但是通过旋转相机和模型,然后通过旋转矩阵 CameraTransformGroup.Value 和向量乘法运行计算的点,您可以计算相对于方向的新偏移量相机正对,从而正确定位和定向 Model2。

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

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