public static void TestVector3Distance()
    {
        Vector3d v1 = new Vector3d(0, 2, 3);
        Vector3d v2 = new Vector3d(1, 2, 3);
        Vector3d v3 = new Vector3d(4, 6, 3);

        double dist1 = v1.Distance(v2);
        dist1.ShouldBe(1);

        double dist2 = v2.Distance(v3);
        dist2.ShouldBe(5);
    }
示例#2
0
        public Vector3d[] GetBasis()
        {
            Vector3d[] shifts = new[] { Vector3d.UnitX, Vector3d.UnitY, Vector3d.UnitZ };
            Vector3d   axis1  = Vector3d.Zero;

            for (int i = 0; i < shifts.Length; i++)
            {
                var proj = ProjPoint(Position + shifts[i]);

                if (Vector3d.Distance(proj, Position) > 10e-6)
                {
                    axis1 = (proj - Position).Normalized();
                    break;
                }
            }
            var axis2 = Vector3d.Cross(Normal.Normalized(), axis1);

            return(new[] { axis1, axis2 });
        }
        public bool GlidePathInRange(Vessel vessel)
        {
            if (slantDistance <= 0.0 && beaconIndex >= 0)
            {
                Vector3d vesselPos = vessel.mainBody.GetRelSurfacePosition(vessel.CoMD);

                slantDistance = Vector3d.Distance(beacon[beaconIndex].worldPosition, vesselPos);
                vesselLoS     = Math.Sqrt(vessel.altitude * (2.0 * vessel.mainBody.Radius + vessel.altitude)) * MASConfig.navigation.generalPropagation;
            }

            if (isILS)
            {
                return(slantDistance < beacon[beaconIndex].maximumRangeGlidePath);
            }
            else
            {
                return(false);
            }
        }
示例#4
0
        /// <summary>
        /// Save move of a ship. We need to prevent hitting an active vessel.
        /// </summary>
        /// <param name="latitude"></param>
        /// <param name="longitude"></param>
        /// <returns>true if rover was moved, false otherwise</returns>
        private bool MoveSafely(double latitude, double longitude)
        {
            if (FlightGlobals.ActiveVessel != null)
            {
                Vector3d newPos   = vessel.mainBody.GetWorldSurfacePosition(latitude, longitude, 0);
                Vector3d actPos   = FlightGlobals.ActiveVessel.GetWorldPos3D();
                double   distance = Vector3d.Distance(newPos, actPos);
                if (distance <= 2400)
                {
                    return(false);
                }
            }

            vessel.latitude  = latitude;
            vessel.longitude = longitude;
            vessel.altitude  = vesselHeightFromTerrain;

            return(true);
        }
        private void ProxDetect()
        {
            mine = GetMine();
            if (!detonating)
            {
                foreach (Vessel v in FlightGlobals.Vessels)
                {
                    double targetDistance = Vector3d.Distance(this.vessel.GetWorldPos3D(), v.GetWorldPos3D());

                    if (targetDistance <= proximity)
                    {
                        if (targetDistance >= 0 && v.speed >= 1.5f)
                        {
                            StartCoroutine(DetonateMineRoutine());
                        }
                    }
                }
            }
        }
示例#6
0
        /// <summary>
        /// Checks if targetTransform is within range of the Observatory or not based on it's level
        /// </summary>
        /// <param name="targetTransform">target CB transform</param>
        /// <returns>true or false</returns>
        public static bool WithinObsRange(Transform targetTransform)
        {
            if (ResearchBodies_Observatory.spacecentertransform == null)
            {
                RSTUtils.RSTLogWriter.Log("Cannot determine range from Observatory as KSC transform is null");
                return(false);
            }
            //Calculate distance from Observatory to CB target body.
            Vector3 hostPos   = ResearchBodies_Observatory.spacecentertransform.position;
            Vector3 targetPos = targetTransform.position;
            //double angle = Vector3.Angle(targetPos - hostPos, ResearchBodies_Observatory.spacecentertransform.up);
            double distance = Vector3d.Distance(targetTransform.position, ResearchBodies_Observatory.spacecentertransform.position);

            //Get the current Observatory level and set the range of the Observatory from the database (settings).
            int obslevel = 1;

            for (int i = 0; i < PSystemSetup.Instance.SpaceCenterFacilities.Length; i++)
            {
                if (PSystemSetup.Instance.SpaceCenterFacilities[i].name == "Observatory")
                {
                    obslevel = Mathf.RoundToInt(ScenarioUpgradeableFacilities.GetFacilityLevel("Observatory") + 1);
                    break;
                }
            }
            double obsrange = 0;

            if (obslevel == 1)
            {
                obsrange = Database.instance.Observatorylvl1Range;
            }
            if (obslevel == 2)
            {
                obsrange = Database.instance.Observatorylvl2Range;
            }

            //If it's within range return true, otherwise false.
            if (distance <= obsrange)
            {
                return(true);
            }

            return(false);
        }
        void DrawGUIPrediction()
        {
            ReentrySimulation.Result result = predictor.GetResult();
            if (result != null)
            {
                switch (result.outcome)
                {
                case ReentrySimulation.Outcome.LANDED:
                    GUILayout.Label("Predicted landing site:");
                    GUILayout.Label(Coordinates.ToStringDMS(result.endPosition.latitude, result.endPosition.longitude));
                    double error = Vector3d.Distance(mainBody.GetRelSurfacePosition(result.endPosition.latitude, result.endPosition.longitude, 0),
                                                     mainBody.GetRelSurfacePosition(core.target.targetLatitude, core.target.targetLongitude, 0));
                    GUILayout.Label("Difference from target = " + MuUtils.ToSI(error, 0) + "m");
                    if (result.maxDragGees > 0)
                    {
                        GUILayout.Label("Predicted max drag gees: " + result.maxDragGees.ToString("F1"));
                    }
                    break;

                case ReentrySimulation.Outcome.AEROBRAKED:
                    GUILayout.Label("Predicted orbit after aerobraking:");
                    Orbit o = result.EndOrbit();
                    if (o.eccentricity > 1)
                    {
                        GUILayout.Label("Hyperbolic, eccentricity = " + o.eccentricity.ToString("F2"));
                    }
                    else
                    {
                        GUILayout.Label(MuUtils.ToSI(o.PeA, 3) + "m x " + MuUtils.ToSI(o.ApA, 3) + "m");
                    }
                    break;

                case ReentrySimulation.Outcome.NO_REENTRY:
                    GUILayout.Label("Orbit does not reenter:");
                    GUILayout.Label(MuUtils.ToSI(orbit.PeA, 3) + "m Pe > " + MuUtils.ToSI(mainBody.RealMaxAtmosphereAltitude(), 3) + "m atmosphere height");
                    break;

                case ReentrySimulation.Outcome.TIMED_OUT:
                    GUILayout.Label("Reentry simulation timed out.");
                    break;
                }
            }
        }
