Пример #1
0
        public virtual void ComputeViewMatrix()
        {
            double lat1 = _latitude.Degrees;
            double lon1 = _longitude.Degrees;


            EyeDiff.X = SMath.DegreesToRadians(_latitude.Degrees - lat1);
            EyeDiff.Y = SMath.DegreesToRadians(_longitude.Degrees - lon1);

            ReferenceCenter = SMath.SphericalToCartesianV3D(
                _latitude.Degrees,
                _longitude.Degrees,
                WorldRadius);


            if (World.Settings.Project == Projection.OrthoGraghics)
            {
                //lat1 = 0;
                //lon1 = 0;

                EyeDiff.X = 0;
                EyeDiff.Y = 0;
            }

            Vector3d defaultPosition = SMath.SphericalToCartesianV3D(lat1, lon1, _worldRadius);


            m_ViewMatrix = Matrix4d.LookAtRH(
                defaultPosition,
                Vector3d.Empty,
                cameraUpVector);
            //TODO JHJ 这是干什么的  有什么用
            m_ViewMatrix *= Matrix4d.Translation(0, 0, _worldRadius);
            m_ViewMatrix *= Matrix4d.RotationYawPitchRoll(-EyeDiff.Y, EyeDiff.X, 0);
            m_ViewMatrix *= Matrix4d.Translation(0, 0, -_worldRadius);

            m_ViewMatrix *= Matrix4d.RotationYawPitchRoll(
                0,
                -_tilt.Radians,
                this._heading.Radians);
            m_ViewMatrix *= Matrix4d.Translation(0, 0, (-this._distance));
            if (World.Settings.Project == Projection.Perspective)
            {
                m_ViewMatrix *= Matrix4d.RotationZ(this._bank.Radians);
            }
            else
            {
                m_ViewMatrix *= Matrix4d.RotationZ(this._bank.Radians);
            }

            // Extract camera position
            Matrix4d cam = Matrix4d.Invert(m_ViewMatrix);

            _position = new Vector3d(cam[3, 0], cam[3, 1], cam[3, 2]);
        }
Пример #2
0
        /// <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);
        }
Пример #3
0
        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);
        }
Пример #4
0
        // 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));
        }
Пример #5
0
        public static Vector3d GetGeocentricPosition(System.DateTime utcDateTime)
        {
            if (World.Settings.SunSynchedWithTime)
            {
                // Sun synched with time and date
                double JD = getJulianDay(utcDateTime);
                double T  = (JD - 2451545.0) / 36525; // number of Julian centuries since Jan 1, 2000, 12 UT

                double k  = Math.PI / 180.0;
                double M  = 357.52910 + 35999.05030 * T - 0.0001559 * T * T - 0.00000048 * T * T * T; // mean anomaly, degree
                double L0 = 280.46645 + 36000.76983 * T + 0.0003032 * T * T;                          // mean longitude, degree
                double DL = (1.914600 - 0.004817 * T - 0.000014 * T * T) * Math.Sin(k * M) + (0.019993 - 0.000101 * T) * Math.Sin(k * 2 * M) + 0.000290 * Math.Sin(k * 3 * M);
                double L  = L0 + DL;                                                                  // true longitude, degree
                L = L % 360;
                //		obliquity eps of ecliptic:
                double eps = 23.0 + 26.0 / 60.0 + 21.448 / 3600.0 - (46.8150 * T + 0.00059 * T * T - 0.001813 * T * T * T) / 3600;

                double X = Math.Cos(k * L);
                double Y = Math.Cos(k * eps) * Math.Sin(k * L);
                double Z = Math.Sin(k * eps) * Math.Sin(k * L);

                double R = Math.Sqrt(1.0 - Z * Z);

                double dec = (180 / Math.PI) * Math.Atan(Z / R);                                                                  // in degrees
                double RA  = (24 / Math.PI) * Math.Atan(Y / (X + R));                                                             // in hours

                double theta0 = 280.46061837 + 360.98564736629 * (JD - 2451545.0) + 0.000387933 * T * T - T * T * T / 38710000.0; // Greenwich Sidereal Time

                theta0 = theta0 % 360;
                RA    *= 15; // convert from hours to degrees
                double tau = theta0 - RA;

                Vector3d pos = SMath.SphericalToCartesianV3D(
                    -dec,
                    -(tau - 180), 1);

                return(pos);
            }
            else
            {
                // Fixed sun heading and elevation
                double  worldRadius = 6378137;  // Earth meter
                Vector3 position    = SMath.SphericalToCartesian(DrawArgs.Instance.WorldCamera.Latitude.Degrees, DrawArgs.Instance.WorldCamera.Longitude.Degrees, worldRadius);
                return(GetGeocentricPosition(position, Angle.FromRadians(World.Settings.SunHeading), Angle.FromRadians(World.Settings.SunElevation), World.Settings.SunDistance));
            }
        }
