Satellite.cpp   Satellite.cpp 
/* /*
* Stellarium * Stellarium
* Copyright (C) 2009 Matthew Gates * Copyright (C) 2009, 2012 Matthew Gates
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2 * as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version. * of the License, or (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, U SA. * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
*/ */
#include "Satellite.hpp" #include "Satellite.hpp"
#include "StelObject.hpp" #include "StelObject.hpp"
#include "StelPainter.hpp" #include "StelPainter.hpp"
#include "StelApp.hpp" #include "StelApp.hpp"
#include "StelLocation.hpp" #include "StelLocation.hpp"
#include "StelCore.hpp" #include "StelCore.hpp"
#include "StelTexture.hpp" #include "StelTexture.hpp"
#include "VecMath.hpp" #include "VecMath.hpp"
#include "StelUtils.hpp" #include "StelUtils.hpp"
#include "StelTranslator.hpp"
#include <QTextStream> #include <QTextStream>
#include <QRegExp> #include <QRegExp>
#include <QDebug> #include <QDebug>
#include <QVariant> #include <QVariant>
#include <QtOpenGL> #include <QtOpenGL>
#include <QSettings> #include <QSettings>
#include <QByteArray> #include <QByteArray>
#include "gsatellite/gTime.hpp" #include "gsatellite/gTime.hpp"
skipping to change at line 53 skipping to change at line 54
StelTextureSP Satellite::hintTexture; StelTextureSP Satellite::hintTexture;
float Satellite::showLabels = true; float Satellite::showLabels = true;
float Satellite::hintBrightness = 0.0; float Satellite::hintBrightness = 0.0;
float Satellite::hintScale = 1.f; float Satellite::hintScale = 1.f;
SphericalCap Satellite::viewportHalfspace = SphericalCap(); SphericalCap Satellite::viewportHalfspace = SphericalCap();
int Satellite::orbitLineSegments = 90; int Satellite::orbitLineSegments = 90;
int Satellite::orbitLineFadeSegments = 4; int Satellite::orbitLineFadeSegments = 4;
int Satellite::orbitLineSegmentDuration = 20; int Satellite::orbitLineSegmentDuration = 20;
bool Satellite::orbitLinesFlag = true; bool Satellite::orbitLinesFlag = true;
Satellite::Satellite(const QVariantMap& map) Satellite::Satellite(const QString& identifier, const QVariantMap& map)
: initialized(false), visible(true), hintColor(0.0,0.0,0.0), : initialized(false), visible(true), newlyAdded(false), orbi
lastUpdated(), pSatWrapper(NULL) tValid(false), hintColor(0.0,0.0,0.0), lastUpdated(), pSatWrapper(NULL)
{ {
// return initialized if the mandatory fields are not present // return initialized if the mandatory fields are not present
if (!map.contains("designation") || !map.contains("tle1") || !map.co if (identifier.isEmpty())
ntains("tle2")) return;
if (!map.contains("name") || !map.contains("tle1") || !map.contains(
"tle2"))
return; return;
font.setPixelSize(16); font.setPixelSize(16);
designation = map.value("designation").toString(); id = identifier;
name = map.value("name").toString();
if (name.isEmpty())
return;
if (map.contains("description")) description = map.value("descriptio n").toString(); if (map.contains("description")) description = map.value("descriptio n").toString();
if (map.contains("visible")) visible = map.value("visible").toBool() ; if (map.contains("visible")) visible = map.value("visible").toBool() ;
if (map.contains("orbitVisible")) orbitVisible = map.value("orbitVis ible").toBool(); if (map.contains("orbitVisible")) orbitVisible = map.value("orbitVis ible").toBool();
if (map.contains("hintColor")) if (map.contains("hintColor"))
{ {
if (map.value("hintColor").toList().count() == 3) if (map.value("hintColor").toList().count() == 3)
{ {
hintColor[0] = map.value("hintColor").toList().at(0) .toDouble(); hintColor[0] = map.value("hintColor").toList().at(0) .toDouble();
hintColor[1] = map.value("hintColor").toList().at(1) .toDouble(); hintColor[1] = map.value("hintColor").toList().at(1) .toDouble();
skipping to change at line 105 skipping to change at line 112
orbitColorNight[1] = 0; orbitColorNight[1] = 0;
orbitColorNight[2] = 0; orbitColorNight[2] = 0;
if (StelApp::getInstance().getVisionModeNight()) if (StelApp::getInstance().getVisionModeNight())
orbitColor = &orbitColorNight; orbitColor = &orbitColorNight;
else else
orbitColor = &orbitColorNormal; orbitColor = &orbitColorNormal;
if (map.contains("comms")) if (map.contains("comms"))
{ {
foreach(const QVariant &comm, map.value("comms").toList()) foreach(const QVariant &comm, map.value("comms").toList())
{ {
QVariantMap commMap = comm.toMap(); QVariantMap commMap = comm.toMap();
commLink c; commLink c;
if (commMap.contains("frequency")) c.frequency = com mMap.value("frequency").toDouble(); if (commMap.contains("frequency")) c.frequency = com mMap.value("frequency").toDouble();
if (commMap.contains("modulation")) c.modulation = c ommMap.value("modulation").toString(); if (commMap.contains("modulation")) c.modulation = c ommMap.value("modulation").toString();
if (commMap.contains("description")) c.description = commMap.value("description").toString(); if (commMap.contains("description")) c.description = commMap.value("description").toString();
comms.append(c); comms.append(c);
} }
} }
if (map.contains("groups")) if (map.contains("groups"))
{ {
foreach(const QVariant &group, map.value("groups").toList() ) foreach(const QVariant &group, map.value("groups").toList())
{ {
if (!groupIDs.contains(group.toString())) if (!groupIDs.contains(group.toString()))
groupIDs << group.toString(); groupIDs << group.toString();
} }
} }
setNewTleElements(map.value("tle1").toString(), map.value("tle2").to QString line1 = map.value("tle1").toString();
String()); QString line2 = map.value("tle2").toString();
setNewTleElements(line1, line2);
internationalDesignator = extractInternationalDesignator(line1);
if (map.contains("lastUpdated")) if (map.contains("lastUpdated"))
{ {
lastUpdated = map.value("lastUpdated").toDateTime(); lastUpdated = QDateTime::fromString(map.value("lastUpdated")
.toString(),
Qt::ISODate);
} }
orbitValid = true;
initialized = true; initialized = true;
} }
Satellite::~Satellite() Satellite::~Satellite()
{ {
if (pSatWrapper != NULL) if (pSatWrapper != NULL)
{
delete pSatWrapper; delete pSatWrapper;
pSatWrapper = NULL;
}
} }
double Satellite::roundToDp(float n, int dp) double Satellite::roundToDp(float n, int dp)
{ {
// round n to dp decimal places // round n to dp decimal places
return floor(n * pow(10., dp) + .5) / pow(10., dp); return floor(n * pow(10., dp) + .5) / pow(10., dp);
} }
QVariantMap Satellite::getMap(void) QVariantMap Satellite::getMap(void)
{ {
QVariantMap map; QVariantMap map;
map["designation"] = designation; map["name"] = name;
map["tle1"] = tleElements.first.data(); map["tle1"] = tleElements.first.data();
map["tle2"] = tleElements.second.data(); map["tle2"] = tleElements.second.data();
if (!description.isEmpty() && description!="") if (!description.isEmpty() && description!="")
map["description"] = description; map["description"] = description;
map["visible"] = visible; map["visible"] = visible;
map["orbitVisible"] = orbitVisible; map["orbitVisible"] = orbitVisible;
QVariantList col, orbitCol; QVariantList col, orbitCol;
col << roundToDp(hintColor[0],3) << roundToDp(hintColor[1], 3) << ro undToDp(hintColor[2], 3); col << roundToDp(hintColor[0],3) << roundToDp(hintColor[1], 3) << ro undToDp(hintColor[2], 3);
orbitCol << roundToDp(orbitColorNormal[0], 3) << roundToDp(orbitColo rNormal[1], 3) << roundToDp(orbitColorNormal[2],3); orbitCol << roundToDp(orbitColorNormal[0], 3) << roundToDp(orbitColo rNormal[1], 3) << roundToDp(orbitColorNormal[2],3);
map["hintColor"] = col; map["hintColor"] = col;
map["orbitColor"] = orbitCol; map["orbitColor"] = orbitCol;
QVariantList commList; QVariantList commList;
foreach(const commLink &c, comms) foreach(const commLink &c, comms)
{ {
QVariantMap commMap; QVariantMap commMap;
commMap["frequency"] = c.frequency; commMap["frequency"] = c.frequency;
if (!c.modulation.isEmpty() && c.modulation != "") commMap[" modulation"] = c.modulation; if (!c.modulation.isEmpty() && c.modulation != "") commMap[" modulation"] = c.modulation;
if (!c.description.isEmpty() && c.description != "") commMap ["description"] = c.description; if (!c.description.isEmpty() && c.description != "") commMap ["description"] = c.description;
commList << commMap; commList << commMap;
} }
map["comms"] = commList; map["comms"] = commList;
QVariantList groupList; QVariantList groupList;
foreach(const QString &g, groupIDs) foreach(const QString &g, groupIDs)
{ {
groupList << g; groupList << g;
} }
map["groups"] = groupList; map["groups"] = groupList;
if (!lastUpdated.isNull()) if (!lastUpdated.isNull())
{ {
map["lastUpdated"] = lastUpdated; // A raw QDateTime is not a recognised JSON data type. --BM
map["lastUpdated"] = lastUpdated.toString(Qt::ISODate);
} }
return map; return map;
} }
float Satellite::getSelectPriority(const StelCore*) const float Satellite::getSelectPriority(const StelCore*) const
{ {
return -10.; return -10.;
} }
QString Satellite::getInfoString(const StelCore *core, const InfoStringGrou p& flags) const QString Satellite::getInfoString(const StelCore *core, const InfoStringGrou p& flags) const
{ {
QString str; QString str;
QTextStream oss(&str); QTextStream oss(&str);
if (flags&Name) if (flags & Name)
{
oss << "<h2>" << name << "</h2>";
if (!description.isEmpty())
oss << description << "<br/>";
}
if (flags & CatalogNumber)
{ {
oss << "<h2>" << designation << "</h2><br>"; QString catalogNumbers;
if (description!="") if (internationalDesignator.isEmpty())
oss << description << "<br>"; catalogNumbers = QString("%1: %2")
.arg(q_("Catalog #"))
.arg(id);
else
catalogNumbers = QString("%1: %2; %3: %4")
.arg(q_("Catalog #"))
.arg(id)
.arg(q_("International Designator")
)
.arg(internationalDesignator);
oss << catalogNumbers << "<br/><br/>";
} }
// Ra/Dec etc. // Ra/Dec etc.
oss << getPositionInfoString(core, flags); oss << getPositionInfoString(core, flags);
if (flags&Extra1) if (flags & Extra1)
{ {
oss << "<p>"; oss << "<br/>";
oss << QString("Range (km): <b>%1</b>").arg(range, 5, 'f', 2 // TRANSLATORS: Slant range: distance between the satellite
) << "<br>"; and the observer
oss << QString("Range rate (km/s): <b>%1</b>").arg(rangeRate oss << QString(q_("Range (km): %1")).arg(range, 5, 'f', 2);
, 5, 'f', 3) << "<br>"; oss << "<br/>";
oss << QString("Altitude (km): <b>%1</b>").arg(height, 5, 'f // TRANSLATORS: Rate at which the distance changes
', 2) << "<br>"; oss << QString(q_("Range rate (km/s): %1")).arg(rangeRate, 5
oss << QString("SubPoint Lat/Long(Deg): <b>%1</b>").arg(lat , 'f', 3);
LongSubPointPosition[0], 5, 'f', 2) << "/"; oss << "<br/>";
oss << QString("<b>%1</b>").arg(latLongSubPointPosition[1], // TRANSLATORS: Satellite altitude
5, 'f', 3); oss << QString(q_("Altitude (km): %1")).arg(height, 5, 'f',
oss << "</p>"; 2);
oss << "<br/>";
oss << "TEME Coordinates(km): "; // TRANSLATORS: %1 and %3 are numbers, %2 and %4 - degree si
oss << QString("<b>X:</b> %1 ").arg(position[0], 5, 'f', 2) gns.
; oss << QString(q_("SubPoint (Lat./Long.): %1%2/%3%4"))
oss << QString("<b>Y:</b> %1 ").arg(position[1], 5, 'f', 2) .arg(latLongSubPointPosition[0], 5, 'f', 2)
; .arg(QChar(0x00B0))
oss << QString("<b>Z:</b> %1 ").arg(position[2], 5, 'f', 2) .arg(latLongSubPointPosition[1], 5, 'f', 3)
<< "<br>"; .arg(QChar(0x00B0));
oss << "TEME Vel(km/s): "; oss << "<br/><br/>";
oss << QString("<b>X:</b> %1 ").arg(velocity[0], 5, 'f', 2)
; //TODO: This one can be done better
oss << QString("<b>Y:</b> %1 ").arg(velocity[1], 5, 'f', 2) const char* xyz = "<b>X:</b> %1, <b>Y:</b> %2, <b>Z:</b> %3"
; ;
oss << QString("<b>Z:</b> %1 ").arg(velocity[2], 5, 'f', 2) QString temeCoords = QString(xyz)
<< "<br>"; .arg(position[0], 5, 'f', 2)
.arg(position[1], 5, 'f', 2)
oss << "Visibility: "; .arg(position[2], 5, 'f', 2);
switch (visibility) // TRANSLATORS: TEME is an Earth-centered inertial coordinat
e system
oss << QString(q_("TEME coordinates (km): %1")).arg(temeCoor
ds);
oss << "<br/>";
QString temeVel = QString(xyz)
.arg(velocity[0], 5, 'f', 2)
.arg(velocity[1], 5, 'f', 2)
.arg(velocity[2], 5, 'f', 2);
// TRANSLATORS: TEME is an Earth-centered inertial coordinat
e system
oss << QString(q_("TEME velocity (km/s): %1")).arg(temeVel);
oss << "<br/>";
//Visibility: Full text
//TODO: Move to a more prominent place.
switch (visibility)
{ {
case RADAR_SUN: case RADAR_SUN:
oss << "Sat&Observer in Sunlit" << "<br>"; oss << q_("The satellite and the observer are in sun light.") << "<br/>";
break; break;
case VISIBLE: case VISIBLE:
oss << "Visible" << "<br>"; oss << q_("The satellite is visible.") << "<br/>";
break; break;
case RADAR_NIGHT: case RADAR_NIGHT:
oss << "Sat. Eclipsed" << "<br>"; oss << q_("The satellite is eclipsed.") << "<br/>";
break; break;
case NOT_VISIBLE: case NOT_VISIBLE:
oss << "Sat. Not Visible" << "<br>"; oss << q_("The satellite is not visible") << "<br/>" ;
break; break;
default: default:
break; break;
} }
} }
if (flags&Extra2 && comms.size() > 0) if (flags&Extra2 && comms.size() > 0)
{ {
foreach(const commLink &c, comms) foreach(const commLink &c, comms)
{ {
double dop = getDoppler(c.frequency); double dop = getDoppler(c.frequency);
double ddop = dop; double ddop = dop;
char sign; char sign;
if (dop<0.) if (dop<0.)
{ {
sign='-'; sign='-';
ddop*=-1; ddop*=-1;
} }
else else
sign='+'; sign='+';
oss << "<p>"; oss << "<br/>";
if (!c.modulation.isEmpty() && c.modulation != "") o ss << " " << c.modulation; if (!c.modulation.isEmpty() && c.modulation != "") o ss << " " << c.modulation;
if (!c.description.isEmpty() && c.description != "") oss << " " << c.description; if (!c.description.isEmpty() && c.description != "") oss << " " << c.description;
if ((!c.modulation.isEmpty() && c.modulation != "") if ((!c.modulation.isEmpty() && c.modulation != "")
|| (!c.description.isEmpty() && c.description != "")) oss << "<br>"; || (!c.description.isEmpty() && c.description != "")) oss << "<br/>";
oss << QString("%1 MHz (%2%3 kHz)</p>").arg(c.freque oss << QString(q_("%1 MHz (%2%3 kHz)"))
ncy, 8, 'f', 5) .arg(c.frequency, 8, 'f', 5)
.arg(sign) .arg(sign)
.arg(ddop, 6, 'f', 3); .arg(ddop, 6, 'f', 3);
oss << "<br/>";
} }
} }
postProcessInfoString(str, flags); postProcessInfoString(str, flags);
return str; return str;
} }
Vec3f Satellite::getInfoColor(void) const Vec3f Satellite::getInfoColor(void) const
{ {
return StelApp::getInstance().getVisionModeNight() ? Vec3f(0.6, 0.0, 0.0) : hintColor; return StelApp::getInstance().getVisionModeNight() ? Vec3f(0.6, 0.0, 0.0) : hintColor;
} }
float Satellite::getVMagnitude(const StelCore*) const float Satellite::getVMagnitude(const StelCore* core, bool withExtinction) c onst
{ {
return 5.0; float extinctionMag=0.0; // track magnitude loss
if (withExtinction && core->getSkyDrawer()->getFlagHasAtmosphere())
{
Vec3d altAz=getAltAzPosApparent(core);
altAz.normalize();
core->getSkyDrawer()->getExtinction().forward(&altAz[2], &extinction
Mag);
}
return 5.0 + extinctionMag;
} }
double Satellite::getAngularSize(const StelCore*) const double Satellite::getAngularSize(const StelCore*) const
{ {
return 0.00001; return 0.00001;
} }
void Satellite::setNewTleElements(const QString& tle1, const QString& tle2) void Satellite::setNewTleElements(const QString& tle1, const QString& tle2)
{ {
if (pSatWrapper) if (pSatWrapper)
skipping to change at line 306 skipping to change at line 368
gSatWrapper *old = pSatWrapper; gSatWrapper *old = pSatWrapper;
pSatWrapper = NULL; pSatWrapper = NULL;
delete old; delete old;
} }
tleElements.first.clear(); tleElements.first.clear();
tleElements.first.append(tle1); tleElements.first.append(tle1);
tleElements.second.clear(); tleElements.second.clear();
tleElements.second.append(tle2); tleElements.second.append(tle2);
pSatWrapper = new gSatWrapper(designation, tle1, tle2); pSatWrapper = new gSatWrapper(id, tle1, tle2);
orbitPoints.clear(); orbitPoints.clear();
} }
void Satellite::update(double) void Satellite::update(double)
{ {
if (pSatWrapper) if (pSatWrapper && orbitValid)
{ {
epochTime = StelApp::getInstance().getCore()->getJDay(); epochTime = StelApp::getInstance().getCore()->getJDay();
pSatWrapper->setEpoch(epochTime); pSatWrapper->setEpoch(epochTime);
position = pSatWrapper->getTEMEPos(); position = pSatWrapper->getTEMEPos();
velocity = pSatWrapper->getTEMEVel(); velocity = pSatWrapper->getTEMEVel();
latLongSubPointPosition = pSatWrapper->getSubPoint(); latLongSubPointPosition = pSatWrapper->getSubPoint();
height = latLongSubPointPosition[2]; height = latLongSubPointPosition[2];
elAzPosition = pSatWrapper->getAltAz(); if (height <= 0.0)
elAzPosition.normalize(); {
// The orbit is no longer valid. Causes include ver
y out of date
// TLE, system date and time out of a reasonable ran
ge, and orbital
// degradation and re-entry of a satellite. In any
of these cases
// we might end up with a problem - usually a crash
of Stellarium
// because of a div/0 or something. To prevent this
, we turn off
// the satellite.
qWarning() << "Satellite has invalid orbit:" << name
;
orbitValid = false;
return;
}
elAzPosition = pSatWrapper->getAltAz();
elAzPosition.normalize();
pSatWrapper->getSlantRange(range, rangeRate); pSatWrapper->getSlantRange(range, rangeRate);
visibility = pSatWrapper->getVisibilityPredict(); visibility = pSatWrapper->getVisibilityPredict();
// Compute orbit points to draw orbit line. // Compute orbit points to draw orbit line.
if (orbitVisible) computeOrbitPoints(); if (orbitVisible) computeOrbitPoints();
} }
} }
double Satellite::getDoppler(double freq) const double Satellite::getDoppler(double freq) const
{ {
double result; double result;
double f = freq * 1000000; double f = freq * 1000000;
result = -f*((rangeRate*1000.0)/SPEED_OF_LIGHT); result = -f*((rangeRate*1000.0)/SPEED_OF_LIGHT);
return result/1000000; return result/1000000;
} }
void Satellite::recalculateOrbitLines(void) void Satellite::recalculateOrbitLines(void)
{ {
orbitPoints.clear(); orbitPoints.clear();
} }
QString Satellite::extractInternationalDesignator(const QString& tle1)
{
QString result;
if (tle1.isEmpty())
return result;
// The designator is encoded as the 3rd group on the first line
QString rawString = tle1.split(' ').at(2);
if (rawString.isEmpty())
return result;
//TODO: Use a regular expression?
bool ok;
int year = rawString.left(2).toInt(&ok);
if (!ok)
return result;
// Y2K bug :) I wonder what NORAD will do in 2057. :)
if (year < 57)
year += 2000;
else
year += 1900;
result = QString::number(year) + "-" + rawString.right(4);
return result;
}
void Satellite::draw(const StelCore* core, StelPainter& painter, float) void Satellite::draw(const StelCore* core, StelPainter& painter, float)
{ {
XYZ = core->altAzToJ2000(elAzPosition); XYZ = core->altAzToJ2000(elAzPosition);
StelApp::getInstance().getVisionModeNight() ? glColor4f(0.6,0.0,0.0, 1.0) : glColor4f(hintColor[0],hintColor[1],hintColor[2], Satellite::hintBri ghtness); StelApp::getInstance().getVisionModeNight() ? glColor4f(0.6,0.0,0.0, 1.0) : glColor4f(hintColor[0],hintColor[1],hintColor[2], Satellite::hintBri ghtness);
StelProjectorP prj = core->getProjection(StelCore::FrameJ2000); StelProjectorP prj = core->getProjection(StelCore::FrameJ2000);
Vec3d xy; Vec3d xy;
if (prj->project(XYZ,xy)) if (prj->project(XYZ,xy))
{ {
if (Satellite::showLabels) if (Satellite::showLabels)
{ {
painter.drawText(xy[0], xy[1], designation, 0, 10, 1 0, false); painter.drawText(xy[0], xy[1], name, 0, 10, 10, fals e);
Satellite::hintTexture->bind(); Satellite::hintTexture->bind();
} }
painter.drawSprite2dMode(xy[0], xy[1], 11); painter.drawSprite2dMode(xy[0], xy[1], 11);
if (orbitVisible && Satellite::orbitLinesFlag) drawOrbit(pai nter); if (orbitVisible && Satellite::orbitLinesFlag) drawOrbit(pai nter);
} }
} }
void Satellite::drawOrbit(StelPainter& painter) void Satellite::drawOrbit(StelPainter& painter)
{ {
Vec3d position,previousPosition; Vec3d position,previousPosition;
glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_2D);
QList<Vec3d>::iterator it= orbitPoints.begin(); QList<Vec3d>::iterator it= orbitPoints.begin();
//First point projection calculation //First point projection calculation
previousPosition.set(it->operator [](0), it->operator [](1), it->op erator [](2)); previousPosition.set(it->operator [](0), it->operator [](1), it->ope rator [](2));
it++; it++;
StelVertexArray vertexArray; StelVertexArray vertexArray;
vertexArray.primitiveType=StelVertexArray::Lines; vertexArray.primitiveType=StelVertexArray::Lines;
//Rest of points //Rest of points
for (int i=1; i<orbitPoints.size(); i++) for (int i=1; i<orbitPoints.size(); i++)
{ {
position.set(it->operator [](0), it->operator [](1), it->op erator [](2)); position.set(it->operator [](0), it->operator [](1), it->ope rator [](2));
it++; it++;
position.normalize(); position.normalize();
previousPosition.normalize(); previousPosition.normalize();
// Draw end (fading) parts of orbit lines one segment at a t ime. // Draw end (fading) parts of orbit lines one segment at a t ime.
if (i<=orbitLineFadeSegments || orbitLineSegments-i < orbitL ineFadeSegments) if (i<=orbitLineFadeSegments || orbitLineSegments-i < orbitL ineFadeSegments)
{ {
painter.setColor((*orbitColor)[0], (*orbitColor)[1], (*orbitColor)[2], hintBrightness * calculateOrbitSegmentIntensity(i)); painter.setColor((*orbitColor)[0], (*orbitColor)[1], (*orbitColor)[2], hintBrightness * calculateOrbitSegmentIntensity(i));
painter.drawGreatCircleArc(previousPosition, positi on, &viewportHalfspace); painter.drawGreatCircleArc(previousPosition, positio n, &viewportHalfspace);
} }
else else
{ {
vertexArray.vertex << previousPosition << position; vertexArray.vertex << previousPosition << position;
} }
previousPosition = position; previousPosition = position;
} }
// Draw center section of orbit in one go // Draw center section of orbit in one go
painter.setColor((*orbitColor)[0], (*orbitColor)[1], (*orbitColor)[2 ], hintBrightness); painter.setColor((*orbitColor)[0], (*orbitColor)[1], (*orbitColor)[2 ], hintBrightness);
painter.drawGreatCircleArcs(vertexArray, &viewportHalfspace); painter.drawGreatCircleArcs(vertexArray, &viewportHalfspace);
glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D);
} }
float Satellite::calculateOrbitSegmentIntensity(int segNum) float Satellite::calculateOrbitSegmentIntensity(int segNum)
skipping to change at line 434 skipping to change at line 536
if (night) if (night)
orbitColor = &orbitColorNight; orbitColor = &orbitColorNight;
else else
orbitColor = &orbitColorNormal; orbitColor = &orbitColorNormal;
} }
void Satellite::computeOrbitPoints() void Satellite::computeOrbitPoints()
{ {
gTimeSpan computeInterval(0, 0, 0, orbitLineSegmentDuration); gTimeSpan computeInterval(0, 0, 0, orbitLineSegmentDuration);
gTimeSpan orbitSpan(0, 0, 0, orbitLineSegments*orbitLineSegmentDurat ion/2); gTimeSpan orbitSpan(0, 0, 0, orbitLineSegments*orbitLineSegmentDurat ion/2);
gTime epochTm; gTime epochTm;
gTime epoch(epochTime); gTime epoch(epochTime);
gTime lastEpochComp(lastEpochCompForOrbit); gTime lastEpochComp(lastEpochCompForOrbit);
Vec3d elAzVector; Vec3d elAzVector;
int diffSlots; int diffSlots;
if (orbitPoints.isEmpty())//Setup orbitPoins if (orbitPoints.isEmpty())//Setup orbitPoins
{ {
epochTm = epoch - orbitSpan; epochTm = epoch - orbitSpan;
for (int i=0; i<=orbitLineSegments; i++) for (int i=0; i<=orbitLineSegments; i++)
{ {
pSatWrapper->setEpoch(epochTm.getGmtTm()); pSatWrapper->setEpoch(epochTm.getGmtTm());
elAzVector = pSatWrapper->getAltAz(); elAzVector = pSatWrapper->getAltAz();
orbitPoints.append(elAzVector); orbitPoints.append(elAzVector);
epochTm += computeInterval; epochTm += computeInterval;
} }
lastEpochCompForOrbit = epochTime; lastEpochCompForOrbit = epochTime;
} }
else if (epochTime > lastEpochCompForOrbit) else if (epochTime > lastEpochCompForOrbit)
{ // compute next orbit point when clock runs forward { // compute next orbit point when clock runs forward
gTimeSpan diffTime = epoch - lastEpochComp; gTimeSpan diffTime = epoch - lastEpochComp;
diffSlots = (int)(diffTime.getDblSeconds()/orbitLin eSegmentDuration); diffSlots = (int)(diffTime.getDblSeconds()/orbitLin eSegmentDuration);
if (diffSlots > 0) if (diffSlots > 0)
{ {
if (diffSlots > orbitLineSegments) if (diffSlots > orbitLineSegments)
{ {
diffSlots = orbitLineSegments + 1; diffSlots = orbitLineSegments + 1;
epochTm = epoch - orbitSpan; epochTm = epoch - orbitSpan;
} }
else else
{ {
epochTm = lastEpochComp + orbitSpan + comp uteInterval; epochTm = lastEpochComp + orbitSpan + comp uteInterval;
} }
for (int i=0; i<diffSlots; i++) for (int i=0; i<diffSlots; i++)
{ //remove points at beginning of list and add poin {
ts at end. //remove points at beginning of list and add
points at end.
orbitPoints.removeFirst(); orbitPoints.removeFirst();
pSatWrapper->setEpoch(epochTm.getGmtTm()); pSatWrapper->setEpoch(epochTm.getGmtTm());
elAzVector = pSatWrapper->getAltAz(); elAzVector = pSatWrapper->getAltAz();
orbitPoints.append(elAzVector); orbitPoints.append(elAzVector);
epochTm += computeInterval; epochTm += computeInterval;
} }
lastEpochCompForOrbit = epochTime; lastEpochCompForOrbit = epochTime;
} }
} }
else if (epochTime < lastEpochCompForOrbit) else if (epochTime < lastEpochCompForOrbit)
{ // compute next orbit point when clock runs backward { // compute next orbit point when clock runs backward
gTimeSpan diffTime = lastEpochComp - epoch; gTimeSpan diffTime = lastEpochComp - epoch;
diffSlots = (int)(diffTime.getDblSeconds()/orbitLin eSegmentDuration); diffSlots = (int)(diffTime.getDblSeconds()/orbitLin eSegmentDuration);
if (diffSlots > 0) if (diffSlots > 0)
{ {
if (diffSlots > orbitLineSegments) if (diffSlots > orbitLineSegments)
{ {
diffSlots = orbitLineSegments + 1; diffSlots = orbitLineSegments + 1;
epochTm = epoch + orbitSpan; epochTm = epoch + orbitSpan;
} }
else else
{ {
epochTm = epoch - orbitSpan - computeInte rval; epochTm = epoch - orbitSpan - computeInter val;
} }
for (int i=0; i<diffSlots; i++) for (int i=0; i<diffSlots; i++)
{ //remove points at end of list and add points at b eginning. { //remove points at end of list and add points at b eginning.
orbitPoints.removeLast(); orbitPoints.removeLast();
pSatWrapper->setEpoch(epochTm.getGmtTm()); pSatWrapper->setEpoch(epochTm.getGmtTm());
elAzVector = pSatWrapper->getAltAz(); elAzVector = pSatWrapper->getAltAz();
orbitPoints.push_front(elAzVector); orbitPoints.push_front(elAzVector);
epochTm -= computeInterval; epochTm -= computeInterval;
} }
lastEpochCompForOrbit = epochTime; lastEpochCompForOrbit = epochTime;
} }
} }
} }
 End of changes. 58 change blocks. 
107 lines changed or deleted 214 lines changed or added

This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/