/// <summary> /// Calculates latitude/longitude for given screen coordinate. /// </summary> public virtual void PickingRayIntersection( int screenX, int screenY, out Angle latitude, out Angle longitude) { Vector3 v1 = new Vector3(); v1.X = screenX; v1.Y = screenY; v1.Z = viewPort.MinZ; v1.Unproject(viewPort, m_absoluteProjectionMatrix, m_absoluteViewMatrix, m_absoluteWorldMatrix); Vector3 v2 = new Vector3(); v2.X = screenX; v2.Y = screenY; v2.Z = viewPort.MaxZ; v2.Unproject(viewPort, m_absoluteProjectionMatrix, m_absoluteViewMatrix, m_absoluteWorldMatrix); Point3d p1 = new Point3d(v1.X, v1.Y, v1.Z); Point3d p2 = new Point3d(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; } // float t0 = ((-1.0f) * b + (float)Math.Sqrt(b*b - 4 * a * c)) / (2*a); double t1 = ((-1.0) * b - Math.Sqrt(b * b - 4 * a * c)) / (2 * a); // Vector3 i0 = new Vector3(p1.X + t0*(p2.X - p1.X), p1.Y + t0*(p2.Y - p1.Y), p1.Z + t0 *(p2.Z - p1.Z)); Point3d i1 = new Point3d(p1.X + t1 * (p2.X - p1.X), p1.Y + t1 * (p2.Y - p1.Y), p1.Z + t1 * (p2.Z - p1.Z)); // Vector3 i0t = MathEngine.CartesianToSpherical(i0.X, i0.Y, i0.Z); Point3d i1t = MathEngine.CartesianToSphericalD(i1.X, i1.Y, i1.Z); Point3d mousePointer = i1t; latitude = Angle.FromRadians(mousePointer.Y); longitude = Angle.FromRadians(mousePointer.Z); }
/// <summary> /// 1.绘制太阳 /// </summary> /// <param name="drawArgs"></param> private void RenderSun(DrawArgs drawArgs) { //根据时间计算太阳的位置 Point3d sunPosition = -SunCalculator.GetGeocentricPosition(TimeKeeper.CurrentTimeUtc); Point3d sunSpherical = MathEngine.CartesianToSphericalD(sunPosition.X, sunPosition.Y, sunPosition.Z); sunPosition = MathEngine.SphericalToCartesianD( Angle.FromRadians(sunSpherical.Y), Angle.FromRadians(sunSpherical.Z), 150000000000); Vector3 sunVector = new Vector3((float)sunPosition.X, (float)sunPosition.Y, (float)sunPosition.Z); Frustum viewFrustum = new Frustum(); float aspectRatio = (float)drawArgs.WorldCamera.Viewport.Width / drawArgs.WorldCamera.Viewport.Height; Matrix projectionMatrix = Matrix.PerspectiveFovRH((float)drawArgs.WorldCamera.Fov.Radians, aspectRatio, 1.0f, 300000000000); viewFrustum.Update( Matrix.Multiply(drawArgs.WorldCamera.AbsoluteWorldMatrix, Matrix.Multiply(drawArgs.WorldCamera.AbsoluteViewMatrix, projectionMatrix))); if (!viewFrustum.ContainsPoint(sunVector)) { return; } Vector3 translationVector = new Vector3( (float)(sunPosition.X - drawArgs.WorldCamera.ReferenceCenter.X), (float)(sunPosition.Y - drawArgs.WorldCamera.ReferenceCenter.Y), (float)(sunPosition.Z - drawArgs.WorldCamera.ReferenceCenter.Z)); Vector3 projectedPoint = drawArgs.WorldCamera.Project(translationVector); if (m_sunTexture == null) { m_sunTexture = ImageHelper.LoadTexture(Path.Combine(((QRSTWorldGlobeControl)drawArgs.parentControl).DataDirectory, @"Space\sun.dds")); m_sunSurfaceDescription = m_sunTexture.GetLevelDescription(0); } if (m_sprite == null) { m_sprite = new Sprite(drawArgs.device); } m_sprite.Begin(SpriteFlags.AlphaBlend); // Render icon float xscale = (float)m_sunWidth / m_sunSurfaceDescription.Width; float yscale = (float)m_sunHeight / m_sunSurfaceDescription.Height; m_sprite.Transform = Matrix.Scaling(xscale, yscale, 0); m_sprite.Transform *= Matrix.Translation(projectedPoint.X, projectedPoint.Y, 0); m_sprite.Draw(m_sunTexture, new Vector3(m_sunSurfaceDescription.Width >> 1, m_sunSurfaceDescription.Height >> 1, 0), Vector3.Empty, System.Drawing.Color.FromArgb(253, 253, 200).ToArgb()); // Reset transform to prepare for text rendering later m_sprite.Transform = Matrix.Identity; m_sprite.End(); }