예제 #1
0
        public GridFin(ISpaceCraft parent, DVector2 offset, int block, bool isLeft)
            : base(parent, GenerateTexturePath(block, isLeft))
        {
            if (block == 6)
            {
                Width  = 2.4;
                Height = 4.0;
            }
            else if (block == 5)
            {
                Width  = 1.3;
                Height = 2.0;
            }
            else
            {
                Width  = 1.2192;
                Height = 1.79806518;
            }

            DrawingOffset = 0.6;

            _isLeft = isLeft;

            _offsetLength   = offset.Length();
            _offsetRotation = offset.Angle() - Constants.PiOverTwo;
        }
예제 #2
0
        private void ComputeCachedProperties()
        {
            DVector2 difference = GravitationalParent.Position - Position;

            double totalDistance = difference.Length() - TotalHeight * 0.5;

            _cachedAltitude = totalDistance - GravitationalParent.SurfaceRadius;

            double altitude = GetRelativeAltitude();

            if (altitude > GravitationalParent.AtmosphereHeight)
            {
                _cachedRelativeVelocity = Velocity - GravitationalParent.Velocity;
            }
            else
            {
                difference.Normalize();

                var surfaceNormal = new DVector2(-difference.Y, difference.X);

                double altitudeFromCenter = altitude + GravitationalParent.SurfaceRadius;

                // Distance of circumference at this altitude ( c= 2r * pi )
                double pathCirumference = 2 * Math.PI * altitudeFromCenter;

                double rotationalSpeed = pathCirumference / GravitationalParent.RotationPeriod;

                _cachedRelativeVelocity = Velocity - (GravitationalParent.Velocity + surfaceNormal * rotationalSpeed);
            }
        }
예제 #3
0
        public static List <ISpaceCraft> BuildSpaceCraft(IMassiveBody planet, double surfaceAngle, MissionConfig config, string craftDirectory)
        {
            if (string.IsNullOrEmpty(config.VehicleType))
            {
                throw new Exception("Must specify a vehicle type in the MissionConfig.xml!");
            }

            if (string.IsNullOrEmpty(config.ParentPlanet))
            {
                throw new Exception("Must specify a parent planet for the launch vehicle!");
            }

            var planetOffset = new DVector2(Math.Cos(surfaceAngle) * planet.SurfaceRadius,
                                            Math.Sin(surfaceAngle) * planet.SurfaceRadius);

            List <ISpaceCraft> spaceCrafts = GenerateSpaceCraft(planet, config, craftDirectory);

            if (spaceCrafts.Count == 0)
            {
                throw new Exception("No spacecrafts produced!");
            }

            ISpaceCraft primaryCraft = spaceCrafts[0];

            DVector2 distanceFromSurface = primaryCraft.Position - planet.Position;

            // If the ship is spawned on the planet update it's position to the correct surface angle
            if (distanceFromSurface.Length() * 0.999 < planet.SurfaceRadius)
            {
                primaryCraft.SetSurfacePosition(planet.Position + planetOffset, surfaceAngle);
            }

            return(spaceCrafts);
        }
예제 #4
0
        protected virtual void RenderAbove(Graphics graphics, Camera camera)
        {
            if (EntryFlame != null)
            {
                EntryFlame.Draw(graphics, camera);
            }

            // Only show the vectors when it's requested and the craft is not parented
            if (_showDisplayVectors && Parent == null)
            {
                // The length of the vector is based on the width of the camera bounds
                float lengthFactor = (float)(camera.Bounds.Width * 0.1);

                PointF start = RenderUtils.WorldToScreen(Position, camera.Bounds);

                DVector2 relativeVelocity = GetRelativeVelocity();

                // Only draw the velocity vector when it can be normalized
                if (relativeVelocity.Length() > 0)
                {
                    relativeVelocity.Normalize();

                    PointF velocityEnd = RenderUtils.WorldToScreen(Position + relativeVelocity * lengthFactor, camera.Bounds);

                    graphics.DrawLine(Pens.White, start, velocityEnd);
                }

                DVector2 pitchVector = DVector2.FromAngle(Pitch);
                pitchVector.Normalize();

                PointF pitchEnd = RenderUtils.WorldToScreen(Position + pitchVector * lengthFactor, camera.Bounds);

                graphics.DrawLine(Pens.Red, start, pitchEnd);
            }
        }
