コード例 #1
0
ファイル: SunCalculator.cs プロジェクト: PrincessGod/2017.2
        // 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));
        }
コード例 #2
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);
        }
コード例 #3
0
ファイル: SunCalculator.cs プロジェクト: PrincessGod/2017.2
        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));
            }
        }
コード例 #4
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();
        }
コード例 #5
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);
        }