コード例 #1
0
ファイル: NavWindow.cs プロジェクト: Moth-Tolias/Pulsar4x
        void DisplayPhaseChangeMode()
        {
            ImGui.SliderAngle("PhaseAngle", ref _phaseAngleRadians);

            var manuvers = InterceptCalcs.OrbitPhasingManuvers(_currentKE, _sgp, _atDatetime, _phaseAngleRadians);


            double totalManuverDV = 0;

            foreach (var manuver in manuvers)
            {
                ImGui.Text(manuver.deltaV.Length() + "Δv");
                totalManuverDV += manuver.deltaV.Length();
                ImGui.Text("Seconds: " + manuver.timeInSeconds);
            }

            ImGui.Text("Total Δv");
            ImGui.SameLine();
            ImGui.Text("for all manuvers: " + Stringify.Velocity(totalManuverDV));



            if (ImGui.Button("Make it so"))
            {
                NewtonThrustCommand.CreateCommand(_orderEntity.FactionOwner, _orderEntity, _atDatetime, manuvers[0].deltaV);
                DateTime futureDate = _atDatetime + TimeSpan.FromSeconds(manuvers[1].timeInSeconds);
                NewtonThrustCommand.CreateCommand(_orderEntity.FactionOwner, _orderEntity, futureDate, manuvers[1].deltaV);
            }
        }
コード例 #2
0
        void InsertionCalcs()
        {
            OrbitDB targetOrbit = TargetEntity.Entity.GetDataBlob <OrbitDB>();

            (ECSLib.Vector3 position, DateTime eti)targetIntercept = InterceptCalcs.GetInterceptPosition(OrderingEntity.Entity, TargetEntity.Entity.GetDataBlob <OrbitDB>(), _departureDateTime);

            DateTime estArivalDateTime = targetIntercept.eti; //rough calc.

            /*
             * double x = (_radialDV * Math.Cos(_departureAngle)) - (_progradeDV * Math.Sin(_departureAngle));
             * double y = (_radialDV * Math.Sin(_departureAngle)) + (_progradeDV * Math.Cos(_departureAngle));
             */
            var    norm = Vectors.Vector2.Normalise(_departureOrbitalVelocity);
            double x    = norm.X * _radialDV;
            double y    = norm.Y * _progradeDV;

            _deltaV_MS = new ECSLib.Vector3(x, y, 0);

            var insertionVector2d = OrbitProcessor.GetOrbitalInsertionVector(_departureOrbitalVelocity, targetOrbit, estArivalDateTime);//_departureOrbitalVelocity - parentOrbitalVector;

            _insertionOrbitalVelocity = new ECSLib.Vector3(insertionVector2d.X, insertionVector2d.Y, 0);

            _insertionOrbitalVelocity += Distance.MToAU(_deltaV_MS);
            _insertionOrbitalSpeed     = _insertionOrbitalVelocity.Length();
            _insertionAngle            = Math.Atan2(_insertionOrbitalVelocity.Y, _insertionOrbitalVelocity.X);
            _moveWidget.SetArivalProgradeAngle(_insertionAngle);

            /*
             * var sgpCBAU = GameConstants.Science.GravitationalConstant * (_massCurrentBody + _massOrderingEntity) / 3.347928976e33;// (149597870700 * 149597870700 * 149597870700);
             * var ralPosCBAU = OrderingEntity.Entity.GetDataBlob<PositionDB>().RelativePosition_AU;
             * var smaCurrOrbtAU = OrderingEntity.Entity.GetDataBlob<OrbitDB>().SemiMajorAxis;
             * var velAU = OrbitProcessor.PreciseOrbitalVector(sgpCBAU, ralPosCBAU, smaCurrOrbtAU);
             */
        }
