Estoy intentando modelar las posiciones de los satélites GPS en el globo para un conjunto de efemérides. Tengo un conjunto verificado de coordenadas XYZ ECI ( http://en.wikipedia.org/wiki/Earth-centered_inertial ) y un conjunto verificado de coordenadas ECEF ( http://en.wikipedia.org/wiki/ECEF ) XYZ.
For example ( m ):
ECEF X 4076514.50
ECEF Y 14673598.00
ECEF Z -21793674.00
ECI X 8004604.50
ECI Y 12956032.00
ECI Z -21793674.00
A veces, los signos de las coordenadas ECI X e Y son opuestos a los signos de las coordenadas ECEF X e Y.
Cuando trazo estas ubicaciones en un globo y, obviamente, no coinciden a menos que gire la tierra en algún número de radianes. Puedo ver que si rotas la tierra, las coordenadas ECI siguen una trayectoria terrestre que es consistente con la trayectoria terrestre ECEF, pero con mi código actual, se compensa en diferentes cantidades variables, según la hora del día en que lo trazo.
Aquí está mi código:
// The radians earth rotates in 1 second
double earthRotation = 0.000072921151467;
// Do something different depending on the switch position
if ( self.shouldAnimate == true ) {
// The seconds since we started rotating
double newRotationMultiplier = [self.eciDate timeIntervalSinceDate:self.lastEciDate];
// Seconds // Rad/Sec // Multiplier
self.timeSinceOpenGlStarted = newRotationMultiplier * earthRotation;
matrixToRotate = GLKMatrix4Rotate(matrixToRotate, self.timeSinceOpenGlStarted, 0.0, 0.0, 1.0);
// Latch it so that when we stop rotating, it doesn't revert
self.effect.transform.modelviewMatrix = matrixToRotate;
}
¿Cómo determino los radianes para rotar la tierra para mostrar las posiciones ECI durante un tiempo para que sea la misma ubicación en el globo rotado (en términos de latitud y longitud)? Es decir, ¿cómo calculo para cualquier hora UTC en un día, cuánto girar la tierra sobre el eje Z ("Arriba") para que las coordenadas ECI coincidan con las coordenadas ECEF y los satélites parezcan estar en la misma posición? sobre mi globo 3D?
ACTUALIZAR:
Lo hice funcionar, ¡gracias a la respuesta a continuación! Aquí está el código:
// Get the NSDate components
NSCalendar *currentCalendar = [NSCalendar currentCalendar];
[currentCalendar setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]];
NSDateComponents *components = [currentCalendar components:NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit fromDate:self.eciDate];
[components setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]];
NSInteger hour = [components hour];
NSInteger minute = [components minute];
NSInteger second = [components second];
// Get UTC in terms of decimal hours
float utc = hour + (float)minute/60.0f + (float)second/3600.0f; // UTC is expressed in hours as a decimal number
//NSLog(@"UTC: %f H %f M %f S %f",utc,(float)hour,(float)minute/60.0f ,(float)second/3600.0f);
// Get the seconds since the last vernal equinox
double secondsSinceVernalEquinox = [self.eciDate timeIntervalSinceDate:appDelegate.lastVernalEquinox];
// Do the math
// http://physics.stackexchange.com/questions/98466/radians-to-rotate-earth-to-match-eci-lat-lon-with-ecef-lat-lon
double d = secondsSinceVernalEquinox / ( 60.0 * 60.0 * 24.0 ); // Give decimal days
double p = 365.242187; // Length of tropical year
double result = ( M_PI * 2 / 24 ) * ( utc - 12.0 ) + ( 2 * M_PI * d / p );
//NSLog(@"Radians = %f",result);
// Seconds // Rad/Sec // Multiplier
self.timeSinceOpenGlStarted = result;
matrixToRotate = GLKMatrix4Rotate(matrixToRotate, self.timeSinceOpenGlStarted, 0.0, 0.0, 1.0);
// Latch it so that when we stop rotating, it doesn't revert
self.effect.transform.modelviewMatrix = matrixToRotate;
Descargo de responsabilidad: actualicé mi respuesta anterior cuando encontré una fórmula más precisa.
El ángulo de rotación es el ángulo entre el punto primaveral y el meridiano de Greenwich. Esto también se corresponde con el Tiempo Sideral de Greenwich , convertido a radianes.
Para una hora UTC dada y una fecha dada, la hora sideral (media) de Greenwich correspondiente (en horas y partes decimales de una hora) se puede calcular como
púlsar