void UpdateReletiveTargetData(object Sender, UpdateEventArgs e) // Only works in atmosphere { Vector3D PlanetPos; Cockpit.TryGetPlanetPosition(out PlanetPos); Vector3D MePos = Me.CubeGrid.GetPosition(); Vector3D TargetPos = LastTargetData.HitPosition ?? MePos; Vector3D MeVelocity = Cockpit.GetShipVelocities().LinearVelocity; Vector3D MeGravity = Cockpit.GetNaturalGravity(); double Distance = Vector3D.Distance(TargetPos, MePos); double MeHeight = Vector3D.Distance(MePos, PlanetPos); double TargetHeight = Vector3D.Distance(TargetPos, PlanetPos); double RelativeTargetHeight = TargetHeight - MeHeight; // Should be negative when aircraft is above Vector3D RelativePlanetPos = PlanetPos - MePos; Vector3D MeRelativeGroundPos = RelativePlanetPos * (-RelativeTargetHeight / MeHeight); Vector3D MeGroundPos = MePos + MeRelativeGroundPos; Vector3D GroundPosToTarget = TargetPos - MeGroundPos; double S, U, V, A, T; // Equations of motion in SUVAT notation. T = ProjectileGroundInterceptTime(RelativeTargetHeight, Cockpit.GetShipVelocities().LinearVelocity, Cockpit.GetNaturalGravity()); S = ProjectileLateralTravelDistance(T, GroundPosToTarget, Cockpit.GetShipVelocities().LinearVelocity); double GroundDistanceToDrop = Vector3D.Distance(MeGroundPos, TargetPos) - S; double TimeUntilDrop = GroundDistanceToDrop / Cockpit.GetShipVelocities().LinearVelocity.Dot(Vector3D.Normalize(GroundPosToTarget)); Vector3D RelativePlanetPosFromTarget = PlanetPos - MePos; Vector3D ToRight = Vector3D.Normalize(GroundPosToTarget.Cross(MeGravity)); double ToRightCorrection = Vector3D.Normalize(MeVelocity).Dot(ToRight); double ToRightCorrectionAngle = Math.Asin(ToRightCorrection) / Math.PI * 180; string ToRightText = ToRightCorrectionAngle >= 0 ? "Right" : "Left"; ConsoleBuffers["ToRightCorrectionAngle"] = $"To {ToRightText}: {Math.Abs(ToRightCorrectionAngle):F1}°"; ConsoleBuffers["TimeUntilDrop"] = $"Time until Drop: {TimeUntilDrop:F1}s"; ConsoleBuffers["GroundDistanceUntillDrop"] = $"Distance until Drop: {GroundDistanceToDrop:F1}m"; }
/// <summary> /// гаситель инерции /// </summary> private void InertionCompensator() { velocity = cockpit.GetShipVelocities(); // получение скорости корабля относительно мира Vector3D V3Dfow = cockpit.WorldMatrix.Forward; // вектор направления вперед у корабля Vector3D V3Dup = cockpit.WorldMatrix.Up; // вектор направления вверх у корабля Vector3D V3Dleft = cockpit.WorldMatrix.Left; // вектор направления влево у корабля Vector3D velocityV3Dleft = new Vector3D(velocity.LinearVelocity.X, 0, 0); // вектор скорости по оси X (лево/право) Vector3D velocityV3Dup = new Vector3D(0, velocity.LinearVelocity.Y, 0); // вектор скорости по оси Y (вверх/вниз) Vector3D velocityV3Dfow = new Vector3D(0, 0, velocity.LinearVelocity.Z); // вектор скорости по оси Z (вперед/назад) double projectionLeft = velocityV3Dleft.Length() * Vector3D.Dot(velocityV3Dleft, V3Dleft) + velocityV3Dfow.Length() * Vector3D.Dot(velocityV3Dfow, V3Dleft) + velocityV3Dup.Length() * Vector3D.Dot(velocityV3Dup, V3Dleft); double projectionUp = velocityV3Dleft.Length() * Vector3D.Dot(velocityV3Dleft, V3Dup) + velocityV3Dfow.Length() * Vector3D.Dot(velocityV3Dfow, V3Dup) + velocityV3Dup.Length() * Vector3D.Dot(velocityV3Dup, V3Dup); double projectionFow = velocityV3Dleft.Length() * Vector3D.Dot(velocityV3Dleft, V3Dfow) + velocityV3Dfow.Length() * Vector3D.Dot(velocityV3Dfow, V3Dfow) + velocityV3Dup.Length() * Vector3D.Dot(velocityV3Dup, V3Dfow); // нахождение длин проекций по 3 осям /* * Управление тягой вперед/назад */ if (projectionFow > 10) { ThrustOn(thrustBackward); ThrustOff(thrustForward); } else if (projectionFow < -10) { ThrustOn(thrustForward); ThrustOff(thrustBackward); } else { ThrustOff(thrustForward); ThrustOff(thrustBackward); } /* * Управление тягой влево/вправо */ if (projectionLeft > 10) { ThrustOn(thrustRight); ThrustOff(thrustLeft); } else if (projectionLeft < -10) { ThrustOn(thrustLeft); ThrustOff(thrustRight); } else { ThrustOff(thrustRight); ThrustOff(thrustLeft); } /* * Управление тягой вверх/вниз */ if (projectionUp > 10) { ThrustOn(thrustDown); ThrustOff(thrustUp); } else if (projectionUp < -10) { ThrustOn(thrustUp); ThrustOff(thrustDown); } else { ThrustOff(thrustUp); ThrustOff(thrustDown); } }
public void Update(MyDetectedEntityInfo target, Vector3D T, Vector3D PointerPos, Vector3D PointerDir) { if (!Launched) { foreach (IMyThrust thr in thrusters) { thr.Enabled = true; thr.ThrustOverridePercentage = 1; } Launched = true; } else { counter++; if (remcon.IsFunctional && (counter > VerticalDelay)) { double currentVelocity = remcon.GetShipVelocities().LinearVelocity.Length(); Vector3D targetvector = new Vector3D(); if (LASER_GUIDED) { targetvector = ((remcon.GetPosition() - PointerPos).Dot(PointerDir) + 700) * PointerDir + PointerPos - remcon.GetPosition(); } else { targetvector = FindInterceptVector(remcon.GetPosition(), currentVelocity * INTERCEPT_COURSE, T, target.Velocity); } Vector3D trgNorm = Vector3D.Normalize(targetvector); if ((target.Position - remcon.GetPosition()).Length() < WH_ARM_DIST) { if (currentVelocity - MyVelocity < -ACCEL_DET) { foreach (IMyWarhead wh in warheads) { wh.Detonate(); } } MyVelocity = currentVelocity; } Vector3D velNorm = Vector3D.Normalize(remcon.GetShipVelocities().LinearVelocity); Vector3D CorrectionVector = Math.Max(ReflectK * trgNorm.Dot(velNorm), 1) * trgNorm - velNorm; Vector3D G = remcon.GetNaturalGravity(); if (G.LengthSquared() == 0) { CorrectionVector = Math.Max(ReflectK * trgNorm.Dot(velNorm), 1) * trgNorm - velNorm; } else { if (JAVELIN) { //trgNorm = Vector3D.Normalize(Vector3D.Reflect(-G, trgNorm)); trgNorm = Vector3D.Normalize(G.Dot(trgNorm) * trgNorm * JAVELIN_CURVE - G); } CorrectionVector = Math.Max(ReflectK * trgNorm.Dot(velNorm), 1) * trgNorm - velNorm; double A = 0; foreach (IMyThrust thr in thrusters) { A += thr.MaxEffectiveThrust; } A /= remcon.CalculateShipMass().PhysicalMass; Vector3D CorrectionNorm = Vector3D.Normalize(CorrectionVector); //CorrectionVector = CorrectionNorm * A - G; Vector3D gr = Vector3D.Reject(remcon.GetNaturalGravity(), CorrectionNorm); CorrectionVector = CorrectionNorm * Math.Sqrt(A * A + gr.LengthSquared()) - gr; } Vector3D Axis = Vector3D.Normalize(CorrectionVector).Cross(remcon.WorldMatrix.Forward); if (Axis.LengthSquared() < 0.1) { Axis += remcon.WorldMatrix.Backward * ROLL; } Axis *= GyroMult; foreach (IMyGyro gyro in gyros) { gyro.Pitch = (float)Axis.Dot(gyro.WorldMatrix.Right); gyro.Yaw = (float)Axis.Dot(gyro.WorldMatrix.Up); gyro.Roll = (float)Axis.Dot(gyro.WorldMatrix.Backward); } } else { foreach (IMyGyro gyro in gyros) { gyro.Pitch = 0; gyro.Yaw = 0; gyro.Roll = 0; } } } }