コード例 #1
0
ファイル: RotationQuaternion.cs プロジェクト: DigNative/MSISF
        public RotationQuaternion(Vector3D axis, double angle)
        {
            double sinCoeff = Math.Sin(angle / 2);

            this._r = Math.Cos(angle / 2);
            this._v = new Vector3D( axis.x() * sinCoeff,
                                    axis.y() * sinCoeff,
                                    axis.z() * sinCoeff);
        }
コード例 #2
0
ファイル: KeplerOrbit.cs プロジェクト: DigNative/MSISF
        public KeplerOrbit(Vector3D r, Vector3D dr)
        {
            Vector3D h = r % dr;
            Vector3D ev = ((dr % h) / _GM) - (r / r.norm());
            Vector3D n = new Vector3D(0, 0, 1) % h;
            double nu = 0;

            if (r * dr >= 0)
            {
                nu = Math.Acos((ev * r) / (ev.norm() * r.norm()));
            }
            else
            {
                nu = (2*Math.PI - Math.Acos((ev * r) / (ev.norm() * r.norm())));
            }

            double E = Math.Acos((ev.norm() + Math.Cos(nu)) / (1 + (ev.norm() * Math.Cos(nu))));
            double i = Math.Acos(h.z()/h.norm());
            double e = ev.norm();
            double Omega = 0;

            if (n.y() >= 0)
            {
                Omega = Math.Acos(n.x() / n.norm());
            }
            else
            {
                Omega = 2*Math.PI - Math.Acos(n.x() / n.norm());
            }

            double omega = 0;

            if (ev.z() >= 0)
            {
                omega = Math.Acos((n*ev) / (n.norm()*ev.norm()));
            }
            else
            {
                omega = 2*Math.PI - Math.Acos((n * ev) / (n.norm() * ev.norm()));
            }

            double M = E - (e * Math.Sin(E));
            double a = 1 / ((2/r.norm()) - (Math.Pow(dr.norm(),2)/_GM));

            this.setKeplerElements(a, e, omega, Omega, i, M);
        }
コード例 #3
0
ファイル: Spacecraft.cs プロジェクト: DigNative/MSISF
 public void setStateVectors(Vector3D r, Vector3D dr)
 {
     this._kepler_orbit = new KeplerOrbit(r, dr);
 }
コード例 #4
0
ファイル: Spacecraft.cs プロジェクト: DigNative/MSISF
 public void setPosition(Vector3D r)
 {
     this._fixed_position = r;
     this.fixedPositionGiven = true;
 }
コード例 #5
0
ファイル: Spacecraft.cs プロジェクト: DigNative/MSISF
 public void setOrientationTransition(Vector3D trans)
 {
     this._orientation_transition = trans;
 }
コード例 #6
0
ファイル: Vector3D.cs プロジェクト: DigNative/MSISF
        public Vector3D QuaternionRotate(Vector3D axis, double angle)
        {
            Quaternion RotationQuaternion = new RotationQuaternion(axis, angle);
            Quaternion RotationQuaternionConjugate = RotationQuaternion.conjugate();
            Quaternion vec = new Quaternion(0, this._x, this._y, this._z);

            Quaternion result = RotationQuaternion * vec * RotationQuaternionConjugate;

            return result.getVector();
        }