예제 #5
0
        // Find the parent body for each massive body
        private void ResolveMassiveBodyParents()
        {
            foreach (IMassiveBody bodyA in _massiveBodies)
            {
                double bestMassDistanceRatio = double.MaxValue;

                foreach (IMassiveBody bodyB in _massiveBodies)
                {
                    if (bodyA == bodyB)
                    {
                        continue;
                    }

                    double massRatio = Math.Pow(bodyA.Mass / bodyB.Mass, 0.45);

                    DVector2 difference = bodyA.Position - bodyB.Position;

                    double massDistanceRatio = massRatio * difference.Length();

                    // New parent
                    if (massDistanceRatio < bestMassDistanceRatio)
                    {
                        bodyA.SetGravitationalParent(bodyB);

                        bestMassDistanceRatio = massDistanceRatio;
                    }
                }
            }
        }
예제 #6
0
        public override void Update(double dt)
        {
            base.Update(dt);

            foreach (GridFin gridFin in _gridFins)
            {
                gridFin.Update(dt);
            }

            foreach (LandingLeg landingLeg in _landingLegs)
            {
                landingLeg.Update(dt);
            }

            DVector2 velocity = GetRelativeVelocity();
            double   altitude = GetRelativeAltitude();

            DVector2 normalizedVelocity = velocity.Clone();

            normalizedVelocity.Normalize();

            DVector2 rotation = new DVector2(Math.Cos(Pitch), Math.Sin(Pitch));

            // If we are going retro-grade and firing rockets adds soot
            if (altitude < 70000 && normalizedVelocity.Dot(rotation) < 0 && velocity.Length() > 400)
            {
                foreach (IEngine engine in Engines)
                {
                    if (engine.IsActive && engine.Throttle > 0)
                    {
                        _sootRatio = Math.Min(_sootRatio + 0.015 * dt, 1.0);
                    }
                }
            }
        }
예제 #7
0
        public double GetRelativeHeight(DVector2 position)
        {
            DVector2 difference = Position - position;

            double totalDistance = difference.Length();

            return(totalDistance - _proxy.SurfaceRadius);
        }
예제 #8
0
        /// <summary>
        /// Gets the relative altitude of the spacecraft from it's parent's surface.
        /// </summary>
        public override double GetRelativeAltitude()
        {
            DVector2 difference = Position - GravitationalParent.Position;

            double totalDistance = difference.Length();

            return(totalDistance - GravitationalParent.SurfaceRadius);
        }
예제 #9
0
        public SSGridFin(ISpaceCraft parent, DVector2 offset, bool isLeft)
            : base(parent, GenerateTexturePath(isLeft))
        {
            _isLeft = isLeft;

            _offsetLength   = offset.Length();
            _offsetRotation = offset.Angle() - Constants.PiOverTwo;
        }
예제 #10
0
        public LandingLeg(ISpaceCraft parent, DVector2 offset, int block, bool isLeft)
            : base(parent, GenerateTexturePath(block, isLeft))
        {
            _isLeft = isLeft;

            _offsetLength   = offset.Length();
            _offsetRotation = offset.Angle() - Constants.PiOverTwo;
        }
예제 #11
0
        public NGLandingLeg(ISpaceCraft parent, DVector2 offset, bool isLeft)
            : base(parent, GenerateTexturePath(isLeft))
        {
            _parent = parent;
            _isLeft = isLeft;

            _offsetLength = -offset.Length();
            _offsetRotation = offset.Angle() + Math.PI / 2.0;
        }
예제 #12
0
        public void AddPoint(DVector2 point, IMassiveBody parentBody, bool isPowered)
        {
            DVector2 offset = point - parentBody.Position;

            _trailAngles.Add(offset.Angle() - parentBody.Pitch);
            _trailDistances.Add(offset.Length());

            _trailPowered.Add(isPowered);
        }
예제 #13
0
        public DrogueChute(ISpaceCraft parent, DVector2 offset)
        {
            _parent = parent;

            _offsetLength   = offset.Length();
            _offsetRotation = _offsetRotation = offset.Angle() - Math.PI / 2.0;

            _texture = new Bitmap("Textures/Spacecrafts/Falcon/Common/drogueChute.png");
        }
