@@ -123,29 +123,48 @@ void load_tle_data(const char* filename) {
123123 fclose (file );
124124}
125125
126- // figure out where the satellite is right now
126+ // figure out where the satellite is right now (with j2 spheroid perturbations)
127127Vector3 calculate_position (Satellite * sat , double current_time_days ) {
128128 double delta_time_s = (current_time_days - sat -> epoch_days ) * 86400.0 ;
129+
130+ // earth oblateness (j2) effects
131+ double e2 = sat -> eccentricity * sat -> eccentricity ;
132+ double p = sat -> semi_major_axis * (1.0 - e2 );
133+
134+ // j2 math constants
135+ const double J2 = 0.00108262668 ;
136+ const double RE = 6378.137 ; // earth radius in km
137+
138+ double n_J2_Re2_p2 = sat -> mean_motion * J2 * (RE * RE ) / (p * p );
139+ double raan_dot = -1.5 * n_J2_Re2_p2 * cos (sat -> inclination );
140+ double arg_perigee_dot = 0.75 * n_J2_Re2_p2 * (4.0 - 5.0 * pow (sin (sat -> inclination ), 2 ));
141+
142+ double current_raan = sat -> raan + raan_dot * delta_time_s ;
143+ double current_arg_perigee = sat -> arg_perigee + arg_perigee_dot * delta_time_s ;
144+
129145 double M = sat -> mean_anomaly + sat -> mean_motion * delta_time_s ;
130146 M = fmod (M , 2.0 * PI );
131- if (M < 0 ) M += 2.0 * PI ;
147+ if (M < 0.0 ) M += 2.0 * PI ;
132148
133- double E = M ;
149+ // improved guess for kepler's equation
150+ double E = M + sat -> eccentricity * sin (M );
151+ double sinE , cosE ;
134152 for (int i = 0 ; i < 10 ; i ++ ) {
135- double delta = (E - sat -> eccentricity * sin (E ) - M ) / (1.0 - sat -> eccentricity * cos (E ));
153+ sinE = sin (E );
154+ cosE = cos (E );
155+ double delta = (E - sat -> eccentricity * sinE - M ) / (1.0 - sat -> eccentricity * cosE );
136156 E -= delta ;
137157 if (fabs (delta ) < 1e-6 ) break ;
138158 }
139159
140- double nu = 2.0 * atan2 (sqrt (1.0 + sat -> eccentricity ) * sin (E / 2.0 ),
141- sqrt (1.0 - sat -> eccentricity ) * cos (E / 2.0 ));
142-
143- double r = sat -> semi_major_axis * (1.0 - sat -> eccentricity * cos (E ));
144- double x_orb = r * cos (nu );
145- double y_orb = r * sin (nu );
160+ // bypass true anomaly calculation
161+ double sqrt_1_minus_e2 = sqrt (1.0 - e2 );
162+ double x_orb = sat -> semi_major_axis * (cosE - sat -> eccentricity );
163+ double y_orb = sat -> semi_major_axis * sqrt_1_minus_e2 * sinE ;
146164
147- double cw = cos (sat -> arg_perigee ), sw = sin (sat -> arg_perigee );
148- double cO = cos (sat -> raan ), sO = sin (sat -> raan );
165+ // use perturbed angles for orientation
166+ double cw = cos (current_arg_perigee ), sw = sin (current_arg_perigee );
167+ double cO = cos (current_raan ), sO = sin (current_raan );
149168 double ci = cos (sat -> inclination ), si = sin (sat -> inclination );
150169
151170 Vector3 pos ;
0 commit comments