-1

I am working with a WPF Viewport3d. The viewpoint is from an aircraft (call it AC1) that is constantly changing position and orientation. In this viewport I need to draw another aircraft (call it Model2) that also changes position and orientation. I am given the following as inputs:

  1. AC1's Lat/Lon/Alt, Heading/Pitch/Roll
  2. Model2's Lat/Lon/Alt, Heading/Pitch/Roll, and Azimuth/Elevation/Range relative to AC1

To position Model2 is not difficult provided I don't rotate/reposition my Perspective camera. The camera looks in the direction (0,0,-1) and up is (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.

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. I've also tried rotating the axes of the viewpoint, and then rotating Model2 around those new axes, but that isn't working either.

Does anyone have a simple algorithm to orient Model2 appropriately? Ideally we wouldn't be rotating the camera, but rather calculate how Model2 should be oriented relative to the viewpoint. 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).

Hopefully that makes sense. If not I will try to elaborate. Thanks for any help you can provide.

1 Answers1

0

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

<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

<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

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.