Пример #6
0
        /// <summary>
        /// Intermediate points on a great circle
        /// In previous sections we have found intermediate points on a great circle given either
        /// the crossing latitude or longitude. Here we find points (lat,lon) a given fraction of the
        /// distance (d) between them. Suppose the starting point is (lat1,lon1) and the final point
        /// (lat2,lon2) and we want the point a fraction f along the great circle route. f=0 is
        /// point 1. f=1 is point 2. The two points cannot be antipodal ( i.e. lat1+lat2=0 and
        /// abs(lon1-lon2)=pi) because then the route is undefined.
        /// </summary>
        /// <param name="f">Fraction of the distance for intermediate point (0..1)</param>
        public Vector3 IntermediateGCPoint(float f, Angle lat1, Angle lon1, Angle lat2, Angle lon2, Angle d)
        {
            double sind    = Math.Sin(d.Radians);
            double cosLat1 = Math.Cos(lat1.Radians);
            double cosLat2 = Math.Cos(lat2.Radians);
            double A       = Math.Sin((1 - f) * d.Radians) / sind;
            double B       = Math.Sin(f * d.Radians) / sind;
            double x       = A * cosLat1 * Math.Cos(lon1.Radians) + B * cosLat2 * Math.Cos(lon2.Radians);
            double y       = A * cosLat1 * Math.Sin(lon1.Radians) + B * cosLat2 * Math.Sin(lon2.Radians);
            double z       = A * Math.Sin(lat1.Radians) + B * Math.Sin(lat2.Radians);
            Angle  lat     = Angle.FromRadians(Math.Atan2(z, Math.Sqrt(x * x + y * y)));
            Angle  lon     = Angle.FromRadians(Math.Atan2(y, x));

            Vector3 v = SMath.SphericalToCartesian(lat.Degrees, lon.Degrees, World.EquatorialRadius);

            return(v);
        }
Пример #7
0
        public void Update(double south, double north, double west, double east, double radius1, double radius2)
        {
            double scale = radius2 / radius1;

            SMath.SphericalToCartesianV3D(south, west, radius1, ref this.corners[0]);
            this.corners[1] = this.corners[0];
            this.corners[1].scale(scale);
            SMath.SphericalToCartesianV3D(south, east, radius1, ref this.corners[2]);
            this.corners[3] = this.corners[2];
            this.corners[3].scale(scale);
            SMath.SphericalToCartesianV3D(north, west, radius1, ref this.corners[4]);
            this.corners[5] = this.corners[4];
            this.corners[5].scale(scale);
            SMath.SphericalToCartesianV3D(north, east, radius1, ref this.corners[6]);
            this.corners[7] = this.corners[6];
            this.corners[7].scale(scale);

            ComputeBoundSphere();
        }
Пример #8
0
        /// <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);
        }
Пример #9
0
        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);
        }