예제 #14
0
파일: EngineBase.cs 프로젝트: ap0r/SpaceSim
        protected EngineBase(ISpaceCraft parent, DVector2 offset, EngineFlame flame)
        {
            _parent = parent;

            _offsetLength   = offset.Length();
            _offsetRotation = offset.Angle() - Math.PI / 2.0;

            _engineFlame = flame;
        }
예제 #15
0
        protected EngineBase(ISpaceCraft parent, DVector2 offset, Plume plume)
        {
            Parent = parent;
            Offset = offset;

            _offsetLength   = offset.Length();
            _offsetRotation = offset.Angle() - Math.PI / 2.0;

            _plume = plume;
        }
예제 #16
0
        public ReEntryFlame(int maxParticles, double particleRate, DVector2 offset)
            : base(maxParticles, Color.FromArgb(50, 255, 255, 0))
        {
            _random = new Random();

            _particleRate = particleRate;

            _offsetAngle  = offset.Angle();
            _offsetLength = offset.Length();
        }
예제 #17
0
        public LandingLeg(ISpaceCraft parent, DVector2 offset, bool isLeft)
        {
            _parent = parent;
            _isLeft = isLeft;

            _offsetLength   = offset.Length();
            _offsetRotation = _offsetRotation = offset.Angle() - Math.PI / 2.0;

            _texture = isLeft ? new Bitmap("Textures/landingLegLeft.png") : new Bitmap("Textures/landingLegRight.png");
        }
예제 #18
0
        public GridFin(ISpaceCraft parent, DVector2 offset, bool isLeft)
        {
            _parent = parent;
            _isLeft = isLeft;

            _offsetLength   = offset.Length();
            _offsetRotation = _offsetRotation = offset.Angle() - Math.PI / 2.0;

            _texture = isLeft ? new Bitmap("Textures/Spacecrafts/Falcon/Common/gridFinLeft.png") :
                       new Bitmap("Textures/Spacecrafts/Falcon/Common//gridFinRight.png");
        }
예제 #19
0
        public void ResolveAtmopsherics(IMassiveBody body)
        {
            DVector2 difference = body.Position - Position;

            double distance = difference.Length();

            difference.Normalize();

            double altitude = distance - body.SurfaceRadius;

            // The object is in the atmosphere of body B
            if (altitude < body.AtmosphereHeight)
            {
                var surfaceNormal = new DVector2(-difference.Y, difference.X);

                double altitudeFromCenter = altitude + body.SurfaceRadius;

                // Distance of circumference at this altitude ( c= 2r * pi )
                double pathCirumference = 2 * Math.PI * altitudeFromCenter;

                double rotationalSpeed = pathCirumference / body.RotationPeriod;

                // Simple collision detection
                if (altitude <= 0)
                {
                    var normal = new DVector2(-difference.X, -difference.Y);

                    Position = body.Position + normal * (body.SurfaceRadius);

                    Velocity = (body.Velocity + surfaceNormal * rotationalSpeed);

                    Rotation = normal.Angle();

                    AccelerationN.X = -AccelerationG.X;
                    AccelerationN.Y = -AccelerationG.Y;
                }

                double atmosphericDensity = body.GetAtmosphericDensity(altitude);

                DVector2 relativeVelocity = (body.Velocity + surfaceNormal * rotationalSpeed) - Velocity;

                double velocityMagnitude = relativeVelocity.LengthSquared();

                if (velocityMagnitude > 0)
                {
                    relativeVelocity.Normalize();

                    // Drag ( Fd = 0.5pv^2dA )
                    DVector2 dragForce = relativeVelocity * (0.5 * atmosphericDensity * velocityMagnitude * DragCoefficient * CrossSectionalArea);

                    AccelerationD += dragForce / Mass;
                }
            }
        }
예제 #20
0
        protected StructureBase(DVector2 relativePosition, string texturePath, IMassiveBody parent)
        {
            _parent = parent;

            _initialDistance = relativePosition.Length();

            _rotationOffset  = relativePosition.Angle();
            _initialRotation = parent.Rotation;

            _texture = new Bitmap(texturePath);
        }