コード例 #7
0
ファイル: KeplerOrbit.cs プロジェクト: DigNative/MSISF
        public Vector3D getPosition(double t)
        {
            double M = 0;
            double dt = 0;
            double E = 0;
            double nu = 0;
            double r_c = 0;
            Vector3D o = new Vector3D();
            //Vector3D d_o = new Vector3D();
            Vector3D r = new Vector3D();

            if (t == this._epoch)
            {
                M = this._M0;
            }
            else
            {
                dt = 86400 * (t - this._epoch);
                M = this._M0 + dt * Math.Sqrt((_GM) / (Math.Pow(this._a, 3)));
                M = tools.normalizeAngle(M);
            }

            E = tools.solveKeplerForE(M, this._e);
            nu = 2 * Math.Atan2(Math.Sqrt(1 + this._e) * Math.Sin(E / 2), Math.Sqrt(1 - this._e) * Math.Cos(E / 2));
            r_c = this._a * (1 - this._e * Math.Cos(E));
            o = r_c * new Vector3D(Math.Cos(nu), Math.Sin(nu), 0);
            //d_o = (Math.Sqrt(_GM * this._a) / r_c) * new Vector3D(-Math.Sin(E), Math.Sqrt(1 - Math.Pow(this._e, 2)) * Math.Cos(E), 0);

            r = new Vector3D(
                    o.x() * (Math.Cos(this._omega) * Math.Cos(this._Omega) - Math.Sin(this._omega) * Math.Cos(this._i) * Math.Sin(this._Omega)) - o.y() * (Math.Sin(this._omega) * Math.Cos(this._Omega) + Math.Cos(this._omega) * Math.Cos(this._i) * Math.Sin(this._Omega)),
                    o.x() * (Math.Cos(this._omega) * Math.Sin(this._Omega) - Math.Sin(this._omega) * Math.Cos(this._i) * Math.Cos(this._Omega)) + o.y() * (Math.Cos(this._omega) * Math.Cos(this._i) * Math.Cos(this._Omega) - Math.Sin(this._omega) * Math.Sin(this._Omega)),
                    o.x() * (Math.Sin(this._omega) * Math.Sin(this._i)) + o.y() * (Math.Cos(this._omega) * Math.Sin(this._i)));

            //Console.WriteLine(o.x().ToString("e"));
            //Console.WriteLine(o.y().ToString("e"));
            //Console.WriteLine(o.z().ToString("e"));

            return r;
        }
コード例 #8
0
ファイル: Simulation.cs プロジェクト: DigNative/MSISF
        private void DSPSA(Vector3D rayDirection, Vector3D camPos, ArrayList patternList)
        {
            double discriminant = 4 * Math.Pow(camPos * rayDirection, 2) - 4 * (rayDirection * rayDirection) * (camPos * camPos) + 4 * (rayDirection * rayDirection) * Math.Pow(_moon_radius, 2);

            bool encounter = false;
            double lat = 0;
            double lon = 0;

            if (discriminant < 0)
            {
                // no encounter
            }
            else if (discriminant == 0)
            {
                // one intersection
                encounter = true;
                double t = (-2 * (camPos * rayDirection)) / (2 * (rayDirection * rayDirection));

                Vector3D ray_point = camPos + rayDirection * t;
                lat = tools.rad2deg((Math.PI / 2) - Math.Acos(ray_point.z() / _moon_radius));
                lon = tools.rad2deg(Math.Atan2(ray_point.y(), ray_point.x()));
            }
            else
            {
                // two intersections
                encounter = true;
                double t1 = (-2 * (camPos * rayDirection) + Math.Sqrt(discriminant)) / (2 * (rayDirection * rayDirection));
                double t2 = (-2 * (camPos * rayDirection) - Math.Sqrt(discriminant)) / (2 * (rayDirection * rayDirection));

                Vector3D ray_point1 = camPos + rayDirection * t1;
                Vector3D ray_point2 = camPos + rayDirection * t2;
                double ray_norm1 = (ray_point1 - camPos).norm();
                double ray_norm2 = (ray_point2 - camPos).norm();

                if (ray_norm1 < ray_norm2)
                {
                    lat = tools.rad2deg((Math.PI / 2) - Math.Acos(ray_point1.z() / _moon_radius));
                    lon = tools.rad2deg(Math.Atan2(ray_point1.y(), ray_point1.x()));
                }
                else
                {
                    lat = tools.rad2deg((Math.PI / 2) - Math.Acos(ray_point2.z() / _moon_radius));
                    lon = tools.rad2deg(Math.Atan2(ray_point2.y(), ray_point2.x()));
                }
            }

            if (lon < 0)
            {
                lon += 360;
            }

            if (encounter)
            {
                double lat_start = 0;
                double lat_end = 0;
                double lon_start = 0;
                double lon_end = 0;

                if (lat >= 0)
                {
                    lat_start = Math.Truncate(lat / 5) * 5;
                    lat_end = lat_start + 5;
                }
                else
                {
                    lat_end = Math.Truncate(lat / 5) * 5;
                    lat_start = lat_end - 5;
                }

                lon_start = Math.Truncate(lon / 5) * 5;
                lon_end = lon_start + 5;

                string temp = "_lat_" + lat_start + "_" + lat_end + "_lon_" + lon_start + "_" + lon_end;
                if (!patternList.Contains(temp))
                {
                    patternList.Add(temp);
                }
            }
        }