Пример #10
0
        /// <summary>
        /// 输出对应插值的Point3d(纬度,经度,高程)。高程值为当前经纬度下的最高精度值。
        /// 空间插值,通过首尾两点的经纬度计算,由f来控制此点的次序,f=n/N;在0~1之间
        /// </summary>
        /// <param name="Args"></param>
        /// <param name="f"></param>
        /// <param name="lat1"></param>
        /// <param name="lon1"></param>
        /// <param name="lat2"></param>
        /// <param name="lon2"></param>
        /// <returns></returns>
        public static Vector3d CacuInterGCPoint(float f, Angle lat1, Angle lon1, Angle lat2, Angle lon2)
        {
            Angle  lat;
            Angle  lon;
            Double Z = new double();

            Angle  d       = SMath.ApproxAngularDistance(lat1.Radians, lon1.Radians, lat2.Radians, lon2.Radians);
            double sind    = Math.Sin(d.Radians);
            double cosLat1 = Math.Cos(lat1.Radians);
            double cosLat2 = Math.Cos(lat2.Radians);
            double A       = Math.Sin((1 - f) * d.Radians) / sind;
            double B       = Math.Sin(f * d.Radians) / sind;
            double x       = A * cosLat1 * Math.Cos(lon1.Radians) + B * cosLat2 * Math.Cos(lon2.Radians);
            double y       = A * cosLat1 * Math.Sin(lon1.Radians) + B * cosLat2 * Math.Sin(lon2.Radians);
            double z       = A * Math.Sin(lat1.Radians) + B * Math.Sin(lat2.Radians);

            lat = Angle.FromRadians(Math.Atan2(z, Math.Sqrt(x * x + y * y)));
            lon = Angle.FromRadians(Math.Atan2(y, x));
            Z   = 0;
            Vector3d p = new Vector3d(lat.Degrees, lon.Degrees, Z);

            return(p);
        }
Пример #11
0
        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();
        }
Пример #12
0
        public void Initialize(Device device)
        {
            this.numvertices  = (this.slice + 1) * (this.stack + 1);
            this.numtriangles = this.slice * this.stack * 2;
            this.numindices   = this.numtriangles * 3;

            DoubleTextureVertex[] verts = new DoubleTextureVertex[this.numvertices];
            int[] ind = new int[this.numindices];

            double stacksize = 180.0 / stack;
            double slicesize = 360.0 / slice;
            int    index     = 0;

            for (int i = 0; i <= stack; i++)
            {
                double lat = -90.0 + i * stacksize;
                float  tv  = (float)(i * 1.0 / stack);

                for (int j = 0; j <= slice; j++)
                {
                    double  lon = -180.0 + j * slicesize;
                    Vector3 v   = SMath.SphericalToCartesian(lat, lon, this.radius);
                    Vector3 n   = Vector3.Normalize(v);
                    verts[index++] = new DoubleTextureVertex(
                        v,
                        n,
                        (float)(j * 1.0 / slice),
                        tv,
                        0.5f, 0.5f, 0, 0, false);
                }
            }

            int io           = 0;
            int bottomVertex = 0;
            int topVertex    = 0;

            for (int x = 0; x < stack; x++)
            {
                bottomVertex = (slice + 1) * x;
                topVertex    = (bottomVertex + slice + 1);

                for (int y = 0; y < slice; y++)
                {
                    ind[io++] = bottomVertex;
                    ind[io++] = topVertex;
                    ind[io++] = topVertex + 1;
                    ind[io++] = bottomVertex;
                    ind[io++] = topVertex + 1;
                    ind[io++] = bottomVertex + 1;
                }
            }

            this.vb = new VertexBuffer(typeof(DoubleTextureVertex),
                                       this.numvertices,
                                       device,
                                       Usage.Dynamic,
                                       DoubleTextureVertex.Format,
                                       Pool.Default);
            this.vb.SetData(verts, 0, 0);

            this.ib = new IndexBuffer(typeof(int), this.numindices,
                                      device, 0, 0);
            this.ib.SetData(ind, 0, 0);

            // Create the vertexdeclaration
            VertexElement[] vs = new VertexElement[] { new VertexElement(0, 0, DeclarationType.Float3, DeclarationMethod.Default, DeclarationUsage.Position, 0),
                                                       new VertexElement(0, 12, DeclarationType.Float3, DeclarationMethod.Default, DeclarationUsage.Normal, 0),
                                                       new VertexElement(0, 24, DeclarationType.Float2, DeclarationMethod.Default, DeclarationUsage.TextureCoordinate, 0),
                                                       new VertexElement(0, 32, DeclarationType.Float4, DeclarationMethod.Default, DeclarationUsage.TextureCoordinate, 1),
                                                       VertexElement.VertexDeclarationEnd };

            this.decl = new VertexDeclaration(device, vs);
        }