예제 #21
0
파일: Skid.cs 프로젝트: tdandrade/SpaceSim
        public Skid(ISpaceCraft parent, DVector2 offset, bool isLeft)
        {
            _parent = parent;
            _isLeft = isLeft;

            _offsetLength   = -offset.Length();
            _offsetRotation = offset.Angle() + Math.PI / 2.0;

            _texture = isLeft ? new Bitmap("Textures/Spacecrafts/NewGlenn/landingLegLeft.png") :
                       new Bitmap("Textures/Spacecrafts/NewGlenn/landingLegRight.png");
        }
예제 #22
0
        public Parachute(ISpaceCraft parent, DVector2 offset)
        {
            _parent = parent;

            _offsetLength   = offset.Length();
            _offsetRotation = offset.Angle();

            //Pitch = -Math.PI / 2.0;
            Pitch = Math.PI / 2.0 + Math.PI / 12.0;

            _texture = new Bitmap("Textures/Spacecrafts/Falcon/Common/parachutes.png");
        }
예제 #23
0
        private void ResolveGravitionalParents()
        {
            // Find the parent body for each massive body
            foreach (IMassiveBody bodyA in _massiveBodies)
            {
                double bestMassDistanceRatio = double.MaxValue;

                foreach (IMassiveBody bodyB in _massiveBodies)
                {
                    if (bodyA == bodyB)
                    {
                        continue;
                    }

                    double massRatio = Math.Pow(bodyA.Mass / bodyB.Mass, 0.45);

                    DVector2 difference = bodyA.Position - bodyB.Position;

                    double massDistanceRatio = massRatio * difference.Length();

                    // New parent
                    if (massDistanceRatio < bestMassDistanceRatio)
                    {
                        bodyA.SetGravitationalParent(bodyB);

                        bestMassDistanceRatio = massDistanceRatio;
                    }
                }
            }

            // Find the parent for each space craft
            foreach (ISpaceCraft spaceCraft in _spaceCrafts)
            {
                double bestMassDistanceRatio = double.MaxValue;

                foreach (IMassiveBody bodyB in _massiveBodies)
                {
                    double massRatio = Math.Pow(spaceCraft.Mass / bodyB.Mass, 0.45);

                    DVector2 difference = spaceCraft.Position - bodyB.Position;

                    double massDistanceRatio = massRatio * difference.Length();

                    // New parent
                    if (massDistanceRatio < bestMassDistanceRatio)
                    {
                        spaceCraft.SetGravitationalParent(bodyB);

                        bestMassDistanceRatio = massDistanceRatio;
                    }
                }
            }
        }
예제 #24
0
        // Finds the orbtial delta time step by assuming 200 points along the oribtal cirumference
        private static double GetOrbitalDt(DVector2 positon, DVector2 velocity, out double terminationRadius)
        {
            double orbitalAltitude = positon.Length();

            double approximateOrbitDiameter = orbitalAltitude * 2 * Math.PI;

            // Terminate the trace if it comes within 1/100 of starting point
            terminationRadius = approximateOrbitDiameter * 0.01;

            double approximateOrbitPeriod = approximateOrbitDiameter / velocity.Length();

            return(approximateOrbitPeriod * 0.005);
        }
예제 #25
0
        public virtual void UpdateChildren(DVector2 position, DVector2 velocity)
        {
            Position = position - new DVector2(StageOffset.X * Math.Sin(Rotation) + StageOffset.Y * Math.Cos(Rotation),
                                               -StageOffset.X * Math.Cos(Rotation) + StageOffset.Y * Math.Sin(Rotation));
            Velocity.X = velocity.X;
            Velocity.Y = velocity.Y;

            MachNumber = velocity.Length() * 0.0029411764;

            foreach (ISpaceCraft child in Children)
            {
                child.UpdateChildren(Position, Velocity);
            }
        }
