| 
				  
 2юнит: 
	PHP код: 
		
		
			
unit Unit2_1512;
 interface
 
 uses
 Messages;
 const
 (**)  TwoPi = 2 * Pi;
 RE =    6371.21;    //средний радиус Земли км
 ToRad = Pi/180;     // Deg2Rad =
 ToGrad = 180/Pi;    // Rad2Deg
 Mu = 0.398603e6;   // ГПЗ
 (**)  We = 7.2921151467e-5; // Угловая скорость вращения Земли (ср солн сут)
 (**)  JD2000 = 2451545.0; // юлианская дата эпохи 2000 г., январь 1.5. (1 января 12 час)
 
 wm_DrawChart = wm_User + 1;
 
 type
 
 T3DVector = record
 X, Y, Z : real;
 end;
 
 T3DMatrix = array[1..3, 1..3] of real;
 
 TGeo = record
 Pos : T3DVector;    // положение ГСК
 R, Longitude, Latitude,alfa : real  // радиус, долгота, широта
 end;
 
 TClassic = record
 Rp, e, ArgLat, Incl, AscNode, ArgPerigee: real
 end;
 
 TCartesian = record
 Pos: T3DVector;  // АГЭСК ( положение )
 Vel : T3DVector;  // АГЭСК ( скорость )
 end;
 
 POrbit = ^TOrbit;    {New}
 TOrbit = record
 Epoch : TDateTime; // Дата и время начальных условий
 Time  : real;      // Собственное время КА (c)
 Classic : TClassic;
 Cartes  : TCartesian;
 Geo     : TGeo       // ГСК  ( положение, долгота и широта )
 end;
 
 // Векторная алгебра
 
 function ScalProd( A, B : T3DVector ) : real;
 function Summa( A, B : T3DVector ) : T3DVector;
 function Differ( A, B : T3DVector ) : T3DVector;
 function Modul( A : T3DVector ): real;
 function UnitVect ( A : T3DVector ): T3DVector;
 function InitVect( X, Y, Z : real) : T3DVector;
 function ZeroVect : T3DVector;
 function MxV( M : T3DMatrix; V : T3DVector) : T3DVector;
 
 (**) function MAbs_Geo( Value : real ) : T3DMatrix; // матрица перехода АГЭСК->ГСК
 
 // Вычисление декартовых координат КА по классическим элементам
 procedure ClassToXYZ( var AOrbit : TOrbit );
 
 // Вычисление координат КА в земной СК
 
 // Вычисление истинной аномалии КА
 function TrueAnomaly( AOrbit : TOrbit ) : real;
 
 // Вычисление параметра эллипса р
 function Parameter( AOrbit : TOrbit ) : real;
 
 // Вычисление радиус-вектора КА (r)
 function Radius( AOrbit : TOrbit ) : real;
 
 // Вычисление среднего движения (n)
 function MeanMotion( AOrbit : TOrbit ) : real;
 
 // Вычисление периода обращения (Т)
 function Period( AOrbit : TOrbit ) : real;
 
 //  Вычисление радиальной скорости КА Vr
 function VRadial( AOrbit : TOrbit ) : real;
 
 // Вычисление большой полуоси орбиты  (км)
 function SemiMajorAxis( AOrbit : TOrbit ) : real;
 
 // Вычисление эксцентрической аномалии (рад)
 function EccentrAnomaly ( AOrbit : TOrbit ): real;
 
 // Вычисление средней аномалии (рад)
 function MeanAnomaly ( AOrbit : TOrbit ): real;
 
 // Вычисление момента времени прохождения перигея  (с)
 function PerigeePassTime( AOrbit : TOrbit ) : real;
 
 function KeplerEquation(const e,M : real):real;
 
 procedure SetTime( ATime : real; var AOrb : TOrbit);  overload;
 
 procedure SetTime( ATime : real;  IniOrb : TOrbit; var AOrb : TOrbit);  overload;
 
 function  SetTimeF( ATime : real; IniOrb : TOrbit ) : TOrbit;
 
 (**)function SiderialTime0( Value : TDateTime ) : real; // 0h дата
 (**)function SiderialTime ( Value : TDateTime ) : real; // UTC дата+время
 //procedure urTrassa(Value:TDateTime ; Orbit:TOrbit; var lat,long,long_ekv:double);
 procedure NIP (var Nip:TGeo);
 procedure ugolMesta (var alfa:real);
 procedure DecKoord(var Nip:TGeo);
 
 implementation
 
 uses
 Math,
 SysUtils,
 (**)  DateUtils;   {!!!}
 
 var
 Pos,razn : T3DVector;
 Orb : TClassic;
 
 function ScalProd( A, B : T3DVector ) : real;
 begin
 Result := A.X * B.X + A.Y * B.Y + A.Z * B.Z;
 end;
 
 function Summa( A, B : T3DVector ) : T3DVector;
 begin
 Result.X := A.X + B.X;
 Result.Y := A.Y + B.Y;
 Result.Z := A.Z + B.Z;
 end;
 
 function Differ( A, B : T3DVector ) : T3DVector;
 begin
 Result.X := A.X - B.X;
 Result.Y := A.Y - B.Y;
 Result.Z := A.Z - B.Z;
 end;
 
 function Modul( A : T3DVector ): real;
 begin
 Result := Sqrt( Sqr(A.X) + Sqr(A.Y) + Sqr(A.Z));
 end;
 
 function UnitVect ( A : T3DVector ): T3DVector;
 var
 R : real;
 begin
 R := Modul(A);
 if R<>0 then
 begin
 R := 1/R;
 Result.X := A.X * R;
 Result.Y := A.Y * R;
 Result.Z := A.Z * R;
 end else
 begin
 end;
 end;
 
 function InitVect( X, Y, Z : real) : T3DVector;
 begin
 Result.X := X;
 Result.Y := Y;
 Result.Z := Z;
 end;
 
 function ZeroVect : T3DVector;
 begin
 Result := InitVect(0,0,0);
 end;
 
 function MxV( M : T3DMatrix; V : T3DVector) : T3DVector;
 begin
 Result.X := M[1,1] * V.X + M[1,2] * V.Y + M[1,3] * V.Z;
 Result.Y := M[2,1] * V.X + M[2,2] * V.Y + M[2,3] * V.Z;
 Result.Z := M[3,1] * V.X + M[3,2] * V.Y + M[3,3] * V.Z;
 end;
 
 function MAbs_Geo( Value : real ) : T3DMatrix; // матрица перехода АГЭСК->ГСК
 begin
 FillChar( Result, SizeOf(T3DMatrix), 0);
 Result[1,1] := Cos( Value );
 Result[1,2] := Sin( Value );
 Result[2,1] := - Result[1,2];
 Result[2,2] := Result[1,1];
 Result[3,3] := 1;
 end;
 
 function TrueAnomaly( AOrbit : TOrbit ) : real;
 var
 r : real;
 begin
 (**)
 r :=  AOrbit.Classic.ArgLat - AOrbit.Classic.ArgPerigee;
 if r < 0 then r := TwoPi + r;
 Result := r;
 end;
 
 function Parameter ( AOrbit : TOrbit ) : real;
 begin
 Result := AOrbit.Classic.Rp * ( 1 + AOrbit.Classic.e );
 end;
 
 function Radius( AOrbit : TOrbit ) : real;
 begin
 Result := Parameter( AOrbit ) / ( 1 + AOrbit.Classic.e * Cos( TrueAnomaly(AOrbit) ));
 end;
 
 function MeanMotion( AOrbit : TOrbit ) : real;
 begin
 Result := Sqrt( Mu * Parameter( AOrbit )) / Sqr( Radius( AOrbit ));
 end;
 
 function Period( AOrbit : TOrbit ) : real;
 begin
 Result := TwoPi / MeanMotion( AOrbit );
 end;
 
 function VRadial( AOrbit : TOrbit ) : real;
 begin
 Result := Sqrt( Mu/Parameter(AOrbit) ) * AOrbit.Classic.e * Sin( TrueAnomaly( AOrbit ) );
 end;
 
 function SemiMajorAxis( AOrbit : TOrbit ) : real;
 var
 x : real;
 begin
 x := Mu / Sqr( MeanMotion( AOrbit ) );
 Result := Power ( x, 1/3 );
 end;
 
 function EccentrAnomaly ( AOrbit : TOrbit ): real;
 var
 v, e, r : real;
 begin
 v := TrueAnomaly( AOrbit );
 e := AOrbit.Classic.e;
 (**)
 r := 2 * ArcTan( Sqrt((1-e)/(1+e)) * Tan( 0.5 * v ));
 if r < 0 then r := TwoPi + r ;
 Result := r;
 end;
 
 function MeanAnomaly( AOrbit : TOrbit ) : real;
 var
 E, r : real;
 begin
 E := EccentrAnomaly( AOrbit );
 (**)
 r := E - AOrbit.Classic.e * Sin( E );
 if r < 0 then r := TwoPi + r;
 Result := r;
 end;
 
 function PerigeePassTime( AOrbit : TOrbit ) : real;
 begin
 Result := - MeanAnomaly( AOrbit ) / MeanMotion( AOrbit );
 end;
 
 procedure ClassToXYZ( var AOrbit : TOrbit );
 var
 Su, So, Si, Cu, Co, Ci,
 Vr_r, rn, r : real;
 (**) // Внутренния процедура расчета положения КА в ГСК
 procedure _ToGeo ;
 var
 S, Cl, Sl : real;
 t : TDateTime;
 M : T3DMatrix;
 begin
 t := AOrbit.Epoch + AOrbit.Time / 86400 ;
 S := SiderialTime( t );
 M := MAbs_Geo( S );
 AOrbit.Geo.Pos := MxV( M, AOrbit.Cartes.Pos );
 AOrbit.Geo.R := Modul( AOrbit.Geo.Pos) ;
 r := Sqrt( Sqr( AOrbit.Geo.Pos.X ) +  Sqr( AOrbit.Geo.Pos.Y ) );
 Sl := AOrbit.Geo.Pos.Y / r ;
 Cl := AOrbit.Geo.Pos.X / r ;
 AOrbit.Geo.Latitude := ArcSin( AOrbit.Geo.Pos.Z / AOrbit.Geo.R ); // Широта
 case Sl > 0 of
 true : AOrbit.Geo.Longitude := ArcCos( Cl );       // Долгота
 false: AOrbit.Geo.Longitude := - ArcCos( Cl );
 end;
 end;
 begin
 r := Radius( AOrbit );
 rn := r * MeanMotion( AOrbit );
 Vr_r := Vradial( AOrbit) / r;
 
 Su := Sin( AOrbit.Classic.ArgLat);
 Cu := Cos( AOrbit.Classic.ArgLat);
 
 So:= Sin( AOrbit.Classic.AscNode);
 Co := Cos( AOrbit.Classic.AscNode);
 
 Si := Sin( AOrbit.Classic.Incl);
 Ci := Cos( AOrbit.Classic.Incl);
 
 AOrbit.Cartes.Pos.X := r * ( Cu * Co - Su * So * Ci );
 AOrbit.Cartes.Pos.Y := r * ( Cu * So + Su * Co * Ci );
 AOrbit.Cartes.Pos.Z := r * Su * Si;
 
 AOrbit.Cartes.Vel.X := Vr_r * AOrbit.Cartes.Pos.X
 - rn * (Su * Co + Cu * Co * Ci);
 AOrbit.Cartes.Vel.Y := Vr_r * AOrbit.Cartes.Pos.Y
 - rn * (Su * Co - Cu * Co * Ci);
 AOrbit.Cartes.Vel.Z := Vr_r * AOrbit.Cartes.Pos.Z
 -rn * Cu * Si;
 _ToGeo;  // Вычислить координаты в ГСК
 end;
 
 function KeplerEquation(const e,M : real):real;
 { Решение уравнения Кеплера в цикле repeat }
 const
 Eps = 1e-9;
 var
 Eold,Enew : real;
 Stop : boolean;
 begin
 Eold := M;
 repeat
 Enew := M + e * Sin(Eold);
 Stop := Abs(Eold-Enew)<=Eps;
 Eold := Enew;
 until Stop;
 Result := Enew;
 end;
 
 (**) // Служебная функция - вычисляет аргумент широты на заданный момент времени
 function GetArgLat( ATime : real; AOrb : TOrbit ) : real;
 var
 M, E, v, u : real;
 n : integer;
 begin
 // Вычислить среднюю аномалию в момент времени Time
 M := MeanMotion( AOrb ) * ( ATime - PerigeePassTime( AOrb ) );
 // решаем ур-е Кеплера
 E := KeplerEquation( AOrb.Classic.e, M );
 // находим истинную аномалию
 v := 2 * ArcTan(Sqrt((1-AOrb.Classic.e)/(1+AOrb.Classic.e))*Tan(0.5*E));
 //привести v к интервалу 0..2пи
 if v < 0 then v := TwoPi + v;
 // Вычисляем новый аргумент широты
 u := v + AOrb.Classic.ArgPerigee;
 // Привести к интервалу 0..2Pi
 n := Trunc( u / TwoPi ); // целое число периодов
 Result := u - n * TwoPi;
 end;
 
			
 
			
			
			
				  |