public override void RotationYawPitchRoll(Angle yaw, Angle pitch, Angle roll) { if (!World.Settings.cameraSmooth) { base.RotationYawPitchRoll(yaw, pitch, roll); this._targetOrientation = m_Orientation; this._targetLatitude = _latitude; this._targetLongitude = _longitude; this._targetHeading = _heading; return; } _targetOrientation = Quaternion4d.EulerToQuaternion(yaw.Radians, pitch.Radians, roll.Radians) * _targetOrientation; Vector3d v = Quaternion4d.QuaternionToEulerV3D(_targetOrientation); if (!double.IsNaN(v.Y)) { this._targetLatitude.Radians = v.Y; } if (!double.IsNaN(v.X)) { this._targetLongitude.Radians = v.X; } if (Math.Abs(roll.Radians) > double.Epsilon) { this._targetHeading.Radians = v.Z; } }
protected void SlerpToTargetOrientation(double percent) { double c = Quaternion4d.Dot(m_Orientation, _targetOrientation); if (c > 1.0) { c = 1.0; } else if (c < -1.0) { c = -1.0; } angle = Angle.FromRadians(Math.Acos(c)); m_Orientation = Quaternion4d.Slerp(m_Orientation, this._targetOrientation, percent); Vector3d v = Quaternion4d.QuaternionToEulerV3D(m_Orientation); if (!double.IsNaN(v.Y)) { this._latitude.Radians = v.Y; this._longitude.Radians = v.X; this._heading.Radians = v.Z; } this._tilt += (this._targetTilt - this._tilt) * percent; this._bank += (this._targetBank - this._bank) * percent; this._distance += (this._targetDistance - this._distance) * percent; ComputeAltitude(this._distance, this._tilt); this._fov += (this._targetFov - this._fov) * percent; }
public override void RotationYawPitchRoll(Angle yaw, Angle pitch, Angle roll) { //if (World.Settings.Project == Projection.Perspective) //{ if (World.Settings.cameraHasMomentum) { _latitudeMomentum += pitch / 100; _longitudeMomentum += yaw / 100; _headingMomentum += roll / 100; } this._targetOrientation = Quaternion4d.EulerToQuaternion(yaw.Radians, pitch.Radians, roll.Radians) * _targetOrientation; Vector3d v = Quaternion4d.QuaternionToEulerV3D(_targetOrientation); if (!double.IsNaN(v.Y)) { this._targetLatitude.Radians = v.Y; this._targetLongitude.Radians = v.X; if (!World.Settings.cameraTwistLock) { _targetHeading.Radians = v.Z; } } base.RotationYawPitchRoll(yaw, pitch, roll); //} }
public virtual void Update(Device device) { this.viewPort = device.Viewport; Vector3d p = Quaternion4d.QuaternionToEulerV3D(m_Orientation); if (!double.IsNaN(p.Y)) { this._latitude.Radians = p.Y; } if (!double.IsNaN(p.X)) { this._longitude.Radians = p.X; } if (!double.IsNaN(p.Z)) { this._heading.Radians = p.Z; } m_Orientation = Quaternion4d.EulerToQuaternion(_longitude.Radians, _latitude.Radians, _heading.Radians); ComputeProjectionMatrix(viewPort); ComputeViewMatrix(); Matrix proh = (Matrix)ConvertDX.FromMatrix4d(m_ProjectionMatrix); device.Transform.Projection = proh; device.Transform.View = (Matrix)ConvertDX.FromMatrix4d(m_ViewMatrix); //TODO JHJ 默认就是单位矩阵 //device.Transform.World = (Matrix)ConvertDX.FromMatrix4d(m_WorldMatrix); ViewFrustum.Update( Matrix4d.Multiply(m_WorldMatrix, Matrix4d.Multiply(m_ViewMatrix, m_ProjectionMatrix))); // Old view range (used in quadtile logic) double factor = (this._altitude) / this._worldRadius; if (factor > 1) { viewRange = Angle.FromRadians(Math.PI); } else { viewRange = Angle.FromRadians(Math.Abs(Math.Asin((this._altitude) / this._worldRadius)) * 2); } // True view range if (factor < 1) { trueViewRange = Angle.FromRadians(Math.Abs(Math.Asin((this._distance) / this._worldRadius)) * 2); } else { trueViewRange = Angle.FromRadians(Math.PI); } }
const int DoubleTapDelay = 3000; // Double tap max time (ms) /// <summary> /// Initializes a new instance of the <see cref= "T:WorldWind.Camera.CameraBase"/> class. /// </summary> /// <param name="targetPosition"></param> /// <param name="radius">Planet's radius in meters</param> public CameraBase(Vector3d targetPosition, double radius) { this._worldRadius = radius; this._distance = 2 * _worldRadius; this._altitude = this._distance; maximumAltitude = 7 * _worldRadius; this.m_Orientation = Quaternion4d.EulerToQuaternion(0, 0, 0); }
public static Quaternion4d Squad( Quaternion4d q1, Quaternion4d a, Quaternion4d b, Quaternion4d c, double t) { return(Slerp( Slerp(q1, c, t), Slerp(a, b, t), 2 * t * (1.0 - t))); }
public World(string name, Vector3d position, Quaternion4d orientation, System.Windows.Forms.Control control, TerrainAccessor terrainAccessor) { this._name = name; m_worldradius = EarthRadius; this.position = position; this.orientation = orientation; MeterPerDegree = SMath.MeterPerDegree(); this._terrainAccessor = terrainAccessor; this.RenderLayerList = new GeoLayerList(); m_OverlayList = new WidgetRoot(control); }
public override bool Equals(object obj) { if (obj is Quaternion4d) { Quaternion4d q = (Quaternion4d)obj; return(q == this); } else { return(false); } }
//TODO JHJ 可以设置镜头初始位置 orientation 带动画 从0,0 旋转到目标位置 public MomentumCamera(Vector3d targetPosition, double radius, Quaternion4d quanternion, bool isanimation) : this(targetPosition, radius) { if (isanimation) { this.TargetOrientation = quanternion; } else { this.TargetOrientation = this.CurrentOrientation = quanternion; } }
/// <summary> /// Initializes a new instance of the <see cref= "T:WorldWind.Camera.WorldCamera"/> class. /// </summary> /// <param name="targetPosition"></param> /// <param name="radius"></param> public WorldCamera(Vector3d targetPosition, double radius) : base(targetPosition, radius) { this._targetOrientation = m_Orientation; this._targetDistance = this._distance; this._targetAltitude = this._altitude; this._targetTilt = this._tilt; this._targetFov = this._fov; //TODO JHJ 修改参数传递问题 _targetLongitude = _longitude; _targetLatitude = _latitude; _targetHeading = _heading; }
/// <summary> /// Transforms a rotation in quaternion form to a set of Euler angles /// </summary> /// <returns>The rotation transformed to Euler angles, X=Yaw, Y=Pitch, Z=Roll (radians)</returns> public static Vector3d QuaternionToEulerV3D(Quaternion4d q) { double q0 = q.W; double q1 = q.X; double q2 = q.Y; double q3 = q.Z; double x = Math.Atan2(2 * (q2 * q3 + q0 * q1), (q0 * q0 - q1 * q1 - q2 * q2 + q3 * q3)); double y = Math.Asin(-2 * (q1 * q3 - q0 * q2)); double z = Math.Atan2(2 * (q1 * q2 + q0 * q3), (q0 * q0 + q1 * q1 - q2 * q2 - q3 * q3)); return(new Vector3d(x, y, z)); }
public bool EpsilonTest(Quaternion4d q) { if (Math.Abs(q.X - this.X) < CameraBase.dEpsilonTestValue && Math.Abs(q.Y - this.Y) < CameraBase.dEpsilonTestValue && Math.Abs(q.Z - this.Z) < CameraBase.dEpsilonTestValue && Math.Abs(q.W - this.W) < 4.0 * CameraBase.dEpsilonTestValue) { return(true); } else { return(false); } }
public static Quaternion4d Slerp(Quaternion4d q0, Quaternion4d q1, double t) { double cosom = q0.X * q1.X + q0.Y * q1.Y + q0.Z * q1.Z + q0.W * q1.W; double tmp0, tmp1, tmp2, tmp3; if (cosom < 0.0) { cosom = -cosom; tmp0 = -q1.X; tmp1 = -q1.Y; tmp2 = -q1.Z; tmp3 = -q1.W; } else { tmp0 = q1.X; tmp1 = q1.Y; tmp2 = q1.Z; tmp3 = q1.W; } /* calc coeffs */ double scale0, scale1; if ((1.0 - cosom) > double.Epsilon) { // standard case (slerp) double omega = Math.Acos(cosom); double sinom = Math.Sin(omega); scale0 = Math.Sin((1.0 - t) * omega) / sinom; scale1 = Math.Sin(t * omega) / sinom; } else { /* just lerp */ scale0 = 1.0 - t; scale1 = t; } Quaternion4d q = new Quaternion4d(); q.X = scale0 * q0.X + scale1 * tmp0; q.Y = scale0 * q0.Y + scale1 * tmp1; q.Z = scale0 * q0.Z + scale1 * tmp2; q.W = scale0 * q0.W + scale1 * tmp3; return(q); }
/// <summary> /// Pan the camera using delta values /// </summary> /// <param name="lat">Latitude offset</param> /// <param name="lon">Longitude offset</param> public override void Pan(Angle lat, Angle lon) { if (World.Settings.cameraHasMomentum) { _latitudeMomentum += lat / 100; _longitudeMomentum += lon / 100; } if (Angle.IsNaN(lat)) { lat = this._targetLatitude; } if (Angle.IsNaN(lon)) { lon = this._targetLongitude; } lat += _targetLatitude; lon += _targetLongitude; if (Math.Abs(lat.Radians) > Math.PI / 2 - 1e-3) { lat.Radians = Math.Sign(lat.Radians) * (Math.PI / 2 - 1e-3); } this._targetOrientation = Quaternion4d.EulerToQuaternion( lon.Radians, lat.Radians, _targetHeading.Radians); Vector3d v = Quaternion4d.QuaternionToEulerV3D(this._targetOrientation); if (!double.IsNaN(v.Y)) { _targetLatitude.Radians = v.Y; _targetLongitude.Radians = v.X; _targetHeading.Radians = v.Z; if (!World.Settings.cameraSmooth) { _latitude = _targetLatitude; _longitude = _targetLongitude; _heading = _targetHeading; m_Orientation = _targetOrientation; } } }
public virtual void RotationYawPitchRoll(Angle yaw, Angle pitch, Angle roll) { m_Orientation = Quaternion4d.EulerToQuaternion(yaw.Radians, pitch.Radians, roll.Radians) * m_Orientation; Vector3d p = Quaternion4d.QuaternionToEulerV3D(m_Orientation); if (!double.IsNaN(p.Y)) { _latitude.Radians = p.Y; } if (!double.IsNaN(p.X)) { _longitude.Radians = p.X; } if (Math.Abs(roll.Radians) > double.Epsilon) { _heading.Radians = p.Z; } }
//the below functions have not been certified to work properly public static Quaternion4d Exp(Quaternion4d q) { double sinom; double om = Math.Sqrt(q.X * q.X + q.Y * q.Y + q.Z * q.Z); if (Math.Abs(om) < double.Epsilon) { sinom = 1.0; } else { sinom = Math.Sin(om) / om; } q.X = q.X * sinom; q.Y = q.Y * sinom; q.Z = q.Z * sinom; q.W = Math.Cos(om); return(q); }
public override void SetPosition(double lat, double lon, double heading, double _altitude, double tilt, double bank) { if (double.IsNaN(lat)) { lat = this._latitude.Degrees; } if (double.IsNaN(lon)) { lon = this._longitude.Degrees; } if (double.IsNaN(heading)) { heading = this._heading.Degrees; } if (double.IsNaN(bank)) { bank = _targetBank.Degrees; } this._targetOrientation = Quaternion4d.EulerToQuaternion( SMath.DegreesToRadians(lon), SMath.DegreesToRadians(lat), SMath.DegreesToRadians(heading)); Vector3d v = Quaternion4d.QuaternionToEulerV3D(this._targetOrientation); this._targetLatitude.Radians = v.Y; this._targetLongitude.Radians = v.X; this._targetHeading.Radians = v.Z; if (!double.IsNaN(tilt)) { this.Tilt = Angle.FromDegrees(tilt); } if (!double.IsNaN(_altitude)) { Altitude = _altitude; } this.Bank = Angle.FromDegrees(bank); }
/// <summary> /// Sets camera position. /// </summary> /// <param name="lat">Latitude in decimal degrees</param> /// <param name="lon">Longitude in decimal degrees</param> /// <param name="heading">Heading in decimal degrees</param> /// <param name="_altitude">Altitude above ground level in meters</param> /// <param name="tilt">Tilt in decimal degrees</param> /// <param name="bank">Camera bank (roll) in decimal degrees</param> public virtual void SetPosition(double lat, double lon, double heading, double _altitude, double tilt, double bank) { if (double.IsNaN(lat)) { lat = this._latitude.Degrees; } if (double.IsNaN(lon)) { lon = this._longitude.Degrees; } if (double.IsNaN(heading)) { heading = this._heading.Degrees; } if (double.IsNaN(bank)) { bank = this._bank.Degrees; } m_Orientation = Quaternion4d.EulerToQuaternion( SMath.DegreesToRadians(lon), SMath.DegreesToRadians(lat), SMath.DegreesToRadians(heading)); Vector3d p = Quaternion4d.QuaternionToEulerV3D(m_Orientation); _latitude.Radians = p.Y; _longitude.Radians = p.X; _heading.Radians = p.Z; if (!double.IsNaN(tilt)) { Tilt = Angle.FromDegrees(tilt); } if (!double.IsNaN(_altitude)) { this.Altitude = _altitude; } this.Bank = Angle.FromDegrees(bank); }
private void InitWorld() { Vector3 v = SMath.SphericalToCartesian(startlatitude, startlongitude, World.EarthRadius); v.Z = (float)startAltitude * 1.0f; Quaternion4d q = Quaternion4d.EulerToQuaternion(SMath.DegreesToRadians(startlongitude), SMath.DegreesToRadians(startlatitude), 0); Quaternion qz = Quaternion.RotationAxis(new Vector3(0, 0, 1), (float)SMath.DegreesToRadians(startlatitude)); //q.W = qz.W; //q.X = qz.X; //q.Y = qz.Y; //q.Z = qz.Z; //TerrainTileService terrainTileService = new TerrainTileService("http://worldwind25.arc.nasa.gov/tile/tile.aspx", "100", 20, 150, "bil", 8, Path.Combine(EarthSetting.CachePath, "Earth\\TerrainAccessor\\SRTM")); TerrainTileService terrainTileService = new TerrainTileService("http://worldwind25.arc.nasa.gov/tile/tile.aspx", "100", 1, 150, "bil", 6, @"D:\空间数据\重庆H48\bil29107"); TerrainAccessor terrainAccessor = new NltTerrainAccessor("Earth", -180, -90, 180, 90, terrainTileService, null); World _world = new World("Earth", new Vector3d(0, 0, 0), q, this.worldViewer1, terrainAccessor); this.worldViewer1.CurrentWorld = _world; this.worldViewer1.ResetSize(); }
public static Quaternion4d Ln(Quaternion4d q) { double t = 0; double s = Math.Sqrt(q.X * q.X + q.Y * q.Y + q.Z * q.Z); double om = Math.Atan2(s, q.W); if (Math.Abs(s) < double.Epsilon) { t = 0.0f; } else { t = om / s; } q.X = q.X * t; q.Y = q.Y * t; q.Z = q.Z * t; q.W = 0.0f; return(q); }
protected void NoSlerpToTargetOrientation() { m_Orientation = this._targetOrientation; Vector3d v = Quaternion4d.QuaternionToEulerV3D(m_Orientation); if (!double.IsNaN(v.Y)) { this._latitude.Radians = v.Y; this._longitude.Radians = v.X; this._heading.Radians = v.Z; } //TODO JHJ 修改参数传递问题 镜头可以指定开始位置 _targetLatitude = _latitude; _targetLongitude = _longitude; _targetHeading = _heading; this._tilt = this._targetTilt; this._bank = this._targetBank; this._distance = this._targetDistance; ComputeAltitude(this._distance, this._tilt); this._fov = this._targetFov; }
public static void SquadSetup( ref Quaternion4d outA, ref Quaternion4d outB, ref Quaternion4d outC, Quaternion4d q0, Quaternion4d q1, Quaternion4d q2, Quaternion4d q3) { q0 = q0 + q1; q0.Normalize(); q2 = q2 + q1; q2.Normalize(); q3 = q3 + q1; q3.Normalize(); q1.Normalize(); outA = q1 * Exp(-0.25 * (Ln(Exp(q1) * q2) + Ln(Exp(q1) * q0))); outB = q2 * Exp(-0.25 * (Ln(Exp(q2) * q3) + Ln(Exp(q2) * q1))); outC = q2; }
/// <summary> /// Pan the camera using delta values /// </summary> /// <param name="lat">Latitude offset</param> /// <param name="lon">Longitude offset</param> public virtual void Pan(Angle lat, Angle lon) { if (Angle.IsNaN(lat)) { lat = this._latitude; } if (Angle.IsNaN(lon)) { lon = this._longitude; } lat += _latitude; lon += _longitude; // this._orientation = SMath.EulerToQuaternion( // lon.Radians, // lat.Radians, // _heading.Radians); m_Orientation = Quaternion4d.EulerToQuaternion( lon.Radians, lat.Radians, _heading.Radians); Vector3d p = Quaternion4d.QuaternionToEulerV3D(m_Orientation); // Vector3d v = SMath.QuaternionToEuler(this._orientation); // if(!double.IsNaN(v.Y)) // { // this._latitude.Radians = v.Y; // this._longitude.Radians = v.X; // } if (!double.IsNaN(p.Y)) { _latitude.Radians = p.Y; _longitude.Radians = p.X; } }
public static double Dot(Quaternion4d a, Quaternion4d b) { return(a.X * b.X + a.Y * b.Y + a.Z * b.Z + a.W * b.W); }
public static double Norm(Quaternion4d q) { return(q.X * q.X + q.Y * q.Y + q.Z * q.Z + q.W * q.W); }
public static double Abs(Quaternion4d q) { return(Math.Sqrt(Norm(q))); }