コード例 #3
0
ファイル: NavWindow.cs プロジェクト: Moth-Tolias/Pulsar4x
        void DisplayHohmannMode()
        {
            double mySMA  = _currentKE.SemiMajorAxis;
            float  smaMin = 1;
            float  smaMax = (float)OrbitProcessor.GetSOI_m(Entity.GetSOIParentEntity(_orderEntity));

            if (ImGui.Combo("Target Object", ref _selectedSibling, _siblingNames, _siblingNames.Length))
            {
                Entity selectedSib = _siblingEntities[_selectedSibling];
                if (selectedSib.HasDataBlob <OrbitDB>())
                {
                    _targetSMA = (float)_siblingEntities[_selectedSibling].GetDataBlob <OrbitDB>().SemiMajorAxis;
                }
                if (selectedSib.HasDataBlob <OrbitUpdateOftenDB>())
                {
                    _targetSMA = (float)_siblingEntities[_selectedSibling].GetDataBlob <OrbitUpdateOftenDB>().SemiMajorAxis;
                }
                if (selectedSib.HasDataBlob <NewtonMoveDB>())
                {
                    _targetSMA = (float)_siblingEntities[_selectedSibling].GetDataBlob <NewtonMoveDB>().GetElements().SemiMajorAxis;
                }
            }

            //TODO this should be radius from orbiting body not major axies.
            ImGui.SliderFloat("Target SemiMajorAxis", ref _targetSMA, smaMin, smaMax);
            var manuvers = InterceptCalcs.Hohmann2(_sgp, mySMA, _targetSMA);



            double totalManuverDV = 0;

            foreach (var manuver in manuvers)
            {
                ImGui.Text(manuver.deltaV.Length() + "Δv");
                totalManuverDV += manuver.deltaV.Length();
            }

            if (totalManuverDV > _totalDV)
            {
                ImGui.TextColored(new Vector4(0.9f, 0, 0, 1), "Total Δv for all manuvers: " + Stringify.Velocity(totalManuverDV));
            }
            else
            {
                ImGui.Text("Total Δv for all manuvers: " + Stringify.Velocity(totalManuverDV));
            }

            if (ImGui.Button("Make it so"))
            {
                NewtonThrustCommand.CreateCommand(_orderEntity.FactionOwner, _orderEntity, _atDatetime, manuvers[0].deltaV);
                DateTime futureDate = _atDatetime + TimeSpan.FromSeconds(manuvers[1].timeInSeconds);
                NewtonThrustCommand.CreateCommand(_orderEntity.FactionOwner, _orderEntity, futureDate, manuvers[1].deltaV);
            }
        }
コード例 #4
0
ファイル: OrbitTests.cs プロジェクト: UberWaffe/Pulsar4x
        public void TestIntercept()
        {
            double        myMass     = 10000;
            double        parentMass = 1.989e30; //solar mass.
            Game          game       = new Game();
            EntityManager mgr        = new EntityManager(game, false);

            BaseDataBlob[] parentblobs = new BaseDataBlob[3];
            parentblobs[0] = new PositionDB(mgr.ManagerGuid)
            {
                X = 0, Y = 0, Z = 0
            };
            parentblobs[1] = new MassVolumeDB()
            {
                Mass = parentMass
            };
            parentblobs[2] = new OrbitDB();
            Entity parentEntity = new Entity(mgr, parentblobs);

            Vector3 currentPos = new Vector3 {
                X = -0.77473184638034, Y = 0.967145228951685
            };
            Vector3 currentVelocity = new Vector3 {
                Y = Distance.KmToAU(40)
            };
            double nonNewtSpeed = Distance.KmToAU(283.018);

            Vector3 targetObjPosition = new Vector3 {
                X = 0.149246434443459, Y = -0.712107888348067
            };
            Vector3 targetObjVelocity = new Vector3 {
                Y = Distance.KmToAU(35)
            };


            double sgp = GameConstants.Science.GravitationalConstant * (parentMass + myMass) / 3.347928976e33;
            //KeplerElements ke = OrbitMath.KeplerFromVelocityAndPosition(sgp, targetObjPosition, targetObjVelocity);

            var currentDateTime = new DateTime(2000, 1, 1);

            OrbitDB targetOrbit = OrbitDB.FromVector(parentEntity, myMass, parentMass, sgp, targetObjPosition, targetObjVelocity, currentDateTime);



            var intercept = InterceptCalcs.GetInterceptPosition2(currentPos, nonNewtSpeed, targetOrbit, currentDateTime);

            var futurePos1 = Distance.AuToKm(OrbitProcessor.GetAbsolutePosition_AU(targetOrbit, intercept.Item2));

            var futurePos2 = Distance.AuToKm(intercept.Item1);



            Assert.AreEqual(futurePos1.Length(), futurePos2.Length(), 0.01);
            Assert.AreEqual(futurePos1.X, futurePos2.X, 0.01);
            Assert.AreEqual(futurePos1.Y, futurePos2.Y, 0.01);
            Assert.AreEqual(futurePos1.Z, futurePos2.Z, 0.01);
            var time = intercept.Item2 - currentDateTime;

            var distance   = (currentPos - intercept.Item1).Length();
            var distancekm = Distance.AuToKm(distance);

            var speed  = distance / time.TotalSeconds;
            var speed2 = distancekm / time.TotalSeconds;

            var distb   = nonNewtSpeed * time.TotalSeconds;
            var distbKM = Distance.AuToKm(distb);
            var timeb   = distance / nonNewtSpeed;

            Assert.AreEqual(nonNewtSpeed, speed, 1.0e-10);

            var dif = distancekm - distbKM;

            Assert.AreEqual(distancekm, distbKM, 0.25);
        }