예제 #26
0
파일: Smoke.cs 프로젝트: LamidD/SpaceSim-1
        public void Update(TimeStep timeStep, DVector2 enginePosition, DVector2 shipVelocity, DVector2 retrogradeVelocity, double density, double sootRatio)
        {
            int particles = (int)((sootRatio * shipVelocity.Length() * 0.001) / timeStep.UpdateLoops);

            if (density < 0.2 || density > 0.7)
            {
                particles = 0;
            }

            // Add new particles if nessecary
            for (int i = 0; i < particles; i++)
            {
                if (_availableParticles.Count > 0)
                {
                    var randomUnitVector = new DVector2(_random.NextDouble(), _random.NextDouble());

                    DVector2 velocity = shipVelocity.Clone();

                    int id = _availableParticles.Dequeue();

                    Particle particle = _particles[id];

                    particle.IsActive = true;
                    particle.Age      = 0;
                    particle.MaxAge   = _random.NextDouble() + 1;

                    particle.Position = enginePosition.Clone() + randomUnitVector * 2;
                    particle.Velocity = velocity + retrogradeVelocity * 0.5 + randomUnitVector * 2;
                }
            }

            // Update the particles
            for (int i = 0; i < _particles.Length; i++)
            {
                Particle particle = _particles[i];

                if (particle.IsActive)
                {
                    particle.Position += particle.Velocity * timeStep.Dt;
                    particle.Age      += timeStep.Dt;

                    if (particle.Age > particle.MaxAge)
                    {
                        particle.IsActive = false;
                        _availableParticles.Enqueue(i);
                    }
                }
            }
        }
예제 #27
0
        public virtual void UpdateChildren(DVector2 position, DVector2 velocity)
        {
            var rotationOffset = new DVector2(Math.Cos(Pitch), Math.Sin(Pitch));

            Position = position - new DVector2(StageOffset.X * rotationOffset.Y + StageOffset.Y * rotationOffset.X,
                                               -StageOffset.X * rotationOffset.X + StageOffset.Y * rotationOffset.Y);
            Velocity.X = velocity.X;
            Velocity.Y = velocity.Y;

            MachNumber = velocity.Length() * 0.0029411764;

            foreach (ISpaceCraft child in Children)
            {
                child.UpdateChildren(Position, Velocity);
            }
        }
예제 #28
0
        public Parachute(ISpaceCraft parent, DVector2 offset, bool isLeft)
        {
            _parent = parent;

            _offsetLength   = offset.Length();
            _offsetRotation = offset.Angle() - Math.PI / 2.0;

            if (isLeft)
            {
                _texture = new Bitmap("Textures/Spacecrafts/Falcon/Common/parachuteLeft.png");
            }
            else
            {
                _texture = new Bitmap("Textures/Spacecrafts/Falcon/Common/parachuteRight.png");
            }
        }
예제 #29
0
파일: Fin.cs 프로젝트: stauders/SpaceSim
        public Fin(ISpaceCraft parent, DVector2 offset, DVector2 size, double dihedral = 0.0, string texturePath = "Textures/Spacecrafts/ITS/Fin.png")
            : base(parent, texturePath)
        {
            _width  = size.X;
            _height = size.Y;

            Width  = _width;
            Height = _height;

            Dihedral = dihedral;

            DrawingOffset = 0.0;

            _offsetLength   = offset.Length();
            _offsetRotation = offset.Angle() - Constants.PiOverTwo;
        }
예제 #30
0
        /// <summary>
        /// Traces a massive body orbit by re-centering the world around the parent.
        /// </summary>
        public static OrbitTrace TraceMassiveBody(MassiveBodyBase body)
        {
            IMassiveBody parent = body.GravitationalParent;

            DVector2 initialPosition = body.Position - parent.Position;

            var proxyParent    = new MassiveBodyProxy(DVector2.Zero, DVector2.Zero, parent);
            var proxySatellite = new MassiveBodyProxy(initialPosition, body.Velocity - parent.Velocity, body);

            double orbitalTerminationRadius;
            double altitude = body.GetRelativeAltitude();

            double orbitalDt = GetOrbitalDt(initialPosition, proxySatellite.Velocity, out orbitalTerminationRadius);

            var trace = new OrbitTrace(body.Position, altitude);

            for (int i = 0; i < 300; i++)
            {
                proxySatellite.ResetAccelerations();

                proxySatellite.ResolveGravitation(proxyParent);

                proxySatellite.Update(orbitalDt);

                altitude = proxyParent.GetRelativeHeight(proxySatellite.Position);

                // Check expensive termination conditions after half of the iterations
                if (i > 150)
                {
                    DVector2 offsetVector = proxySatellite.Position - initialPosition;

                    double distanceFromStart = offsetVector.Length();

                    // Terminate and add the end point
                    if (distanceFromStart < orbitalTerminationRadius)
                    {
                        trace.AddPoint(proxySatellite.Position + parent.Position, altitude);
                        break;
                    }
                }

                trace.AddPoint(proxySatellite.Position + parent.Position, altitude);
            }

            return(trace);
        }