protected EngineBase(int id, ISpaceCraft parent, DVector2 offset, EngineFlame flame) { _parent = parent; _offsetLength = offset.Length(); _offsetRotation = offset.Angle() - Math.PI / 2.0; _engineFlame = flame; }
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"); }
protected StructureBase(DVector2 relativePosition, string texturePath, IMassiveBody parent) { _parent = parent; _initialDistance = relativePosition.Length(); _rotationOffset = relativePosition.Angle(); _initialRotation = parent.Rotation; _texture = new Bitmap(texturePath); }
public ReEntryFlame(int maxParticles, double particleRate, DVector2 offset) { _random = new Random(); _particles = new Particle[maxParticles]; _availableParticles = new Queue<int>(maxParticles); for (int i = 0; i < maxParticles; i++) { _particles[i] = new Particle(); _availableParticles.Enqueue(i); } _particleRate = particleRate; _offsetAngle = offset.Angle(); _offsetLength = offset.Length(); }
public void ResolveAtmopsherics(IMassiveBody body) { // Don't resolve drag for children if (Parent != null) return; DVector2 difference = body.Position - Position; double distance = difference.Length(); difference.Normalize(); double altitude = distance - body.SurfaceRadius; // The spacecraft is in the bodies atmopshere 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(); double dragTerm = TotalDragCoefficient() * TotalDragArea(); // Drag ( Fd = 0.5pv^2dA ) DVector2 dragForce = relativeVelocity * (0.5 * atmosphericDensity * velocityMagnitude * dragTerm); AccelerationD += dragForce / Mass; } } }
public void ResolveAtmopsherics(IMassiveBody body) { DVector2 difference = body.Position - Position; double distance = difference.Length() - Height * 0.5; difference.Normalize(); 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); Pitch = normal.Angle(); AccelerationN.X = -AccelerationG.X; AccelerationN.Y = -AccelerationG.Y; OnGround = true; } else { OnGround = false; } double atmosphericDensity = body.GetAtmosphericDensity(Altitude); RelativeVelocity = (body.Velocity + surfaceNormal * rotationalSpeed) - Velocity; double velocityMagnitude = RelativeVelocity.LengthSquared(); if (velocityMagnitude > 0) { DVector2 normalizedRelativeVelocity = RelativeVelocity.Clone(); normalizedRelativeVelocity.Normalize(); double formDragTerm = FormDragCoefficient * FrontalArea; double skinFrictionTerm = SkinFrictionCoefficient * ExposedSurfaceArea; double dragTerm = formDragTerm + skinFrictionTerm; // Drag ( Fd = 0.5pv^2dA ) DVector2 dragForce = normalizedRelativeVelocity * (0.5 * atmosphericDensity * velocityMagnitude * dragTerm); AccelerationD = dragForce / Mass; } } }
public void SetRelativePitch(double pitch) { double altitude = GetRelativeAltitude(); if (altitude > GravitationalParent.AtmosphereHeight) { Pitch = GravitationalParent.Pitch + pitch; } else { DVector2 difference = GravitationalParent.Position - Position; difference.Normalize(); var surfaceNormal = new DVector2(difference.Y, difference.X); double normal = surfaceNormal.Angle(); if (double.IsNaN(normal)) Pitch = GravitationalParent.Pitch + pitch; else Pitch = GravitationalParent.Pitch + pitch - normal; } foreach (ISpaceCraft child in Children) { child.SetRelativePitch(pitch); } }
public void ResolveAtmopsherics(IMassiveBody body) { // Don't resolve drag for children if (Parent != null) return; DVector2 difference = body.Position - Position; double heightOffset = Children.Count > 0 ? TotalHeight - Height*0.5 : Height*0.5; double distance = difference.Length() - heightOffset; difference.Normalize(); double altitude = distance - body.SurfaceRadius; // The spacecraft is in the bodies atmopshere 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; // Rough metric for staying on ground from frame to frame if (altitude <= 0.0001) { _onGroundIterations = Math.Min(_onGroundIterations + 1, 10); } else { _onGroundIterations = Math.Max(_onGroundIterations - 1, 0); } // Simple collision detection if (_onGroundIterations > 5) { OnGround = true; var normal = new DVector2(-difference.X, -difference.Y); Position = body.Position + normal * (body.SurfaceRadius + heightOffset); Velocity = (body.Velocity + surfaceNormal*rotationalSpeed); Pitch = normal.Angle(); AccelerationN.X = -AccelerationG.X; AccelerationN.Y = -AccelerationG.Y; } else { OnGround = false; } double atmosphericDensity = body.GetAtmosphericDensity(altitude); DVector2 relativeVelocity = (body.Velocity + surfaceNormal * rotationalSpeed) - Velocity; double velocityMagnitude = relativeVelocity.LengthSquared(); if (velocityMagnitude > 0) { double speed = relativeVelocity.Length(); // Heating HeatingRate = 1.83e-4 * Math.Pow(speed, 3) * Math.Sqrt(atmosphericDensity / (Width * 0.5)); relativeVelocity.Normalize(); double formDragCoefficient = TotalFormDragCoefficient(); double skinFrictionCoefficient = TotalSkinFrictionCoefficient(); double liftCoefficient = TotalLiftCoefficient(); double formDragTerm = formDragCoefficient * TotalFormDragArea(); double skinFrictionTerm = skinFrictionCoefficient * TotalSkinFrictionArea(); double dragTerm = formDragTerm; if (!double.IsNaN(skinFrictionTerm)) dragTerm += skinFrictionTerm; double liftTerm = liftCoefficient * TotalLiftArea() * Math.Cos(Roll); double turnTerm = liftCoefficient * TotalLiftArea() * Math.Sin(Roll); // Form Drag ( Fd = 0.5pv^2dA ) // Skin friction ( Fs = 0.5CfpV^2S ) DVector2 drag = relativeVelocity * (0.5 * atmosphericDensity * velocityMagnitude * dragTerm); DVector2 lift = relativeVelocity * (0.5 * atmosphericDensity * velocityMagnitude * liftTerm); DVector2 turn = relativeVelocity * (0.5 * atmosphericDensity * velocityMagnitude * turnTerm); AccelerationD = drag / Mass; DVector2 accelerationLift = lift / Mass; DVector2 accelerationTurn = turn / Mass; double alpha = GetAlpha(); double halfPi = Math.PI / 2; bool isRetrograde = alpha > halfPi || alpha < -halfPi; if (isRetrograde) { AccelerationL.X -= accelerationLift.Y; AccelerationL.Y += accelerationLift.X; } else { AccelerationL.X += accelerationLift.Y; AccelerationL.Y -= accelerationLift.X; } if (DateTime.Now - timestamp > TimeSpan.FromSeconds(1)) { string filename = MissionName + ".csv"; if (!File.Exists(filename)) { File.AppendAllText(filename, "Altitude, Ma, Acceleration, alpha, roll, HeatingRate, dragTerm, liftTerm, turnTerm\r\n"); } timestamp = DateTime.Now; string contents = string.Format("{0:N3}, {1:N3}, {2:N3}, {3:N3}, {4:N3}, {5:N3}, {6:N3}, {7:N3}, {8:N3}\r\n", altitude / 1000, MachNumber * 10, GetRelativeAcceleration().Length() * 10, alpha * MathHelper.RadiansToDegrees, Roll * MathHelper.RadiansToDegrees, HeatingRate / 100000, dragTerm/10, liftTerm/10, turnTerm/10); File.AppendAllText(filename, contents); } } } else { HeatingRate = 0; } }
public override double GetRelativePitch() { double altitude = GetRelativeAltitude(); double relativePitch = Pitch - GravitationalParent.Pitch; if (altitude > GravitationalParent.AtmosphereHeight) { return relativePitch; } DVector2 difference = GravitationalParent.Position - Position; difference.Normalize(); var surfaceNormal = new DVector2(difference.Y, difference.X); double normal = surfaceNormal.Angle(); if (!double.IsNaN(normal)) { if (altitude > 0.1) { relativePitch += normal; } else { relativePitch = normal; } } return relativePitch; }