コード例 #9
0
ファイル: Simulation.cs プロジェクト: DigNative/MSISF
        private PixelInformation getIlluminationDirectionPerRenderingPixel(SpacecraftState sc, uint x, uint y)
        {
            PixelInformation PixelOut = new PixelInformation();
            Vector3D c_pos = sc.getPosition();

            // STEP 1: Visibility Test
            Vector3D rayDirection = (sc.getPOVDirection() + (((1 + Convert.ToDouble(this._height) - (2 * Convert.ToDouble(y))) / (2 * Convert.ToDouble(this._height))) * sc.getPOVUp()) - (((1 + Convert.ToDouble(this._width) - (2 * Convert.ToDouble(x))) / (2 * Convert.ToDouble(this._width))) * sc.getPOVRight())).unit();
            double discriminant = 4 * Math.Pow(c_pos * rayDirection, 2) - 4 * (rayDirection * rayDirection) * (c_pos * c_pos) + 4 * (rayDirection * rayDirection) * Math.Pow(_moon_radius, 2);

            bool encounter = false;
            Vector3D p_surf = new Vector3D();

            if (discriminant < 0)
            {
                // no encounter
            }
            else if (discriminant == 0)
            {
                // one intersection
                encounter = true;
                double t = (-2 * (c_pos * rayDirection)) / (2 * (rayDirection * rayDirection));

                p_surf = c_pos + rayDirection * t;
            }
            else
            {
                // two intersections
                encounter = true;
                double t1 = (-2 * (c_pos * rayDirection) + Math.Sqrt(discriminant)) / (2 * (rayDirection * rayDirection));
                double t2 = (-2 * (c_pos * rayDirection) - Math.Sqrt(discriminant)) / (2 * (rayDirection * rayDirection));

                Vector3D ray_point1 = c_pos + rayDirection * t1;
                Vector3D ray_point2 = c_pos + rayDirection * t2;
                double ray_norm1 = (ray_point1 - c_pos).norm();
                double ray_norm2 = (ray_point2 - c_pos).norm();

                if (ray_norm1 < ray_norm2)
                {
                    p_surf = ray_point1;
                }
                else
                {
                    p_surf = ray_point2;
                }
            }

            if (encounter)
            {
                /*
                    Pixel shows the Moon's surface: Continue with executing steps 2 - 8.
                */
                double x1 = Convert.ToDouble(x);
                double y1 = Convert.ToDouble(y);

                // STEP 2: Obtaining the Surface Hit Point
                PixelOut.lat = tools.rad2deg((Math.PI / 2) - Math.Acos(p_surf.z() / _moon_radius));
                PixelOut.lon = tools.rad2deg(Math.Atan2(p_surf.y(), p_surf.x()));

                // STEP 3: Calculation of the Sun's direction
                Vector3D hat_p_surf = p_surf.unit();
                Vector3D hat_d_sun = (sc.getSunPosition() - p_surf).unit();

                // STEP 4: Derivation of the Local Tangent Plane of the Surface Hit Point (nothing to do here)
                // STEP 5: Determination of a Subsurface Point of the Solar Illumination Direction on the Local Tangent Plane
                double lambda_5 = -(1000 * (hat_d_sun.x() * hat_p_surf.x() + hat_d_sun.y() * hat_p_surf.y() + hat_d_sun.z() * hat_p_surf.z())) / (hat_p_surf.x() * hat_p_surf.x() + hat_p_surf.y() * hat_p_surf.y() + hat_p_surf.z() * hat_p_surf.z());
                Vector3D p_local = p_surf + 1000 * hat_d_sun + lambda_5 * hat_p_surf;

                // STEP 6: Local Illumination Direction
                Vector3D hat_d_local = (p_local - c_pos).unit();

                /// STEP 7: Projection of the Local Illumination Point to the Image Plane
                Vector3D k = c_pos + sc.getPOVDirection();
                Vector3D c_up = sc.getPOVUp();
                Vector3D c_right = sc.getPOVRight();
                double w = Convert.ToDouble(this._width);
                double h = Convert.ToDouble(this._height);

                double x2 =
                    (
                        -2 * w * c_pos.y() * c_up.z() * hat_d_local.x() - c_right.y() * c_up.z() * hat_d_local.x() - w * c_right.y() * c_up.z() * hat_d_local.x()
                        + 2 * w * c_pos.x() * c_up.z() * hat_d_local.y() + c_right.x() * c_up.z() * hat_d_local.y() + w * c_right.x() * c_up.z() * hat_d_local.y()
                        + 2 * w * c_pos.z() * (c_up.y() * hat_d_local.x() - c_up.x() * hat_d_local.y())
                        + (1 + w) * c_right.z() * (c_up.y() * hat_d_local.x() - c_up.x() * hat_d_local.y())
                        + 2 * w * c_pos.y() * c_up.x() * hat_d_local.z() + c_right.y() * c_up.x() * hat_d_local.z() + w * c_right.y() * c_up.x() * hat_d_local.z()
                        - 2 * w * c_pos.x() * c_up.y() * hat_d_local.z() - c_right.x() * c_up.y() * hat_d_local.z() - w * c_right.x() * c_up.y() * hat_d_local.z()
                        - 2 * w * c_up.z() * hat_d_local.y() * k.x() + 2 * w * c_up.y() * hat_d_local.z() * k.x() + 2 * w * c_up.z() * hat_d_local.x() * k.y() - 2 * w * c_up.x() * hat_d_local.z() * k.y()
                        - 2 * w * c_up.y() * hat_d_local.x() * k.z() + 2 * w * c_up.x() * hat_d_local.y() * k.z()
                    )/(
                        2 * (c_right.z() * (c_up.y() * hat_d_local.x() - c_up.x() * hat_d_local.y()) + c_right.y() * (-c_up.z() * hat_d_local.x() + c_up.x() * hat_d_local.z()) + c_right.x() * (c_up.z() * hat_d_local.y() - c_up.y() * hat_d_local.z()))
                    );

                double y2 =
                    (
                        -c_right.z() * c_up.y() * hat_d_local.x() - h * c_right.z() * c_up.y() * hat_d_local.x() + c_right.y() * c_up.z() * hat_d_local.x()
                        + h * c_right.y() * c_up.z() * hat_d_local.x() - 2 * h * c_pos.x() * c_right.z() * hat_d_local.y() + c_right.z() * c_up.x() * hat_d_local.y()
                        + h * c_right.z() * c_up.x() * hat_d_local.y() - c_right.x() * c_up.z() * hat_d_local.y() - h * c_right.x() * c_up.z() * hat_d_local.y()
                        + c_pos.z() * (-2 * h * c_right.y() * hat_d_local.x() + 2 * h * c_right.x() * hat_d_local.y()) + 2 * h * c_pos.x() * c_right.y() * hat_d_local.z()
                        - c_right.y() * c_up.x() * hat_d_local.z() - h * c_right.y() * c_up.x() * hat_d_local.z() + c_right.x() * c_up.y() * hat_d_local.z()
                        + h * c_right.x() * c_up.y() * hat_d_local.z() + 2 * h * c_pos.y() * (c_right.z() * hat_d_local.x() - c_right.x() * hat_d_local.z())
                        + 2 * h * c_right.z() * hat_d_local.y() * k.x() - 2 * h * c_right.y() * hat_d_local.z() * k.x() - 2 * h * c_right.z() * hat_d_local.x() * k.y()
                        + 2 * h * c_right.x() * hat_d_local.z() * k.y() + 2 * h * c_right.y() * hat_d_local.x() * k.z() - 2 * h * c_right.x() * hat_d_local.y() * k.z()
                    )/(
                        2 * (c_right.z() * (-c_up.y() * hat_d_local.x() + c_up.x() * hat_d_local.y()) + c_right.y() * (c_up.z() * hat_d_local.x() - c_up.x() * hat_d_local.z()) + c_right.x() * (-c_up.z() * hat_d_local.y() + c_up.y() * hat_d_local.z()))
                    );

                // STEP 8: The Local Solar Illumination Angle
                Vector2D v1 = new Vector2D(0, 1000);
                Vector2D v2 = new Vector2D(x2-x1, y2-y1);

                if (v2.x() > 0)
                {
                    PixelOut.IlluminationAngle = tools.rad2deg(Math.Acos((v1 * v2) / (v1.norm() * v2.norm())));
                }
                else
                {
                    PixelOut.IlluminationAngle = tools.rad2deg(2 * Math.PI - Math.Acos((v1 * v2) / (v1.norm() * v2.norm())));
                }
                PixelOut.exists = true;

                return PixelOut;
            }
            else
            {
                // next grid sample point
                return PixelOut;
            }
        }