示例#8
0
        private bool CollapseDegenerateEdges(DMesh3 mesh,
                                             CancellationToken cancellationToken,
                                             double minLength,
                                             bool bBoundaryOnly,
                                             out int collapseCount)
        {
            collapseCount = 0;
            // don't iterate sequentially because there may be pathological cases
            foreach (int eid in MathUtil.ModuloIteration(mesh.MaxEdgeID))
            {
                cancellationToken.ThrowIfCancellationRequested();
                if (mesh.IsEdge(eid) == false)
                {
                    continue;
                }

                bool isBoundaryEdge = mesh.IsBoundaryEdge(eid);
                if (bBoundaryOnly && isBoundaryEdge == false)
                {
                    continue;
                }

                Index2i  ev = mesh.GetEdgeV(eid);
                Vector3d a = mesh.GetVertex(ev.a), b = mesh.GetVertex(ev.b);
                if (a.Distance(b) < minLength)
                {
                    int        keep    = mesh.IsBoundaryVertex(ev.a) ? ev.a : ev.b;
                    int        discard = (keep == ev.a) ? ev.b : ev.a;
                    MeshResult result  = mesh.CollapseEdge(keep, discard, out DMesh3.EdgeCollapseInfo collapseInfo);
                    if (result == MeshResult.Ok)
                    {
                        ++collapseCount;
                        if (mesh.IsBoundaryVertex(keep) == false || isBoundaryEdge)
                        {
                            mesh.SetVertex(keep, (a + b) * 0.5);
                        }
                    }
                }
            }

            return(true);
        }
示例#9
0
        private void updateDistance()
        {
            double     testDistance  = 0;
            double     lastDistance  = 0;
            ProxSensor closestSensor = null;

            //Set the last distance for the purpose of direction determination
            lastDistance = currentDistance;

            //Find closest target on our channel and set closestDistance
            foreach (var listener in ProxChannel.Listeners.ToList())
            {
                if (this.vessel.id != listener.vessel.id)
                {
                    testDistance = Vector3d.Distance(this.vessel.GetWorldPos3D(), listener.vessel.GetWorldPos3D());
                    //Set distance and listener to the values from the closest non-self sensor on the same channel as us
                    if (listener.channel == this.channel && (testDistance < currentDistance || closestSensor == null))
                    {
                        closestSensor   = listener;
                        currentDistance = testDistance;
                    }
                }
            }

            //If no sensors detected, proceed no further
            if (closestSensor == null)
            {
                return;
            }

            //Determine if the vessel is approaching or departing
            departing = (currentDistance < lastDistance ? false : true);

            //Update target window size based on current velocity relative to target
            //If the target was just registered (AKA just entered 2.5km), it's velocity measurements are innacurate. Manually set to 0 until next pass.
            currentWindow = (closestSensor.justRegistered ? 0 : Math.Abs(currentDistance - lastDistance) * 1.05);
            //We now have one data point. Remove the justRegistered flag for the next pass
            if (closestSensor.justRegistered)
            {
                MonoBehaviour.print(closestSensor.vessel.name + " inelligible for proximity detection this time. Waiting for next pass.");
            }
        }