コード例 #5
0
        public static void LaunchMissile(Entity launchingEntity, Entity targetEntity, double launchForce, OrdnanceDesign missileDesign, int count)
        {
            var     atDatetime       = launchingEntity.Manager.StarSysDateTime;
            var     parentPositionDB = launchingEntity.GetDataBlob <PositionDB>();
            Vector3 parentPosition   = parentPositionDB.AbsolutePosition_m;
            var     parentPosRal     = parentPositionDB.RelativePosition_m;
            var     tgtEntityOrbit   = targetEntity.GetDataBlob <OrbitDB>();

            if (targetEntity.HasDataBlob <OrbitUpdateOftenDB>())
            {
                tgtEntityOrbit = targetEntity.GetDataBlob <OrbitUpdateOftenDB>();
            }

            //MissileLauncherAtb launcherAtb;
            VolumeStorageDB cargo = launchingEntity.GetDataBlob <VolumeStorageDB>();

            int numMis = cargo.TypeStores[missileDesign.CargoTypeID].CurrentStoreInUnits[missileDesign.ID];

            if (numMis < 1)
            {
                return;
            }



            double launchSpeed = launchForce / missileDesign.MassPerUnit;

            double  burnTime        = ((missileDesign.WetMass - missileDesign.DryMass) / missileDesign.BurnRate) * 0.8; //use 80% of fuel.
            double  drymass         = (missileDesign.WetMass - missileDesign.DryMass) * 0.8;                            //use 80% of fuel.
            double  launchManuverDv = OrbitMath.TsiolkovskyRocketEquation(missileDesign.WetMass, drymass, missileDesign.ExaustVelocity);
            double  totalDV         = OrbitMath.TsiolkovskyRocketEquation(missileDesign.WetMass, missileDesign.DryMass, missileDesign.ExaustVelocity);
            double  speed           = launchSpeed + launchManuverDv;
            var     misslPositionDB = (PositionDB)parentPositionDB.Clone();
            Vector3 parentVelocity  = Entity.GetRalitiveFutureVelocity(launchingEntity, launchingEntity.StarSysDateTime);



            var orderabledb = new OrderableDB();
            var newtmovedb  = new NewtonMoveDB(misslPositionDB.Parent, parentVelocity);

            string defaultName  = "Missile";
            string factionsName = missileDesign.Name;

            if (count > 1)
            {
                defaultName  += " x" + count;
                factionsName += " x" + count;
            }

            List <BaseDataBlob> dataBlobs = new List <BaseDataBlob>();

            dataBlobs.Add(new ProjectileInfoDB(launchingEntity.Guid, count));
            dataBlobs.Add(new ComponentInstancesDB());
            dataBlobs.Add(misslPositionDB);
            dataBlobs.Add(MassVolumeDB.NewFromMassAndVolume(missileDesign.WetMass, missileDesign.WetMass));
            dataBlobs.Add(new NameDB(defaultName, launchingEntity.FactionOwner, factionsName));
            dataBlobs.Add(newtmovedb);
            dataBlobs.Add(orderabledb);
            var newMissile = Entity.Create(launchingEntity.Manager, launchingEntity.FactionOwner, dataBlobs);

            foreach (var tuple in missileDesign.Components)
            {
                EntityManipulation.AddComponentToEntity(newMissile, tuple.design, tuple.count);
            }

            var newtdb = newMissile.GetDataBlob <NewtonThrustAbilityDB>();

            newtdb.DryMass_kg = missileDesign.MassPerUnit;
            newtdb.SetFuel(missileDesign.WetMass - missileDesign.MassPerUnit);


            bool directAttack = false;


            if (directAttack)
            {
                /*
                 * var tgtintercept = OrbitMath.GetInterceptPosition_m(parentPosition, speed, tgtEntityOrbit, atDatetime);
                 * var tgtEstPos = tgtintercept.position + targetEntity.GetDataBlob<PositionDB>().RelativePosition_m;
                 *
                 * var tgtCurPos = Entity.GetPosition_m(targetEntity, atDatetime);
                 *
                 * var vectorToTgt = Vector3.Normalise(tgtCurPos - parentPosRal);
                 *
                 * //var vectorToTgt = Vector3.Normalise(tgtEstPos - parentPosRal);
                 * var launcherVector = vectorToTgt * launchSpeed;
                 *
                 *
                 * var launchVelocity = parentVelocity + launcherVector;
                 * var manuverDV = vectorToTgt * launchManuverDv;
                 *
                 * launchVelocity = parentVelocity + launcherVector;
                 */
                ThrustToTargetCmd.CreateCommand(launchingEntity.FactionOwner, newMissile, launchingEntity.StarSysDateTime, targetEntity);
            }
            else
            {
                var launchOrbit = launchingEntity.GetDataBlob <OrbitDB>();
                if (launchingEntity.HasDataBlob <OrbitUpdateOftenDB>())
                {
                    launchOrbit = launchingEntity.GetDataBlob <OrbitUpdateOftenDB>();
                }

                var launchTrueAnomaly = OrbitProcessor.GetTrueAnomaly(launchOrbit, atDatetime);
                var targetTrueAnomaly = OrbitProcessor.GetTrueAnomaly(tgtEntityOrbit, atDatetime);
                var phaseAngle        = targetTrueAnomaly - launchTrueAnomaly;
                var manuvers          = InterceptCalcs.OrbitPhasingManuvers(launchOrbit, atDatetime, phaseAngle);


                var manuverDV = manuvers[0].deltaV;
                //newtmovedb.ActionOnDateTime = atDatetime;
                //newtmovedb.DeltaVForManuver_FoRO_m = manuverDV;
                NewtonThrustCommand.CreateCommand(launchingEntity.FactionOwner, newMissile, atDatetime, manuverDV);

                DateTime futureDate = atDatetime + TimeSpan.FromSeconds(manuvers[1].timeInSeconds);
                Vector3  futureDV   = manuvers[1].deltaV;
                NewtonThrustCommand.CreateCommand(launchingEntity.FactionOwner, newMissile, futureDate, futureDV);
                //ThrustToTargetCmd.CreateCommand(launchingEntity.FactionOwner, newMissile, futureDate + TimeSpan.FromSeconds(1), targetEntity);
            }

            cargo.RemoveCargoByUnit(missileDesign, 1); //remove missile from parent.
        }