コード例 #10
0
ファイル: Simulation.cs プロジェクト: DigNative/MSISF
 public void setBatchSet(double time, Vector3D pos)
 {
     Spacecraft sc = new Spacecraft();
     sc.setStateVectors(pos, new Vector3D(0, 0, 0));
     this.spacecrafts.Add(sc);
 }
コード例 #11
0
ファイル: Simulation.cs プロジェクト: DigNative/MSISF
 public void setBatchSet(double time, Vector3D pos, Quaternion orientation)
 {
     Spacecraft sc = new Spacecraft();
     sc.setPosition(pos);
     if (orientation.Norm() > 0)
     {
         sc.setOrientation(orientation);
     }
     sc.setFixedTime(time);
     this.spacecrafts.Add(sc);
 }
コード例 #12
0
ファイル: SpacecraftState.cs プロジェクト: DigNative/MSISF
        public void setTime(double time)
        {
            this._time = time;
            if (this.fixedPositionGiven)
            {
                this._position = this._fixed_position;
            }
            else
            {
                this._position = this._kepler_orbit.getPosition(time);
            }
            this._sun_position = this.calculateSunPosition();

            if (this.isOrientationGiven())
            {
                // take orientation transition into account
                this._orientation = new RotationQuaternion(new Vector3D(0, 0, 1), this._orientation_transition.z()) *
                                    new RotationQuaternion(new Vector3D(0, 1, 0), this._orientation_transition.y()) *
                                    new RotationQuaternion(new Vector3D(1, 0, 0), this._orientation_transition.x()) *
                                    this._initial_orientation;
                this._POV_right = this._POV_right.QuaternionRotate(this._orientation);
                this._POV_direction = ((new Vector3D(-1, 0, 0).QuaternionRotate(this._orientation) / (new Vector3D(-1, 0, 0).QuaternionRotate(this._orientation).norm())) * ((0.5 * this._POV_right.norm()) / Math.Tan(tools.deg2rad(Program.sim.getFOV()) / 2)));
            }
            else
            {
                // calculate necessary orientation quaternion to look nadir
                double phi, theta, r;
                r = this.getPosition().norm();
                phi = Math.Atan2(this.getPosition().y(), this.getPosition().x());
                theta = Math.Acos(this.getPosition().z() / r);

                this._orientation = new RotationQuaternion(new Vector3D(0, 1, 0), theta) * new RotationQuaternion(new Vector3D(0, 0, 1), -phi);
                this._POV_right = this._POV_right.QuaternionRotate(this._orientation);
                this._POV_direction = ((new Vector3D(-this.getPosition().x(), -this.getPosition().y(), -this.getPosition().z()) / (new Vector3D(-this.getPosition().x(), -this.getPosition().y(), -this.getPosition().z()).norm())) * ((0.5 * this._POV_right.norm()) / Math.Tan(tools.deg2rad(Program.sim.getFOV()) / 2)));
            }

            this._POV_up = this._POV_right % this._POV_direction; // cross product
            this._POV_up = this._POV_up / this._POV_up.norm();
        }
コード例 #13
0
ファイル: Quaternion.cs プロジェクト: DigNative/MSISF
 /// <summary>
 ///     Constructor for a quaternion defined by one double value as real part and a Vector3D as vector part.
 /// </summary>
 /// <param name="real">real part</param>
 /// <param name="vec">vector part</param>
 public Quaternion(double real, Vector3D vec)
 {
     this._r = real;
     this._v = vec;
 }
コード例 #14
0
ファイル: Quaternion.cs プロジェクト: DigNative/MSISF
 /// <summary>
 ///     Constructor for a quaternion defined by four single double values.
 /// </summary>
 /// <param name="real">real part</param>
 /// <param name="x">x-component of the vector part</param>
 /// <param name="y">y-component of the vector part</param>
 /// <param name="z">z-component of the vector part</param>
 public Quaternion(double real, double x, double y, double z)
 {
     this._r = real;
     this._v = new Vector3D(x, y, z);
 }