示例#10
0
        // calculates regolith concentration - right now just based on the distance of the planet from the sun, so planets will have uniform distribution. We might add latitude as a factor etc.
        private static double CalculateRegolithConcentration(Vector3d planetPosition, Vector3d sunPosition, double altitude)
        {
            // if my reasoning is correct, this is not only the average distance of Kerbin, but also for the Mun.
            // Maybe this is obvious to everyone else or wrong, but I'm tired, so there.
            var avgMunDistance = GameConstants.KerbinSunDistance;

            /* I decided to incorporate an altitude modifier. According to https://curator.jsc.nasa.gov/lunar/letss/regolith.pdf, most regolith on Moon is deposited in
             * higher altitudes. This is great from a game play perspective, because it makes an incentive for players to collect regolith in more difficult circumstances
             * (i.e. landing on highlands instead of flats etc.) and breaks the flatter-is-better base building strategy at least a bit.
             * This check will divide current altitude by 2500. At that arbitrarily-chosen altitude, we should be getting the basic concentration for the planet.
             * Go to a higher terrain and you will find **more** regolith. The + 500 shift is there so that even at altitude of 0 (i.e. Minmus flats etc.) there will
             * still be at least SOME regolith to be mined.
             */
            var altModifier        = (altitude + 500) / 2500;
            var atmosphereModifier = Math.Pow(1 - FlightGlobals.currentMainBody.atmDensityASL, FlightGlobals.currentMainBody.atmosphereDepth * 0.001);

            var concentration = atmosphereModifier * altModifier * (avgMunDistance / Vector3d.Distance(planetPosition, sunPosition)); // get a basic concentration. Should range from numbers lower than one for planets further away from the sun, to about 2.5 at Moho

            return(concentration);
        }
示例#11
0
 //Adapted from KMP. Called from PlayerStatusWorker.
 public static bool isInSafetyBubble(Vector3d worldPos, CelestialBody body, double safetyBubbleDistance)
 {
     if (body == null)
     {
         return(false);
     }
     foreach (SafetyBubblePosition position in positions)
     {
         if (body.name == position.celestialBody)
         {
             Vector3d testPos  = body.GetWorldSurfacePosition(position.latitude, position.longitude, position.altitude);
             double   distance = Vector3d.Distance(worldPos, testPos);
             if (distance < safetyBubbleDistance)
             {
                 return(true);
             }
         }
     }
     return(false);
 }
        private void ProxDetect()
        {
            part.vessel.DiscoveryInfo.SetLevel(DiscoveryLevels.Unowned);
            mine = GetMine();
            if (!detonating)
            {
                foreach (Vessel v in FlightGlobals.Vessels)
                {
                    if (!v.HoldPhysics && v.speed >= 1.1f)
                    {
                        double targetDistance = Vector3d.Distance(this.vessel.GetWorldPos3D(), v.GetWorldPos3D());

                        if (targetDistance >= 0 && targetDistance <= proximity)
                        {
                            StartCoroutine(DetonateMineRoutine());
                        }
                    }
                }
            }
        }
示例#13
0
        //Tests if byBody occludes worldPosition, from the perspective of the planetarium camera
        public static bool IsOccluded(Vector3d worldPosition, CelestialBody byBody)
        {
            if (Vector3d.Distance(worldPosition, byBody.position) < byBody.Radius - 100)
            {
                return(true);
            }

            Vector3d camPos = ScaledSpace.ScaledToLocalSpace(PlanetariumCamera.Camera.transform.position);

            if (Vector3d.Angle(camPos - worldPosition, byBody.position - worldPosition) > 90)
            {
                return(false);
            }

            double bodyDistance    = Vector3d.Distance(camPos, byBody.position);
            double separationAngle = Vector3d.Angle(worldPosition - camPos, byBody.position - camPos);
            double altitude        = bodyDistance * Math.Sin(Math.PI / 180 * separationAngle);

            return(altitude < byBody.Radius);
        }
示例#14
0
 bool collapse_degenerate_edges(
     double minLength, bool bBoundaryOnly,
     out int collapseCount)
 {
     collapseCount = 0;
     // don't iterate sequentially because there may be pathological cases
     foreach (int eid in MathUtil.ModuloIteration(Mesh.MaxEdgeID))
     {
         if (Cancelled())
         {
             break;
         }
         if (Mesh.IsEdge(eid) == false)
         {
             continue;
         }
         bool is_boundary_edge = Mesh.IsBoundaryEdge(eid);
         if (bBoundaryOnly && is_boundary_edge == false)
         {
             continue;
         }
         Index2i  ev = Mesh.GetEdgeV(eid);
         Vector3d a = Mesh.GetVertex(ev.a), b = Mesh.GetVertex(ev.b);
         if (a.Distance(b) < minLength)
         {
             int keep    = Mesh.IsBoundaryVertex(ev.a) ? ev.a : ev.b;
             int discard = (keep == ev.a) ? ev.b : ev.a;
             DMesh3.EdgeCollapseInfo collapseInfo;
             MeshResult result = Mesh.CollapseEdge(keep, discard, out collapseInfo);
             if (result == MeshResult.Ok)
             {
                 ++collapseCount;
                 if (Mesh.IsBoundaryVertex(keep) == false || is_boundary_edge)
                 {
                     Mesh.SetVertex(keep, (a + b) * 0.5);
                 }
             }
         }
     }
     return(true);
 }
