@@ -244,16 +244,32 @@ public double AngularVelocity(Time epoch)
244244 return ( 2.0 * Constants . PI ) / siderealRotationPeriod . TotalSeconds ;
245245 }
246246
247+ /// <summary>
248+ /// Computes the Keplerian elements for a geosynchronous orbit at the specified longitude and latitude.
249+ /// The latitude parameter defines the orbital inclination — for non-zero latitude, the satellite follows
250+ /// an inclined geosynchronous orbit tracing a figure-eight ground track. The specified (longitude, latitude)
251+ /// is the sub-satellite point only at the given epoch.
252+ /// </summary>
253+ /// <param name="longitude">Planetocentric longitude in radians, in range [-π, π].</param>
254+ /// <param name="latitude">Planetocentric latitude in radians, in range [-π/2, π/2]. Defines the orbital inclination.</param>
255+ /// <param name="epoch">The epoch at which to compute the orbit.</param>
256+ /// <returns>Keplerian elements for the geosynchronous orbit.</returns>
257+ /// <exception cref="ArgumentOutOfRangeException">Thrown when longitude or latitude is out of range.</exception>
247258 public KeplerianElements GeosynchronousOrbit ( double longitude , double latitude , Time epoch )
248259 {
260+ if ( longitude < - Constants . PI || longitude > Constants . PI )
261+ throw new ArgumentOutOfRangeException ( nameof ( longitude ) , longitude , "Longitude must be in range [-π, π] radians." ) ;
262+ if ( latitude < - Constants . PI2 || latitude > Constants . PI2 )
263+ throw new ArgumentOutOfRangeException ( nameof ( latitude ) , latitude , "Latitude must be in range [-π/2, π/2] radians." ) ;
264+
249265 var sideralRotation2 = System . Math . Pow ( SideralRotationPeriod ( epoch ) . TotalSeconds , 2 ) ;
250266 var radius = System . Math . Cbrt ( ( GM * sideralRotation2 ) / ( 4 * Constants . PI * Constants . PI ) ) ;
251267 var bodyfFixedCoordinates = new Planetocentric ( longitude , latitude , radius ) . ToCartesianCoordinates ( ) ;
252268 var icrfPos = bodyfFixedCoordinates . Rotate ( Frame . ToFrame ( Frame . ICRF , epoch ) . Rotation ) ;
253269 var icrfRot = Vector3 . VectorZ . Rotate ( Frame . ToFrame ( Frame . ICRF , epoch ) . Rotation ) ;
254270 var inertialVelocity = icrfRot . Cross ( icrfPos ) . Normalize ( ) * System . Math . Sqrt ( GM / radius ) ;
255271 var sv = new StateVector ( icrfPos , inertialVelocity , this , epoch , Frame . ICRF ) ;
256- return new KeplerianElements ( radius , 0.0 , sv . Inclination ( ) , sv . AscendingNode ( ) , ( sv . ArgumentOfPeriapsis ( ) + sv . MeanAnomaly ( ) ) % Constants . _2PI , 0.0 , this , epoch , sv . Frame ) ;
272+ return new KeplerianElements ( radius , 0.0 , sv . Inclination ( ) , sv . AscendingNode ( ) , sv . ArgumentOfPeriapsis ( ) + sv . MeanAnomaly ( ) , 0.0 , this , epoch , sv . Frame ) ;
257273 }
258274
259275 /// <summary>
0 commit comments