예제 #1
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;
                }
            }
        }
예제 #2
0
        public virtual void ResolveGravitation(IPhysicsBody other)
        {
            DVector2 difference = other.Position - Position;

            double r2 = difference.LengthSquared();

            double massDistanceRatio = other.Mass / r2;

            // Ignore the force, the planet is too far away to matter
            if (massDistanceRatio < 2500)
            {
                return;
            }

            difference.Normalize();

            // Gravitation ( aG = G m1 / r^2 )
            AccelerationG += difference * Constants.GravitationConstant * massDistanceRatio;
        }
예제 #3
0
        // Gets bodies sorted by distance that point the direction of the camera normal
        private static List <Tuple <double, int> > GetSortedBodyDistances(int currentIndex, IList <IGravitationalBody> bodies, DVector2 cameraNormal)
        {
            DVector2 targetCenter = bodies[currentIndex].Position;

            var bodiesByDistance = new List <Tuple <double, int> >();

            for (int i = 0; i < bodies.Count; i++)
            {
                if (i == currentIndex)
                {
                    continue;
                }

                var spaceCraft = bodies[i] as ISpaceCraft;

                // Skip terminated bodies
                if (spaceCraft != null && spaceCraft.Terminated)
                {
                    continue;
                }

                DVector2 difference = bodies[i].Position - targetCenter;

                double distance = difference.LengthSquared();

                difference.Normalize();

                // Only add bodies in the same direction as the camera normal
                if (difference.Dot(cameraNormal) > 0)
                {
                    bodiesByDistance.Add(new Tuple <double, int>(distance, i));
                }
            }

            bodiesByDistance.Sort(Compare);

            return(bodiesByDistance);
        }
        private static List <Tuple <double, int> > GetSortedBodyDistances(int currentIndex, IList <IGravitationalBody> bodies)
        {
            DVector2 targetCenter = bodies[currentIndex].Position;

            var bodiesByDistance = new List <Tuple <double, int> >();

            for (int i = 0; i < bodies.Count; i++)
            {
                if (i == currentIndex)
                {
                    continue;
                }

                DVector2 difference = targetCenter - bodies[i].Position;

                double distance = difference.LengthSquared();

                bodiesByDistance.Add(new Tuple <double, int>(distance, i));
            }

            bodiesByDistance.Sort(Compare);

            return(bodiesByDistance);
        }
예제 #5
0
        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;

                    AccelerationY = new DVector2(0, 0);
                }
                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
                    double qConv = 1.83e-4 * Math.Pow(speed, 3) * Math.Sqrt(atmosphericDensity / (Width * 0.5));
                    double qRad  = 3.2e-22 * Math.Pow(speed, 8) * Math.Pow(atmosphericDensity, 1.2) * Math.Sqrt((Width * 0.5));
                    HeatingRate = qConv + qRad;

                    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();
                    double turnTerm = 0;
                    if (Settings.Default.UseTheTurnForce)
                    {
                        turnTerm  = liftTerm * Math.Sin(Roll);
                        liftTerm *= Math.Cos(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);

                    AccelerationD = drag / Mass;
                    DVector2 accelerationLift = lift / Mass;

                    double alpha        = GetAlpha();
                    double halfPi       = Math.PI / 2;
                    bool   isRetrograde = alpha > halfPi || alpha < -halfPi;

                    if (Settings.Default.UseTheTurnForce && isRetrograde)
                    {
                        AccelerationL.X -= accelerationLift.Y;
                        AccelerationL.Y += accelerationLift.X;
                    }
                    else
                    {
                        AccelerationL.X += accelerationLift.Y;
                        AccelerationL.Y -= accelerationLift.X;
                    }
                }
            }
            else
            {
                HeatingRate = 0;
            }
        }
예제 #6
0
        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 velocity        = relativeVelocity.Length();
                double velocitySquared = relativeVelocity.LengthSquared();

                if (velocitySquared > 0)
                {
                    double speed = relativeVelocity.Length();

                    // Heating
                    HeatingRate = 1.83e-4 * Math.Pow(speed, 3) * Math.Sqrt(atmosphericDensity / (Width * 0.5));

                    relativeVelocity.Normalize();

                    double dragTerm = TotalDragCoefficient() * TotalDragArea();

                    // Drag ( Fd = 0.5pv^2dA )
                    DVector2 dragForce = relativeVelocity * (0.5 * atmosphericDensity * velocitySquared * dragTerm);

                    AccelerationD += dragForce / Mass;

                    double reynoldsNumber = (velocity * Height) / body.GetAtmosphericViscosity(altitude);

                    double frictionCoefficient = 0.455 / Math.Pow(Math.Log10(reynoldsNumber), 2.58);

                    double frictionTerm = frictionCoefficient * TotalSurfaceArea();

                    // Skin friction ( Fs = 0.5CfpV^2S )
                    DVector2 skinFriction = relativeVelocity * (0.5 * atmosphericDensity * velocitySquared * frictionTerm);

                    AccelerationD += skinFriction / Mass;
                }
            }
            else
            {
                HeatingRate = 0;
            }
        }
예제 #7
0
파일: MathOps.cs 프로젝트: vimaec/ara3d-dev
 [MethodImpl(MethodImplOptions.AggressiveInlining)] public static double Length(this DVector2 v) => v.LengthSquared().Sqrt();