示例#15
0
        public void FixedUpdate()
        {
            if (HighLogic.LoadedSceneIsFlight)
            {
                if (!active)
                {
                    base.OnFixedUpdate();
                }

                if (solarPanel != null)
                {
                    double     inv_square_mult = Math.Pow(Vector3d.Distance(FlightGlobals.Bodies[PluginHelper.REF_BODY_KERBIN].transform.position, FlightGlobals.Bodies[PluginHelper.REF_BODY_KERBOL].transform.position), 2) / Math.Pow(Vector3d.Distance(vessel.transform.position, FlightGlobals.Bodies[PluginHelper.REF_BODY_KERBOL].transform.position), 2);
                    FloatCurve satcurve        = new FloatCurve();
                    satcurve.Add(0.0f, (float)inv_square_mult);
                    solarPanel.powerCurve = satcurve;

                    float solar_rate = solarPanel.flowRate * TimeWarp.fixedDeltaTime;
                    float clamper    = PluginHelper.isSolarPanelHeatingClamped() ?
                                       (float)Math.Min(Math.Max((Math.Sqrt(inv_square_mult) - 1.5), 0.0), 1.0) :
                                       1.0f;
                    float heat_rate = clamper * solar_rate * 0.5f / 1000.0f;

                    if (getResourceBarRatio(FNResourceManager.FNRESOURCE_WASTEHEAT) >= 0.98 && solarPanel.panelState == ModuleDeployableSolarPanel.panelStates.EXTENDED && solarPanel.sunTracking)
                    {
                        solarPanel.Retract();
                        if (FlightGlobals.ActiveVessel == vessel)
                        {
                            ScreenMessages.PostScreenMessage("Warning Dangerous Overheating Detected: Solar Panel retraction occuring NOW!", 5.0f, ScreenMessageStyle.UPPER_CENTER);
                        }
                        return;
                    }

                    List <PartResource> prl = part.GetConnectedResources("ElectricCharge").ToList();
                    double current_charge   = prl.Sum(pr => pr.amount);
                    double max_charge       = prl.Sum(pr => pr.maxAmount);

                    supplyFNResourceFixedMax(current_charge >= max_charge ? solar_rate / 1000.0f : 0, solar_rate / 1000.0f, FNResourceManager.FNRESOURCE_MEGAJOULES);
                    wasteheat_production_f = supplyFNResource(heat_rate, FNResourceManager.FNRESOURCE_WASTEHEAT) / TimeWarp.fixedDeltaTime * 1000.0f;
                }
            }
        }
        public static RadiationDose GetRadiationDose(this Vessel vessel)
        {
            CelestialBody cur_ref_body = vessel.mainBody;
            CelestialBody crefkerbin   = FlightGlobals.fetch.bodies[PluginHelper.REF_BODY_KERBIN];

            ORSPlanetaryResourcePixel res_pixel = ORSPlanetaryResourceMapData.getResourceAvailability(
                vessel.mainBody.flightGlobalsIndex,
                InterstellarResourcesConfiguration.Instance.ThoriumTetraflouride,
                cur_ref_body.GetLatitude(vessel.transform.position),
                cur_ref_body.GetLongitude(vessel.transform.position));

            double ground_rad = Math.Sqrt(res_pixel.getAmount() * 9e6) / 24 / 365.25 / Math.Max(vessel.altitude / 870, 1);

            double proton_rad         = cur_ref_body.GetProtonRadiationLevel(FlightGlobals.ship_altitude, FlightGlobals.ship_latitude);
            double electron_rad       = cur_ref_body.GetElectronRadiationLevel(FlightGlobals.ship_altitude, FlightGlobals.ship_latitude);
            double divisor            = Math.Pow(cur_ref_body.Radius / crefkerbin.Radius, 2.0);
            double proton_rad_level   = proton_rad / divisor;
            double electron_rad_level = electron_rad / divisor;

            double inv_square_mult    = Math.Pow(Vector3d.Distance(FlightGlobals.Bodies[PluginHelper.REF_BODY_KERBIN].transform.position, FlightGlobals.Bodies[PluginHelper.REF_BODY_KERBOL].transform.position), 2) / Math.Pow(Vector3d.Distance(vessel.transform.position, FlightGlobals.Bodies[PluginHelper.REF_BODY_KERBOL].transform.position), 2);
            double solar_radiation    = 0.19 * inv_square_mult;
            double mag_field_strength = cur_ref_body.GetBeltMagneticFieldMagnitude(FlightGlobals.ship_altitude, FlightGlobals.ship_latitude);

            while (cur_ref_body.referenceBody != null)
            {
                CelestialBody old_ref_body = cur_ref_body;
                cur_ref_body = cur_ref_body.referenceBody;
                if (cur_ref_body == old_ref_body)
                {
                    break;
                }
                mag_field_strength += cur_ref_body.GetBeltMagneticFieldMagnitude(Vector3d.Distance(FlightGlobals.ship_position, cur_ref_body.transform.position) - cur_ref_body.Radius, FlightGlobals.ship_latitude);
            }
            if (vessel.mainBody != FlightGlobals.fetch.bodies[PluginHelper.REF_BODY_KERBOL])
            {
                solar_radiation = solar_radiation * Math.Exp(-73840.5645666 * mag_field_strength) * Math.Exp(-vessel.atmDensity * 4.5);
            }
            RadiationDose dose = new RadiationDose(Math.Pow(electron_rad_level / 3e-5, 3.0) * 3.2, ground_rad, solar_radiation + Math.Pow(proton_rad_level / 3e-5, 3.0) * 3.2, 0.0);

            return(dose);
        }
        public void CalculateTargetLine()
        {
            // Selected target
            var target = FlightGlobals.fetch.VesselTarget;

            // If a target is selected...
            if (target != null)
            {
                orbitT = target.GetOrbit(); // Target orbit
                // Spacecraft relative position at UTf
                rFinalRel = orbitf.getRelativePositionAtUT(UTf).xzy;
                // Target relative position at UTf
                rTargetFinalRel = orbitT.getRelativePositionAtUT(UTf).xzy;
                // Distance to target at UTf
                targetD = Vector3d.Distance(rFinalRel, rTargetFinalRel);
                // Relative speed to target at UTf
                targetV = Vector3d.Distance(orbitf.getOrbitalVelocityAtUT(UTf), orbitT.getOrbitalVelocityAtUT(UTf));
                // Destroy current line if present
                if (lineT != null)
                {
                    UnityEngine.Object.Destroy(lineT);
                }
                // Make line to target at UTf
                var objT = new GameObject("Line to target");
                lineT = objT.AddComponent <LineRenderer>();
                lineT.useWorldSpace = false;
                objT.layer          = 10; // Map
                lineT.material      = MapView.fetch.orbitLinesMaterial;
                lineT.SetColors(Color.red, Color.red);
                lineT.SetVertexCount(2);

                // Target errors
                ApErr  = orbitf.ApR - orbitT.ApR;
                PeErr  = orbitf.PeR - orbitT.PeR;
                TPErr  = orbitf.period - orbitT.period;
                IncErr = orbitf.inclination - orbitT.inclination;
                EccErr = orbitf.eccentricity - orbitT.eccentricity;
                LANErr = orbitf.LAN - orbitT.LAN;
                AOPErr = orbitf.argumentOfPeriapsis - orbitT.argumentOfPeriapsis;
            }
        }
