Показать сообщение отдельно
  #2  
Старый 25.12.2011, 16:16
mmmm mmmm вне форума
Прохожий
 
Регистрация: 25.12.2011
Сообщения: 3
Репутация: 10
По умолчанию

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; 
Ответить с цитированием