/// <summary> /// Calculates latitude/longitude for given screen coordinate. /// </summary> public virtual void PickingRayIntersection( int screenX, int screenY, out Angle latitude, out Angle longitude) { if (m_ProjectionMatrix == null || m_ViewMatrix == null) { latitude = Angle.FromDegrees(0); longitude = Angle.FromDegrees(0); return; } Vector3d v1 = Vector3d.Empty; v1.X = screenX; v1.Y = screenY; v1.Z = viewPort.MinZ; v1.Unproject(viewPort, m_ProjectionMatrix, m_ViewMatrix, m_WorldMatrix); Vector3d v2 = Vector3d.Empty; v2.X = screenX; v2.Y = screenY; v2.Z = viewPort.MaxZ; v2.Unproject(viewPort, m_ProjectionMatrix, m_ViewMatrix, m_WorldMatrix); Vector3d p1 = new Vector3d(v1.X, v1.Y, v1.Z); Vector3d p2 = new Vector3d(v2.X, v2.Y, v2.Z); double a = (p2.X - p1.X) * (p2.X - p1.X) + (p2.Y - p1.Y) * (p2.Y - p1.Y) + (p2.Z - p1.Z) * (p2.Z - p1.Z); double b = 2.0 * ((p2.X - p1.X) * (p1.X) + (p2.Y - p1.Y) * (p1.Y) + (p2.Z - p1.Z) * (p1.Z)); double c = p1.X * p1.X + p1.Y * p1.Y + p1.Z * p1.Z - _worldRadius * _worldRadius; double discriminant = b * b - 4 * a * c; if (discriminant <= 0) { latitude = Angle.NaN; longitude = Angle.NaN; return; } double t1 = ((-1.0) * b - Math.Sqrt(b * b - 4 * a * c)) / (2 * a); Vector3d i1 = new Vector3d(p1.X + t1 * (p2.X - p1.X), p1.Y + t1 * (p2.Y - p1.Y), p1.Z + t1 * (p2.Z - p1.Z)); Vector3d i1t = SMath.CartesianToSpherical(i1.X, i1.Y, i1.Z); Vector3d mousePointer = i1t; latitude = Angle.FromRadians(mousePointer.Y); longitude = Angle.FromRadians(mousePointer.Z); }
// Compute Sun geocentric cartesian position given actual position on the globe, // heading, elevation and sun distance public static Vector3d GetGeocentricPosition(Vector3 position, Angle heading, Angle elevation, double sunDistance) { // Untransformed sun pos from globe center Vector3 sun = SMath.SphericalToCartesian(elevation.Degrees, SMath.RadiansToDegrees(Math.PI - heading.Radians), sunDistance); // Now transform it to current location Vector3 pos = SMath.CartesianToSpherical(position.X, position.Y, position.Z); Matrix sunTrans = Matrix.Identity; sunTrans *= Matrix.Translation(0, 0, pos.X); // radius pos sunTrans *= Matrix.RotationY((float)Math.PI / 2 - pos.Y); // lat pos sunTrans *= Matrix.RotationZ(pos.Z); // lon pos sun.TransformCoordinate(sunTrans); return(new Vector3d(-sun.X, -sun.Y, -sun.Z)); }