示例#18
0
 /// <summary>
 /// Returns the brightest star near the given body.
 /// </summary>
 public static KopernicusStar GetBrightest(CelestialBody body)
 {
     double greatestLuminosity = 0;
     KopernicusStar BrightestStar = GetNearest(body);
     for (Int32 i = 0; i < KopernicusStar.Stars.Count; i++)
     {
         KopernicusStar star = KopernicusStar.Stars[i];
         double distance = Vector3d.Distance(body.position, star.sun.position);
         double aparentLuminosity = 0;
         if (star.shifter.givesOffLight)
         {
             aparentLuminosity = star.shifter.solarLuminosity * (1 / (distance * distance));
         }
         if (aparentLuminosity > greatestLuminosity)
         {
             greatestLuminosity = aparentLuminosity;
             BrightestStar = star;
         }
     }
     return BrightestStar;
 }
示例#19
0
        /// <summary>
        /// Save move of a rover. We need to prevent hitting an active vessel.
        /// </summary>
        /// <param name="latitude"></param>
        /// <param name="longitude"></param>
        /// <returns>true if rover was moved, false otherwise</returns>
        private bool MoveSafely(double latitude, double longitude)
        {
            double altitude = GeoUtils.TerrainHeightAt(latitude, longitude, vessel.mainBody);

            if (FlightGlobals.ActiveVessel != null)
            {
                Vector3d newPos   = vessel.mainBody.GetWorldSurfacePosition(latitude, longitude, altitude);
                Vector3d actPos   = FlightGlobals.ActiveVessel.GetWorldPos3D();
                double   distance = Vector3d.Distance(newPos, actPos);
                if (distance <= 2400)
                {
                    return(false);
                }
            }

            vessel.latitude  = latitude;
            vessel.longitude = longitude;
            vessel.altitude  = altitude + vesselHeightFromTerrain + Configuration.HeightOffset;

            return(true);
        }
示例#20
0
        public void DetectMine()
        {
            foreach (Vessel v in FlightGlobals.Vessels)
            {
                if (v.Parts.Count == 1)
                {
                    var MINE = v.FindPartModuleImplementing <ModuleEnemyMine_Naval>();

                    if (MINE != null)
                    {
                        double targetDistance = Vector3d.Distance(this.vessel.GetWorldPos3D(), v.GetWorldPos3D());
                        var    _targetDist    = ecPerSec * 22;

                        if (targetDistance <= _targetDist)
                        {
                            MINE.Detonate();
                        }
                    }
                }
            }
        }
示例#21
0
        public void DetonateEMPRoutine()
        {
            foreach (Vessel v in FlightGlobals.Vessels)
            {
                if (!v.HoldPhysics)
                {
                    double targetDistance = Vector3d.Distance(this.vessel.GetWorldPos3D(), v.GetWorldPos3D());

                    if (targetDistance <= proximity)
                    {
                        var emp = v.rootPart.FindModuleImplementing <ModuleDrainEC>();
                        if (emp == null)
                        {
                            emp = (ModuleDrainEC)v.rootPart.AddModule("ModuleDrainEC");
                        }
                        emp.incomingDamage += ((proximity - (float)targetDistance) * 10); //this way craft at edge of blast might only get disabled instead of bricked
                        emp.softEMP         = false;                                      //can bypass DMP damage cap
                    }
                }
            }
        }
示例#22
0
            /// <summary>
            /// Update the heat
            /// </summary>
            public void Update()
            {
                if (!FlightGlobals.ready)
                {
                    return;
                }

                // Get all vessels
                List <Vessel> vessels = FlightGlobals.Vessels.FindAll(v => v.mainBody == body);

                // Loop through them
                foreach (Vessel vessel in vessels)
                {
                    Double distanceToPlanet = Math.Abs(Vector3d.Distance(vessel.transform.position, body.transform.position)) - ocean.GetSurfaceHeight(ocean.GetRelativePosition(vessel.transform.position));
                    Double heatingRate      = heatCurve.Evaluate((Single)distanceToPlanet);
                    foreach (Part part in vessel.Parts)
                    {
                        part.temperature += heatingRate;
                    }
                }
            }
示例#23
0
        public void UpdateData()
        {
            Location = Main.ClientRect.Location;
            Location.Offset(10, Height);

            if (MPlanetHandler.CurrentNear == null)
            {
                return;
            }

            //UserInfo.Text = "";
            UserInfo.Text = MPlanetHandler.CurrentNear.Name + ".";


            Vector3d pos = MPlanetHandler.CurrentNear.GetLonLatOnShere(UserPosition);

            UserInfo.Text += string.Format("LonLat: {0:0.0000},{1:0.0000} Alt:{2:0.0}", pos.X, pos.Y, MPlanetHandler.CurrentNear.AvatarDistanceToSurface);

            Vector3d TilePos = MPlanetHandler.CurrentNear.GetTileFromPoint(UserPosition);

            UserInfo.Text += " " + TilePos.ToString();

            GetMetaData(TilePos);

            string sDist = string.Format("{0,12:#.00}km", Vector3d.Distance(Globals.Avatar.GetPosition(), NavigationTarget) / 1000.0);

            UserInfo.Text += " |> " + sDist;
            //Location = Main.ClientLocation;
            //Location.Offset(10, Main.RenderClientSize.Height - Height);
            if (string.IsNullOrEmpty(sStatus))
            {
                UserInfo.BackColor = Color.Black;
            }
            else
            {
                UserInfo.BackColor = Color.DarkRed;
            }
            UserInfo.Text += "\r\n" + sStatus;
        }
示例#24
0
        /// <summary>
        /// This function will find the closest node from a geographical position in space.
        /// </summary>
        /// <param name="PtX">X coordinate of the point from which you want the closest node.</param>
        /// <param name="PtY">Y coordinate of the point from which you want the closest node.</param>
        /// <param name="PtZ">Z coordinate of the point from which you want the closest node.</param>
        /// <param name="Distance">The distance to the closest node.</param>
        /// <param name="IgnorePassableProperty">if 'false', then nodes whose property Passable is set to false will not be taken into account.</param>
        /// <returns>The closest node that has been found.</returns>
        public SimWaypoint ClosestNode(double PtX, double PtY, double PtZ, out double Distance, bool IgnorePassableProperty)
        {
            SimWaypoint NodeMin     = null;
            double      DistanceMin = -1;
            Vector3d    P           = new Vector3d(PtX, PtY, PtZ);

            lock (SimWaypoints) foreach (SimWaypoint N in SimWaypoints)
                {
                    if (IgnorePassableProperty && N.IsPassable == false)
                    {
                        continue;
                    }
                    double DistanceTemp = Vector3d.Distance(N.GlobalPosition, P);
                    if (DistanceMin == -1 || DistanceMin > DistanceTemp)
                    {
                        DistanceMin = DistanceTemp;
                        NodeMin     = N;
                    }
                }
            Distance = DistanceMin;
            return(NodeMin);
        }
示例#25
0
 public static bool AnyNearbyPartModules <T>(double range, Vessel referenceVessel)
     where T : PartModule
 {
     try
     {
         if (FlightGlobals.Vessels == null ||
             FlightGlobals.Vessels.Count < 2 ||
             referenceVessel == null)
         {
             return(false);
         }
         var referencePosition = referenceVessel.GetWorldPos3D();
         foreach (var vessel in FlightGlobals.Vessels)
         {
             if (vessel.persistentId == referenceVessel.persistentId)
             {
                 continue;
             }
             var partModule = vessel.FindPartModuleImplementing <T>();
             if (partModule == null)
             {
                 continue;
             }
             var distance
                 = Vector3d.Distance(vessel.GetWorldPos3D(), referencePosition);
             if (distance <= range)
             {
                 return(true);
             }
         }
         return(false);
     }
     catch (Exception ex)
     {
         Debug.LogError(
             $"[USITools] {nameof(LogisticsTools)}.{nameof(AnyNearbyPartModules)}: {ex.Message}");
         return(false);
     }
 }
示例#26
0
        ///<summary>
        /// Fills the given contact structure with the contact needed
        /// to keep the rod from extending or compressing.
        ///</summary>
        public override int AddContact(IList <Particle> particles, IList <ParticleContact> contacts, int next)
        {
            // Find the length of the cable
            double currentLen = Vector3d.Distance(m_particleA.Position, m_particleB.Position);

            // Check if we're over-extended
            if (currentLen == m_length)
            {
                return(0);
            }

            var contact = contacts[next];

            // Otherwise return the contact
            contact.Particles[0] = m_particleA;
            contact.Particles[1] = m_particleB;

            // Calculate the normal
            Vector3d normal = m_particleB.Position - m_particleA.Position;

            normal.Normalize();

            // The contact normal depends on whether we're extending or compressing
            if (currentLen > m_length)
            {
                contact.ContactNormal = normal;
                contact.Penetration   = currentLen - m_length;
            }
            else
            {
                contact.ContactNormal = normal * -1;
                contact.Penetration   = m_length - currentLen;
            }

            // Always use zero restitution (no bounciness)
            contact.Restitution = 0;

            return(1);
        }
示例#27
0
        /// <summary>
        /// Finds the two points with the maximum distance to each other in the
        /// specified list of points. In other words, will find the diagonal of a
        /// polygon that is defined by the specified list.
        /// </summary>
        /// <param name="list">The list of points.</param>
        /// <returns>
        /// A pair of two points which are farthest from each other.
        /// </returns>
        public static Tuple <Vector3d, Vector3d> FindFarthestPoints(IEnumerable <Vector3d> list)
        {
            int count = list.Count();

            switch (count)
            {
            case 0:
            case 1:
                return(null);

            case 2:
                var point = list.First();
                return(new Tuple <Vector3d, Vector3d>(point, point));
            }

            double   maxDistance = int.MinValue;
            Vector3d a           = Vector3d.Zero;
            Vector3d b           = Vector3d.Zero;

            for (int i = 0; i < count - 1; i++)
            {
                Vector3d first = list.ElementAt(i);

                for (int j = i + 1; j < count; j++)
                {
                    Vector3d second   = list.ElementAt(j);
                    double   distance = first.Distance(second);

                    if (distance > maxDistance)
                    {
                        maxDistance = distance;
                        a           = first;
                        b           = second;
                    }
                }
            }

            return(new Tuple <Vector3d, Vector3d>(a, b));
        }
示例#28
0
            public Vector3d Project(Vector3d vPoint, int identifier = -1)
            {
                int tNearestID        = Spatial.FindNearestTriangle(vPoint);
                DistPoint3Triangle3 q = MeshQueries.TriangleDistance(Mesh, tNearestID, vPoint);

                double curAmount = 1 - amount;

                if (maxDistance < float.MaxValue && maxDistance > 0)
                {
                    var distance = vPoint.Distance(q.TriangleClosest);

                    if (distance < maxDistance)
                    {
                        double distanceAmount        = distance / maxDistance;
                        double projectDistanceAmount = 1 - distanceAmount;

                        return(((vPoint * curAmount) + (q.TriangleClosest * amount)) * projectDistanceAmount + (vPoint * distanceAmount));
                    }
                }

                return(q.TriangleClosest);
            }
示例#29
0
        public static double getRadiationDose(Vessel vessel, double rad_hardness)
        {
            double        radiation_level = 0;
            CelestialBody cur_ref_body    = FlightGlobals.ActiveVessel.mainBody;
            CelestialBody crefkerbin      = FlightGlobals.fetch.bodies[1];

            ORSPlanetaryResourcePixel res_pixel = ORSPlanetaryResourceMapData.getResourceAvailability(vessel.mainBody.flightGlobalsIndex, "Thorium", cur_ref_body.GetLatitude(vessel.transform.position), cur_ref_body.GetLongitude(vessel.transform.position));
            double ground_rad         = Math.Sqrt(res_pixel.getAmount() * 9e6) / 24 / 365.25 / Math.Max(vessel.altitude / 870, 1);
            double rad                = VanAllen.getRadiationLevel(cur_ref_body.flightGlobalsIndex, (float)FlightGlobals.ship_altitude, (float)FlightGlobals.ship_latitude);
            double divisor            = Math.Pow(cur_ref_body.Radius / crefkerbin.Radius, 2.0);
            double mag_field_strength = VanAllen.getBeltMagneticFieldMag(cur_ref_body.flightGlobalsIndex, (float)FlightGlobals.ship_altitude, (float)FlightGlobals.ship_latitude);
            // if (cur_ref_body.flightGlobalsIndex == PluginHelper.REF_BODY_KERBOL) {
            //    rad = rad * 1e6;
            //}

            double rad_level       = rad / divisor;
            double inv_square_mult = Math.Pow(Vector3d.Distance(FlightGlobals.Bodies[PluginHelper.REF_BODY_KERBIN].transform.position, FlightGlobals.Bodies[PluginHelper.REF_BODY_KERBOL].transform.position), 2) / Math.Pow(Vector3d.Distance(vessel.transform.position, FlightGlobals.Bodies[PluginHelper.REF_BODY_KERBOL].transform.position), 2);
            double solar_radiation = 0.19 * inv_square_mult;

            while (cur_ref_body.referenceBody != null)
            {
                CelestialBody old_ref_body = cur_ref_body;
                cur_ref_body = cur_ref_body.referenceBody;
                if (cur_ref_body == old_ref_body)
                {
                    break;
                }
                //rad = VanAllen.getBeltAntiparticles (cur_ref_body.flightGlobalsIndex, (float) (Vector3d.Distance(FlightGlobals.ship_position,cur_ref_body.transform.position)-cur_ref_body.Radius), 0.0f);
                //rad = VanAllen.getRadiationLevel(cur_ref_body.flightGlobalsIndex, (Vector3d.Distance(FlightGlobals.ship_position, cur_ref_body.transform.position) - cur_ref_body.Radius), 0.0);
                mag_field_strength += VanAllen.getBeltMagneticFieldMag(cur_ref_body.flightGlobalsIndex, (float)(Vector3d.Distance(FlightGlobals.ship_position, cur_ref_body.transform.position) - cur_ref_body.Radius), (float)FlightGlobals.ship_latitude);
                //rad_level += rad;
            }
            if (cur_ref_body.flightGlobalsIndex != PluginHelper.REF_BODY_KERBOL)
            {
                solar_radiation = solar_radiation * Math.Exp(-73840.56456662708394321273809886 * mag_field_strength) * Math.Exp(-vessel.atmDensity * 4.5);
            }
            radiation_level = (Math.Pow(rad_level / 3e-5, 3.0) * 3.2 + ground_rad + solar_radiation) / rad_hardness;
            return(radiation_level);
        }
示例#30
0
        /// <summary>Tests whether two vessels have line of sight to each other</summary>
        /// <returns><c>true</c> if a straight line from a to b is not blocked by any celestial body;
        /// otherwise, <c>false</c>.</returns>
        public static bool HasLineOfSightWith(Vessel vessA, Vessel vessB, double freeDistance = 2500, double min_height = 5)
        {
            Vector3d vesselA = vessA.transform.position;
            Vector3d vesselB = vessB.transform.position;

            if (freeDistance > 0 && Vector3d.Distance(vesselA, vesselB) < freeDistance)           // if both vessels are within active view
            {
                return(true);
            }

            foreach (CelestialBody referenceBody in FlightGlobals.Bodies)
            {
                Vector3d bodyFromA = referenceBody.position - vesselA;
                Vector3d bFromA    = vesselB - vesselA;

                // Is body at least roughly between satA and satB?
                if (Vector3d.Dot(bodyFromA, bFromA) <= 0)
                {
                    continue;
                }

                Vector3d bFromANorm = bFromA.normalized;

                if (Vector3d.Dot(bodyFromA, bFromANorm) >= bFromA.magnitude)
                {
                    continue;
                }

                // Above conditions guarantee that Vector3d.Dot(bodyFromA, bFromANorm) * bFromANorm
                // lies between the origin and bFromA
                Vector3d lateralOffset = bodyFromA - Vector3d.Dot(bodyFromA, bFromANorm) * bFromANorm;

                if (lateralOffset.magnitude < referenceBody.Radius - min_height)
                {
                    return(false);
                }
            }
            return(true);
        }
示例#31
0
        private void Objects_OnObjectUpdated(object s, TerseObjectUpdateEventArgs e)
        {
            var Client         = GetGridClient();
            var ClientMovement = Client.Self.Movement;

            if (startTime == DateTime.MinValue)
            {
                DeRegCallback();
                return;
            }
            if (e.Update.LocalID == Client.Self.LocalID)
            {
                XYMovement();
                ZMovement();
                if (ClientMovement.AtPos || ClientMovement.AtNeg)
                {
                    TheBot.TurnToward(Target.GlobalPosition);
                    //Debug("Flyxy ");
                }
                else if (ClientMovement.UpPos || ClientMovement.UpNeg)
                {
                    TheBot.TurnToward(Target.GlobalPosition);
                    //ClientMovement.SendUpdate(false);
                    //Debug("Fly z ");
                }
                else if (Vector3d.Distance(Target.GlobalPosition, TheBot.GlobalPosition) <= 2.0)
                {
                    EndFlyto();
                    KeepFollowing = false;
                    Debug("At Target");
                }
            }
            if (!KeepFollowing)
            {
                EndFlyto();
                Debug("End Flyto");
            }
        }
示例#32
0
 /// <summary>Get the closest distance between this <see cref="Box3d"/> and the <see cref="Vector3d"/>.</summary>
 public Double Distance( ref  Vector3d point)
 {
     Vector3d nearest;
         NearestPointTo(ref point, out nearest);
         return point.Distance(ref nearest);
 }