QString Quasar::getInfoString(const StelCore* core, const InfoStringGroup& flags) const { QString str; QTextStream oss(&str); double mag = getVMagnitude(core, false); if (flags&Name) { oss << "<h2>" << designation << "</h2>"; } if (flags&Extra1) oss << q_("Type: <b>%1</b>").arg(q_("quasar")) << "<br />"; if (flags&Magnitude) { if (core->getSkyDrawer()->getFlagHasAtmosphere()) { if (bV!=0) { oss << q_("Magnitude: <b>%1</b> (extincted to: <b>%2</b>. B-V: <b>%3</b>)").arg(QString::number(mag, 'f', 2), QString::number(getVMagnitude(core, true), 'f', 2), QString::number(bV, 'f', 2)) << "<br />"; } else { oss << q_("Magnitude: <b>%1</b> (extincted to: <b>%2</b>)").arg(QString::number(mag, 'f', 2), QString::number(getVMagnitude(core, true), 'f', 2)) << "<br />"; } } else { if (bV!=0) { oss << q_("Magnitude: <b>%1</b> (B-V: <b>%2</b>)").arg(mag, 0, 'f', 2).arg(bV, 0, 'f', 2) << "<br />"; } else { oss << q_("Magnitude: <b>%1</b>").arg(mag, 0, 'f', 2) << "<br />"; } } if (AMagnitude!=0) { oss << q_("Absolute Magnitude: %1").arg(AMagnitude, 0, 'f', 2) << "<br />"; } } // Ra/Dec etc. oss << getPositionInfoString(core, flags); if (flags&Extra1) { if (redshift>0) { oss << q_("Z (redshift): %1").arg(redshift) << "<br />"; } } postProcessInfoString(str, flags); return str; }
float Nebula::getSurfaceBrightness(const StelCore* core) const { if (getVMagnitude(core)<99 && angularSize>0 && nType!=NebDn && nType!=NebHII) return getVMagnitude(core) + 2.5*log10(M_PI*pow((angularSize*M_PI/180.)*1800,2)); else return 99; }
void Supernova::draw(StelCore* core, StelPainter& painter) { StelSkyDrawer* sd = core->getSkyDrawer(); Vec3f color = Vec3f(1.f,1.f,1.f); if (StelApp::getInstance().getVisionModeNight()) color = StelUtils::getNightColor(color); float rcMag[2], size, shift; double mag; StelUtils::spheToRect(snra, snde, XYZ); mag = getVMagnitude(core, true); sd->preDrawPointSource(&painter); if (mag <= sd->getLimitMagnitude()) { sd->computeRCMag(mag, rcMag); // sd->drawPointSource(&painter, Vec3f(XYZ[0], XYZ[1], XYZ[2]), rcMag, color, false); sd->drawPointSource(&painter, XYZ, rcMag, color, false); painter.setColor(color[0], color[1], color[2], 1); size = getAngularSize(NULL)*M_PI/180.*painter.getProjector()->getPixelPerRadAtCenter(); shift = 6.f + size/1.8f; if (labelsFader.getInterstate()<=0.f) { painter.drawText(XYZ, designation, 0, shift, shift, false); } } sd->postDrawPointSource(&painter); }
void Galaxy::draw(StelCore* core, StelPainter& painter, float) { StelSkyDrawer* sd = core->getSkyDrawer(); Vec3f color = Vec3f(0.4f,0.5f,1.2f); if (StelApp::getInstance().getVisionModeNight()) color = StelUtils::getNightColor(color); double mag = getVMagnitude(core, true); StelUtils::spheToRect(RA, DE, XYZ); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); glEnable(GL_TEXTURE_2D); painter.setColor(color[0], color[1], color[2], Galaxy::galaxyBrightness); glColor4f(color[0],color[1],color[2], Galaxy::galaxyBrightness); if (mag <= sd->getLimitMagnitude()) { Galaxy::markerTexture->bind(); float size = getAngularSize(NULL)*M_PI/180.*painter.getProjector()->getPixelPerRadAtCenter(); float shift = 5.f + size/1.6f; if (GETSTELMODULE(POGS)->getDisplayMode()) { painter.drawSprite2dMode(XYZ, 6); painter.drawText(XYZ, " ", 0, shift, shift, false); } else { painter.drawSprite2dMode(XYZ, 6); painter.drawText(XYZ, designation, 0, shift, shift, false); } } }
void Quasar::draw(StelCore* core, StelRenderer* renderer, StelProjectorP projector, StelTextureNew* markerTexture) { StelSkyDrawer* sd = core->getSkyDrawer(); const Vec3f color = sd->indexToColor(BvToColorIndex(bV))*0.75f; Vec3f dcolor = Vec3f(1.2f,0.5f,0.4f); if (StelApp::getInstance().getVisionModeNight()) dcolor = StelUtils::getNightColor(dcolor); float rcMag[2], size, shift; double mag; StelUtils::spheToRect(qRA, qDE, XYZ); mag = getVMagnitude(core, true); if (GETSTELMODULE(Quasars)->getDisplayMode()) { renderer->setBlendMode(BlendMode_Add); renderer->setGlobalColor(dcolor[0], dcolor[1], dcolor[2], 1); markerTexture->bind(); if (labelsFader.getInterstate()<=0.f) { Vec3d win; if(projector->project(XYZ, win)) { renderer->drawTexturedRect(win[0] - 4, win[1] - 4, 8, 8); } } } else { sd->preDrawPointSource(); if (mag <= sd->getLimitMagnitude()) { sd->computeRCMag(mag, rcMag); const Vec3f XYZf(XYZ[0], XYZ[1], XYZ[2]); Vec3f win; if(sd->pointSourceVisible(&(*projector), XYZf, rcMag, false, win)) { sd->drawPointSource(win, rcMag, sd->indexToColor(BvToColorIndex(bV))); } renderer->setGlobalColor(color[0], color[1], color[2], 1.0f); size = getAngularSize(NULL)*M_PI/180.*projector->getPixelPerRadAtCenter(); shift = 6.f + size/1.8f; if (labelsFader.getInterstate()<=0.f) { renderer->drawText(TextParams(XYZ, projector, designation).shift(shift, shift).useGravity()); } } sd->postDrawPointSource(projector); } }
QString Supernova::getInfoString(const StelCore* core, const InfoStringGroup& flags) const { QString str; QTextStream oss(&str); double mag = getVMagnitude(core, false); if (flags&Name) { oss << "<h2>" << designation; if (note.size()!=0) oss << " (" << q_(note) << ")"; oss << "</h2>"; } if (flags&Extra1) oss << q_("Type: <b>%1</b>").arg(q_("supernova")) << "<br />"; if (flags&Magnitude && mag <= core->getSkyDrawer()->getLimitMagnitude()) { if (core->getSkyDrawer()->getFlagHasAtmosphere()) oss << q_("Magnitude: <b>%1</b> (extincted to: <b>%2</b>)").arg(QString::number(getVMagnitude(core, false), 'f', 2), QString::number(getVMagnitude(core, true), 'f', 2)) << "<br>"; else oss << q_("Magnitude: <b>%1</b>").arg(mag, 0, 'f', 2) << "<br>"; } // Ra/Dec etc. oss << getPositionInfoString(core, flags); if (flags&Extra1) { oss << q_("Type of supernova: %1").arg(sntype) << "<br>"; if (distance>0) oss << q_("Distance: %1 Light Years").arg(distance*1000) << "<br>"; } postProcessInfoString(str, flags); return str; }
void Quasar::draw(StelCore* core, StelPainter& painter) { StelSkyDrawer* sd = core->getSkyDrawer(); Vec3f color = sd->indexToColor(BvToColorIndex(bV))*0.75f; Vec3f dcolor = Vec3f(1.2f,0.5f,0.4f); if (StelApp::getInstance().getVisionModeNight()) dcolor = StelUtils::getNightColor(dcolor); float rcMag[2], size, shift; double mag; StelUtils::spheToRect(qRA, qDE, XYZ); mag = getVMagnitude(core, true); if (GETSTELMODULE(Quasars)->getDisplayMode()) { glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE); painter.setColor(dcolor[0], dcolor[1], dcolor[2], 1); Quasar::markerTexture->bind(); size = getAngularSize(NULL)*M_PI/180.*painter.getProjector()->getPixelPerRadAtCenter(); shift = 5.f + size/1.6f; if (labelsFader.getInterstate()<=0.f) { painter.drawSprite2dMode(XYZ, 4); painter.drawText(XYZ, " ", 0, shift, shift, false); } } else { sd->preDrawPointSource(&painter); if (mag <= sd->getLimitMagnitude()) { sd->computeRCMag(mag, rcMag); //sd->drawPointSource(&painter, Vec3f(XYZ[0], XYZ[1], XYZ[2]), rcMag, sd->indexToColor(BvToColorIndex(bV)), false); sd->drawPointSource(&painter, XYZ, rcMag, sd->indexToColor(BvToColorIndex(bV)), false); painter.setColor(color[0], color[1], color[2], 1); size = getAngularSize(NULL)*M_PI/180.*painter.getProjector()->getPixelPerRadAtCenter(); shift = 6.f + size/1.8f; if (labelsFader.getInterstate()<=0.f) { painter.drawText(XYZ, designation, 0, shift, shift, false); } } sd->postDrawPointSource(&painter); } }
float Nebula::getSelectPriority(const StelCore* core) const { const NebulaMgr* nebMgr = ((NebulaMgr*)StelApp::getInstance().getModuleMgr().getModule("NebulaMgr")); if (!nebMgr->getFlagHints()) return StelObject::getSelectPriority(core)-2.f; const float maxMagHint = nebMgr->computeMaxMagHint(core->getSkyDrawer()); // make very easy to select if labeled if (std::min(15.f, getVMagnitude(core))<maxMagHint) return -10.f; else return StelObject::getSelectPriority(core)-2.f; }
QString StarWrapperBase::getInfoString(const StelCore *core, const InfoStringGroup& flags) const { QString str; QTextStream oss(&str); if (flags&Magnitude) { oss << q_("Magnitude: <b>%1</b> (B-V: %2)").arg(QString::number(getVMagnitude(core, false), 'f', 2), QString::number(getBV(), 'f', 2)) << "<br>"; if (core->getSkyDrawer()->getFlagHasAtmosphere()) { oss << q_("Apparent Magnitude: <b>%1</b> (by extinction)").arg(QString::number(getVMagnitude(core, true), 'f', 2)) << "<br>"; } } oss << getPositionInfoString(core, flags); StelObject::postProcessInfoString(str, flags); return str; }
float Nebula::getSelectPriority(const StelCore* core) const { const NebulaMgr* nebMgr = ((NebulaMgr*)StelApp::getInstance().getModuleMgr().getModule("NebulaMgr")); if (!nebMgr->getFlagHints()) return StelObject::getSelectPriority(core)-2.f; const float maxMagHint = nebMgr->computeMaxMagHint(core->getSkyDrawer()); // make very easy to select if labeled float lim=getVMagnitude(core); if (nType==NebDn) lim=15.0f - mag - 2.0f*angularSize; // Note that "mag" field is used for opacity in this catalog! else if (nType==NebHII) lim=10.0f - 2.0f*angularSize; // Unfortunately, in Sh catalog, we always have mag=99=unknown! if (std::min(15.f, lim)<maxMagHint) return -10.f; else return StelObject::getSelectPriority(core)-2.f; }
QString Nova::getInfoString(const StelCore* core, const InfoStringGroup& flags) const { QString str; QTextStream oss(&str); double mag = getVMagnitude(core); if (flags&Name) { QString name = novaName.isEmpty() ? QString("<h2>%1</h2>").arg(designation) : QString("<h2>%1 (%2)</h2>").arg(novaName).arg(designation); oss << name; } if (flags&ObjectType) oss << q_("Type: <b>%1</b> (%2)").arg(q_("nova")).arg(novaType) << "<br />"; if (flags&Magnitude) { if (core->getSkyDrawer()->getFlagHasAtmosphere()) oss << q_("Magnitude: <b>%1</b> (extincted to: <b>%2</b>)").arg(QString::number(mag, 'f', 2), QString::number(getVMagnitudeWithExtinction(core), 'f', 2)) << "<br>"; else oss << q_("Magnitude: <b>%1</b>").arg(mag, 0, 'f', 2) << "<br>"; } // Ra/Dec etc. oss << getPositionInfoString(core, flags); if (flags&Extra) { oss << q_("Maximum brightness: %1").arg(getMaxBrightnessDate(peakJD)) << "<br>"; if (distance>0) { //TRANSLATORS: Unit of measure for distance - Light Years oss << q_("Distance: %1 ly").arg(distance*1000) << "<br>"; } } postProcessInfoString(str, flags); return str; }
float Supernova::getSelectPriority(const StelCore* core) const { //Same as StarWrapper::getSelectPriority() return getVMagnitude(core, false); }
QString Comet::getInfoString(const StelCore *core, const InfoStringGroup &flags) const { //Mostly copied from Planet::getInfoString(): QString str; QTextStream oss(&str); if (flags&Name) { oss << "<h2>"; oss << q_(englishName); // UI translation can differ from sky translation oss.setRealNumberNotation(QTextStream::FixedNotation); oss.setRealNumberPrecision(1); if (sphereScale != 1.f) oss << QString::fromUtf8(" (\xC3\x97") << sphereScale << ")"; oss << "</h2>"; } if (flags&Extra1) { if (pType.length()>0) oss << q_("Type: <b>%1</b>").arg(q_(pType)) << "<br />"; } if (flags&Magnitude) { if (core->getSkyDrawer()->getFlagHasAtmosphere()) oss << q_("Magnitude: <b>%1</b> (extincted to: <b>%2</b>)").arg(QString::number(getVMagnitude(core, false), 'f', 2), QString::number(getVMagnitude(core, true), 'f', 2)) << "<br>"; else oss << q_("Magnitude: <b>%1</b>").arg(getVMagnitude(core, false), 0, 'f', 2) << "<br>"; } if (flags&AbsoluteMagnitude) { //TODO: Make sure absolute magnitude is a sane value //If the two parameter magnitude system is not use, don't display this //value. (Using radius/albedo doesn't make any sense for comets.) if (slopeParameter >= 0) oss << q_("Absolute Magnitude: %1").arg(absoluteMagnitude, 0, 'f', 2) << "<br>"; } oss << getPositionInfoString(core, flags); if (flags&Distance) { double distanceAu = getJ2000EquatorialPos(core).length(); if (distanceAu < 0.1) { double distanceKm = AU * distanceAu; // xgettext:no-c-format oss << QString(q_("Distance: %1AU (%2 km)")) .arg(distanceAu, 0, 'f', 8) .arg(distanceKm, 0, 'f', 0); } else { // xgettext:no-c-format oss << q_("Distance: %1AU").arg(distanceAu, 0, 'f', 8); } oss << "<br>"; } /* if (flags&Size) oss << q_("Apparent diameter: %1").arg(StelUtils::radToDmsStr(2.*getAngularSize(core)*M_PI/180., true)); */ // If semi-major axis not zero then calculate and display orbital period for comet in days double siderealPeriod = getSiderealPeriod(); if ((flags&Extra1) && (siderealPeriod>0)) { // TRANSLATORS: Sidereal (orbital) period for solar system bodies in days and in Julian years (symbol: a) oss << q_("Sidereal period: %1 days (%2 a)").arg(QString::number(siderealPeriod, 'f', 2)).arg(QString::number(siderealPeriod/365.25, 'f', 3)) << "<br>"; } postProcessInfoString(str, flags); return str; }
QString StarWrapper1::getInfoString(const StelCore *core, const InfoStringGroup& flags) const { QString str; QTextStream oss(&str); if (s->hip) { if ((flags&Name) || (flags&CatalogNumber)) oss << "<h2>"; const QString commonNameI18 = StarMgr::getCommonName(s->hip); const QString sciName = StarMgr::getSciName(s->hip); bool nameWasEmpty=true; if (flags&Name) { if (commonNameI18!="" || sciName!="") { oss << commonNameI18 << (commonNameI18 == "" ? "" : " "); if (commonNameI18!="" && sciName!="") oss << "("; oss << (sciName=="" ? "" : sciName); if (commonNameI18!="" && sciName!="") oss << ")"; nameWasEmpty=false; } } if ((flags&CatalogNumber) && (flags&Name) && !nameWasEmpty) oss << " - "; if (flags&CatalogNumber || (nameWasEmpty && (flags&Name))) oss << "HIP " << s->hip; if (s->componentIds) oss << " " << StarMgr::convertToComponentIds(s->componentIds); if ((flags&Name) || (flags&CatalogNumber)) oss << "</h2>"; } if (flags&Magnitude) { if (core->getSkyDrawer()->getFlagHasAtmosphere()) oss << q_("Magnitude: <b>%1</b> (extincted to: <b>%2</b>. B-V: <b>%3</b>)").arg(QString::number(getVMagnitude(core, false), 'f', 2), QString::number(getVMagnitude(core, true), 'f', 2), QString::number(s->getBV(), 'f', 2)) << "<br>"; else oss << q_("Magnitude: <b>%1</b> (B-V: <b>%2</b>)").arg(QString::number(getVMagnitude(core, false), 'f', 2), QString::number(s->getBV(), 'f', 2)) << "<br>"; } if ((flags&AbsoluteMagnitude) && s->plx && !isNan(s->plx) && !isInf(s->plx)) oss << q_("Absolute Magnitude: %1").arg(getVMagnitude(core, false)+5.*(1.+std::log10(0.00001*s->plx)), 0, 'f', 2) << "<br>"; oss << getPositionInfoString(core, flags); if (s->spInt && flags&Extra1) { oss << q_("Spectral Type: %1").arg(StarMgr::convertToSpectralType(s->spInt)) << "<br>"; } if ((flags&Distance) && s->plx && !isNan(s->plx) && !isInf(s->plx)) oss << q_("Distance: %1 Light Years").arg((AU/(SPEED_OF_LIGHT*86400*365.25)) / (s->plx*((0.00001/3600)*(M_PI/180))), 0, 'f', 2) << "<br>"; if (s->plx && flags&Extra2) oss << q_("Parallax: %1\"").arg(0.00001*s->plx, 0, 'f', 5) << "<br>"; StelObject::postProcessInfoString(str, flags); return str; }
QString Nebula::getInfoString(const StelCore *core, const InfoStringGroup& flags) const { QString str; QTextStream oss(&str); if ((flags&Name) || (flags&CatalogNumber)) oss << "<h2>"; if (nameI18!="" && flags&Name) { oss << getNameI18n(); } if (flags&CatalogNumber) { if (nameI18!="" && flags&Name) oss << " ("; QStringList catIds; if ((M_nb > 0) && (M_nb < 111)) catIds << QString("M %1").arg(M_nb); if (NGC_nb > 0) catIds << QString("NGC %1").arg(NGC_nb); if (IC_nb > 0) catIds << QString("IC %1").arg(IC_nb); if ((C_nb > 0) && (C_nb < 110)) catIds << QString("C %1").arg(C_nb); oss << catIds.join(" - "); if (nameI18!="" && flags&Name) oss << ")"; } if ((flags&Name) || (flags&CatalogNumber)) oss << "</h2>"; if (flags&ObjectType) oss << q_("Type: <b>%1</b>").arg(getTypeString()) << "<br>"; if (mag < 50 && flags&Magnitude) { if (core->getSkyDrawer()->getFlagHasAtmosphere()) { oss << q_("Magnitude: <b>%1</b> (extincted to: <b>%2</b>)").arg(QString::number(getVMagnitude(core), 'f', 2), QString::number(getVMagnitudeWithExtinction(core), 'f', 2)) << "<br>"; if (getSurfaceBrightness(core)<99 && getSurfaceBrightnessWithExtinction(core)<99) oss << q_("Surface brightness: <b>%1</b> (extincted to: <b>%2</b>)").arg(QString::number(getSurfaceBrightness(core), 'f', 2), QString::number(getSurfaceBrightnessWithExtinction(core), 'f', 2)) << "<br>"; } else { oss << q_("Magnitude: <b>%1</b>").arg(getVMagnitude(core), 0, 'f', 2) << "<br>"; if (getSurfaceBrightness(core)<99) oss << q_("Surface brightness: <b>%1</b>").arg(QString::number(getSurfaceBrightness(core), 'f', 2)) << "<br>"; } } oss << getPositionInfoString(core, flags); if (angularSize>0 && flags&Size) oss << q_("Size: %1").arg(StelUtils::radToDmsStr(angularSize*M_PI/180.)) << "<br>"; postProcessInfoString(str, flags); return str; }
QString MinorPlanet::getInfoString(const StelCore *core, const InfoStringGroup &flags) const { //Mostly copied from Planet::getInfoString(): QString str; QTextStream oss(&str); if (flags&Name) { oss << "<h2>"; if (minorPlanetNumber) oss << QString("(%1) ").arg(minorPlanetNumber); if (nameIsProvisionalDesignation) oss << provisionalDesignationHtml; else oss << q_(properName); // UI translation can differ from sky translation oss.setRealNumberNotation(QTextStream::FixedNotation); oss.setRealNumberPrecision(1); if (sphereScale != 1.f) oss << QString::fromUtf8(" (\xC3\x97") << sphereScale << ")"; oss << "</h2>"; if (!nameIsProvisionalDesignation && !provisionalDesignationHtml.isEmpty()) { oss << QString(q_("Provisional designation: %1")).arg(provisionalDesignationHtml); oss << "<br>"; } } if (flags&ObjectType) { if (pType.length()>0) oss << q_("Type: <b>%1</b>").arg(q_(pType)) << "<br />"; } if (flags&Magnitude) { if (core->getSkyDrawer()->getFlagHasAtmosphere()) oss << q_("Magnitude: <b>%1</b> (extincted to: <b>%2</b>)").arg(QString::number(getVMagnitude(core), 'f', 2), QString::number(getVMagnitudeWithExtinction(core), 'f', 2)) << "<br>"; else oss << q_("Magnitude: <b>%1</b>").arg(getVMagnitude(core), 0, 'f', 2) << "<br>"; } if (flags&AbsoluteMagnitude) { //TODO: Make sure absolute magnitude is a sane value //If the H-G system is not used, use the default radius/albedo mechanism if (slopeParameter < 0) { oss << q_("Absolute Magnitude: %1").arg(getVMagnitude(core) - 5. * (std::log10(getJ2000EquatorialPos(core).length()*AU/PARSEC)-1.), 0, 'f', 2) << "<br>"; } else { oss << q_("Absolute Magnitude: %1").arg(absoluteMagnitude, 0, 'f', 2) << "<br>"; } } oss << getPositionInfoString(core, flags); if (flags&Distance) { double distanceAu = getJ2000EquatorialPos(core).length(); double distanceKm = AU * distanceAu; if (distanceAu < 0.1) { // xgettext:no-c-format oss << QString(q_("Distance: %1AU (%2 km)")) .arg(distanceAu, 0, 'f', 6) .arg(distanceKm, 0, 'f', 3); } else { // xgettext:no-c-format oss << QString(q_("Distance: %1AU (%2 Mio km)")) .arg(distanceAu, 0, 'f', 3) .arg(distanceKm / 1.0e6, 0, 'f', 3); } oss << "<br>"; } if (flags&Size) oss << q_("Apparent diameter: %1").arg(StelUtils::radToDmsStr(2.*getAngularSize(core)*M_PI/180., true)) << "<br>"; // If semi-major axis not zero then calculate and display orbital period for asteroid in days double siderealPeriod = getSiderealPeriod(); if ((flags&Extra) && (siderealPeriod>0)) { // TRANSLATORS: Sidereal (orbital) period for solar system bodies in days and in Julian years (symbol: a) oss << q_("Sidereal period: %1 days (%2 a)").arg(QString::number(siderealPeriod, 'f', 2)).arg(QString::number(siderealPeriod/365.25, 'f', 3)) << "<br>"; } //This doesn't work, even if setOpenExternalLinks(true) is used in InfoPanel /* if (flags&Extra) oss << QString("<br><a href=\"http://ssd.jpl.nasa.gov/sbdb.cgi?sstr=%1\">JPL Small-Body Database Browser</a>").arg( (minorPlanetNumber) ? QString::number(minorPlanetNumber) : englishName ); */ postProcessInfoString(str, flags); return str; }
void Comet::drawTail(StelCore* core, StelProjector::ModelViewTranformP transfo, bool gas) { // Find rotation matrix from 0/0/1 to eclipticPosition: crossproduct for axis (normal vector), dotproduct for angle. Vec3d eclposNrm=eclipticPos; eclposNrm.normalize(); Mat4d tailrot=Mat4d::rotation(Vec3d(0.0, 0.0, 1.0)^(eclposNrm), std::acos(Vec3d(0.0, 0.0, 1.0).dot(eclposNrm)) ); StelProjector::ModelViewTranformP transfo2 = transfo->clone(); transfo2->combine(tailrot); if (!gas) { CometOrbit* orbit=(CometOrbit*)userDataPtr; Vec3d velocity=orbit->getVelocity(); // [AU/d] // This was a try to rotate a straight parabola somewhat away from the antisolar direction. //Mat4d dustTailRot=Mat4d::rotation(eclposNrm^(-velocity), 0.15f*std::acos(eclposNrm.dot(-velocity))); // GZ: This scale factor of 0.15 is empirical from photos of Halley and Hale-Bopp. // The curved tail is curved towards positive X. We first rotate around the Z axis into a direction opposite of the motion vector, then again the antisolar rotation applies. Mat4d dustTailRot=Mat4d::zrotation(atan2(velocity[1], velocity[0]) + M_PI); transfo2->combine(dustTailRot); // In addition, we let the dust tail already start with a light tilt. Mat4d dustTailYrot=Mat4d::yrotation(5.0f*velocity.length()); // again, this is pretty ad-hoc, feel free to improve! transfo2->combine(dustTailYrot); } StelPainter* sPainter = new StelPainter(core->getProjection(transfo2)); glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE); glDisable(GL_CULL_FACE); // GZ: If we use getVMagnitudeWithExtinction(), a head extincted in the horizon mist can completely hide an otherwise frighteningly long tail. // we must use unextincted mag, but mix/dim with atmosphere/sky brightness. // In addition, light falloff is a bit reduced for better visibility. Power basis should be 0.4, we use 0.6. //float magfactor=std::pow(0.4f , getVMagnitudeWithExtinction(core)); float magFactor=std::pow(0.6f , getVMagnitude(core)); if (core->getSkyDrawer()->getFlagHasAtmosphere()) { // Mix with sky brightness and light pollution: This is very ad-hoc, if someone finds a better solution, please go ahead! // Light pollution: float bortleIndexFactor=0.1f * (11 - core->getSkyDrawer()->getBortleScaleIndex()); magFactor*= bortleIndexFactor*bortleIndexFactor; // GZ-Guesstimate for light pollution influence // sky brightness: This is about 10 for twilight where bright comet tails should already be visible. Dark night is close to 0. float avgAtmLum=GETSTELMODULE(LandscapeMgr)->getAtmosphereAverageLuminance(); float atmLumFactor=(15.0f-avgAtmLum)/15.0f; if (atmLumFactor<0.05f) atmLumFactor=0.05f; //atmLumFactor=std::sqrt(atmLumFactor); magFactor*=atmLumFactor*atmLumFactor; } magFactor*=(gas? 0.9 : dustTailBrightnessFactor); // TBD: empirical adjustment for texture brightness. magFactor=qMin(magFactor, 1.05f); // Limit excessively bright display. gasTailTexture->bind(); if (gas) { //gasTailTexture->bind(); sPainter->setColor(0.15f*magFactor,0.15f*magFactor,0.6f*magFactor); sPainter->setArrays((Vec3d*)gastailVertexArr.constData(), (Vec2f*)gastailTexCoordArr.constData()); sPainter->drawFromArray(StelPainter::Triangles, gastailIndices.size(), 0, true, gastailIndices.constData()); } else { //dustTailTexture->bind(); sPainter->setColor(magFactor, magFactor,0.6f*magFactor); //sPainter->setArrays((Vec3d*)dusttailVertexArr.constData(), (Vec2f*)dusttailTexCoordArr.constData()); //sPainter->drawFromArray(StelPainter::Triangles, dusttailIndices.size(), 0, true, dusttailIndices.constData()); sPainter->setArrays((Vec3d*)dusttailVertexArr.constData(), (Vec2f*)gastailTexCoordArr.constData()); sPainter->drawFromArray(StelPainter::Triangles, gastailIndices.size(), 0, true, gastailIndices.constData()); } glDisable(GL_BLEND); if (sPainter) delete sPainter; sPainter=NULL; }
// Draw the Comet and all the related infos : name, circle etc... GZ: Taken from Planet.cpp 2013-11-05 and extended void Comet::draw(StelCore* core, float maxMagLabels, const QFont& planetNameFont) { if (hidden) return; if (getEnglishName() == core->getCurrentLocation().planetName) { // GZ moved this up. Maybe even don't do that? E.g., draw tail while riding the comet? Decide later. return; } // The CometOrbit is in fact available in userDataPtr! CometOrbit* orbit=(CometOrbit*)userDataPtr; Q_ASSERT(orbit); if (!orbit->objectDateValid(core->getJDay())) return; // out of useful date range. This allows having hundreds of comet elements. if (orbit->getUpdateTails()){ // Compute lengths and orientations from orbit object, but only if required. // TODO: This part should possibly be moved to another thread to keep draw() free from too much computation. Vec2f tailFactors=getComaDiameterAndTailLengthAU(); float gasTailEndRadius=qMax(tailFactors[0], 0.025f*tailFactors[1]) ; // This avoids too slim gas tails for bright comets like Hale-Bopp. float gasparameter=gasTailEndRadius*gasTailEndRadius/(2.0f*tailFactors[1]); // parabola formula: z=r²/2p, so p=r²/2z // The dust tail is thicker and usually shorter. The factors can be configured in the elements. float dustparameter=gasTailEndRadius*gasTailEndRadius*dustTailWidthFactor*dustTailWidthFactor/(2.0f*dustTailLengthFactor*tailFactors[1]); // Find valid parameters to create paraboloid vertex arrays: dustTail, gasTail. computeParabola(gasparameter, gasTailEndRadius, -0.5f*gasparameter, gastailVertexArr, gastailTexCoordArr, gastailIndices); // This was for a rotated straight parabola: //computeParabola(dustparameter, 2.0f*tailFactors[0], -0.5f*dustparameter, dusttailVertexArr, dusttailTexCoordArr, dusttailIndices); // Now we make a skewed parabola. Skew factor 15 (last arg) ad-hoc/empirical. TBD later: Find physically correct solution. computeParabola(dustparameter, dustTailWidthFactor*gasTailEndRadius, -0.5f*dustparameter, dusttailVertexArr, gastailTexCoordArr, gastailIndices, 25.0f*orbit->getVelocity().length()); // Note that we use a diameter larger than what the formula returns. A scale factor of 1.2 is ad-hoc/empirical (GZ), but may look better. computeComa(1.0f*tailFactors[0]); orbit->setUpdateTails(false); // don't update until position has been recalculated elsewhere } Mat4d mat = Mat4d::translation(eclipticPos) * rotLocalToParent; /* // We can remove that - a Comet has no parent except for the sun... PlanetP p = parent; while (p && p->parent) { mat = Mat4d::translation(p->eclipticPos) * mat * p->rotLocalToParent; p = p->parent; } */ // This removed totally the Planet shaking bug!!! StelProjector::ModelViewTranformP transfo = core->getHeliocentricEclipticModelViewTransform(); transfo->combine(mat); // Compute the 2D position and check if in the screen const StelProjectorP prj = core->getProjection(transfo); float screenSz = getAngularSize(core)*M_PI/180.*prj->getPixelPerRadAtCenter(); float viewport_left = prj->getViewportPosX(); float viewport_bottom = prj->getViewportPosY(); if (prj->project(Vec3d(0), screenPos) && screenPos[1]>viewport_bottom - screenSz && screenPos[1] < viewport_bottom + prj->getViewportHeight()+screenSz && screenPos[0]>viewport_left - screenSz && screenPos[0] < viewport_left + prj->getViewportWidth() + screenSz) { // Draw the name, and the circle if it's not too close from the body it's turning around // this prevents name overlapping (ie for jupiter satellites) float ang_dist = 300.f*atan(getEclipticPos().length()/getEquinoxEquatorialPos(core).length())/core->getMovementMgr()->getCurrentFov(); // if (ang_dist==0.f) ang_dist = 1.f; // if ang_dist == 0, the Planet is sun.. --> GZ: we can remove it. // by putting here, only draw orbit if Comet is visible for clarity drawOrbit(core); // TODO - fade in here also... if (flagLabels && ang_dist>0.25 && maxMagLabels>getVMagnitude(core)) { labelsFader=true; } else { labelsFader=false; } drawHints(core, planetNameFont); draw3dModel(core,transfo,screenSz); } // tails should also be drawn if core is off-screen... drawTail(core,transfo,true); // gas tail drawTail(core,transfo,false); // dust tail //Coma: this is just a fan disk tilted towards the observer;-) drawComa(core, transfo); return; }
QString MinorPlanet::getInfoString(const StelCore *core, const InfoStringGroup &flags) const { //Mostly copied from Planet::getInfoString(): QString str; QTextStream oss(&str); double az_app, alt_app; StelUtils::rectToSphe(&az_app,&alt_app,getAltAzPosApparent(core)); Q_UNUSED(az_app); if (flags&Name) { oss << "<h2>"; if (minorPlanetNumber) oss << QString("(%1) ").arg(minorPlanetNumber); if (nameIsProvisionalDesignation) oss << provisionalDesignationHtml; else oss << getNameI18n(); // UI translation can differ from sky translation oss.setRealNumberNotation(QTextStream::FixedNotation); oss.setRealNumberPrecision(1); if (sphereScale != 1.f) oss << QString::fromUtf8(" (\xC3\x97") << sphereScale << ")"; oss << "</h2>"; if (!nameIsProvisionalDesignation && !provisionalDesignationHtml.isEmpty()) { oss << QString(q_("Provisional designation: %1")).arg(provisionalDesignationHtml); oss << "<br>"; } } if (flags&ObjectType && getPlanetType()!=isUNDEFINED) { oss << q_("Type: <b>%1</b>").arg(q_(getPlanetTypeString())) << "<br />"; } if (flags&Magnitude) { if (core->getSkyDrawer()->getFlagHasAtmosphere() && (alt_app>-3.0*M_PI/180.0)) // Don't show extincted magnitude much below horizon where model is meaningless. oss << q_("Magnitude: <b>%1</b> (extincted to: <b>%2</b>)").arg(QString::number(getVMagnitude(core), 'f', 2), QString::number(getVMagnitudeWithExtinction(core), 'f', 2)) << "<br>"; else oss << q_("Magnitude: <b>%1</b>").arg(getVMagnitude(core), 0, 'f', 2) << "<br>"; } if (flags&AbsoluteMagnitude) { //TODO: Make sure absolute magnitude is a sane value //If the H-G system is not used, use the default radius/albedo mechanism if (slopeParameter < 0) { oss << q_("Absolute Magnitude: %1").arg(getVMagnitude(core) - 5. * (std::log10(getJ2000EquatorialPos(core).length()*AU/PARSEC)-1.), 0, 'f', 2) << "<br>"; } else { oss << q_("Absolute Magnitude: %1").arg(absoluteMagnitude, 0, 'f', 2) << "<br>"; } } oss << getPositionInfoString(core, flags); if (flags&Distance) { double distanceAu = getJ2000EquatorialPos(core).length(); double distanceKm = AU * distanceAu; if (distanceAu < 0.1) { // xgettext:no-c-format oss << QString(q_("Distance: %1AU (%2 km)")) .arg(distanceAu, 0, 'f', 6) .arg(distanceKm, 0, 'f', 3); } else { // xgettext:no-c-format oss << QString(q_("Distance: %1AU (%2 Mio km)")) .arg(distanceAu, 0, 'f', 3) .arg(distanceKm / 1.0e6, 0, 'f', 3); } oss << "<br>"; } float aSize = 2.*getAngularSize(core)*M_PI/180.; if (flags&Size && aSize>1e-6) oss << q_("Apparent diameter: %1").arg(StelUtils::radToDmsStr(aSize, true)) << "<br>"; // If semi-major axis not zero then calculate and display orbital period for asteroid in days double siderealPeriod = getSiderealPeriod(); if ((flags&Extra) && (siderealPeriod>0)) { // TRANSLATORS: Sidereal (orbital) period for solar system bodies in days and in Julian years (symbol: a) oss << q_("Sidereal period: %1 days (%2 a)").arg(QString::number(siderealPeriod, 'f', 2)).arg(QString::number(siderealPeriod/365.25, 'f', 3)) << "<br>"; } postProcessInfoString(str, flags); return str; }
QString Nebula::getInfoString(const StelCore *core, const InfoStringGroup& flags) const { QString str; QTextStream oss(&str); if ((flags&Name) || (flags&CatalogNumber)) oss << "<h2>"; if (nameI18!="" && flags&Name) { oss << getNameI18n(); } if (flags&CatalogNumber) { if (nameI18!="" && flags&Name) oss << " ("; QStringList catIds; if ((M_nb > 0) && (M_nb < 111)) catIds << QString("M %1").arg(M_nb); if ((C_nb > 0) && (C_nb < 110)) catIds << QString("C %1").arg(C_nb); if (NGC_nb > 0) catIds << QString("NGC %1").arg(NGC_nb); if (IC_nb > 0) catIds << QString("IC %1").arg(IC_nb); if ((B_nb > 0) && (B_nb <= 370)) catIds << QString("B %1").arg(B_nb); if ((Sh2_nb > 0) && (Sh2_nb <= 313)) catIds << QString("Sh 2-%1").arg(Sh2_nb); if ((VdB_nb > 0) && (VdB_nb <= 158)) catIds << QString("VdB %1").arg(VdB_nb); if ((RCW_nb > 0) && (RCW_nb <= 182)) catIds << QString("RCW %1").arg(RCW_nb); if ((LDN_nb > 0) && (LDN_nb <= 1802)) catIds << QString("LDN %1").arg(LDN_nb); if ((LBN_nb > 0) && (LBN_nb <= 1125)) catIds << QString("LBN %1").arg(LBN_nb); if ((Cr_nb > 0) && (Cr_nb <= 471)) catIds << QString("Cr %1").arg(Cr_nb); if ((Mel_nb > 0) && (Mel_nb <= 245)) catIds << QString("Mel %1").arg(Mel_nb); oss << catIds.join(" - "); if (nameI18!="" && flags&Name) oss << ")"; } if ((flags&Name) || (flags&CatalogNumber)) oss << "</h2>"; if (flags&ObjectType) oss << q_("Type: <b>%1</b>").arg(getTypeString()) << "<br>"; if (mag < 50 && flags&Magnitude) { if (nType == NebDn) { oss << q_("Opacity: <b>%1</b>").arg(getVMagnitude(core), 0, 'f', 2) << "<br>"; } else { if (core->getSkyDrawer()->getFlagHasAtmosphere()) oss << q_("Magnitude: <b>%1</b> (extincted to: <b>%2</b>)").arg(QString::number(getVMagnitude(core), 'f', 2), QString::number(getVMagnitudeWithExtinction(core), 'f', 2)) << "<br>"; else oss << q_("Magnitude: <b>%1</b>").arg(getVMagnitude(core), 0, 'f', 2) << "<br>"; } } if (nType != NebDn && mag < 50 && flags&Extra) { if (core->getSkyDrawer()->getFlagHasAtmosphere()) { if (getSurfaceBrightness(core)<99 && getSurfaceBrightnessWithExtinction(core)<99) oss << q_("Surface brightness: <b>%1</b> (extincted to: <b>%2</b>)").arg(QString::number(getSurfaceBrightness(core), 'f', 2), QString::number(getSurfaceBrightnessWithExtinction(core), 'f', 2)) << "<br>"; } else { if (getSurfaceBrightness(core)<99) oss << q_("Surface brightness: <b>%1</b>").arg(QString::number(getSurfaceBrightness(core), 'f', 2)) << "<br>"; } } if (flags&Extra) { if (nType==NebHII) { if (LBN_nb!=0) oss << q_("Brightness: %1").arg(brightnessClass) << "<br>"; else { oss << qc_("Form: %1","HII Region").arg(getHIIFormTypeString()) << "<br>"; oss << qc_("Structure: %1","HII Region").arg(getHIIStructureTypeString()) << "<br>"; oss << q_("Brightness: %1").arg(getHIIBrightnessTypeString()) << "<br>"; } } if (nType==NebHa) { oss << q_("Brightness: %1").arg(getHaBrightnessTypeString()) << "<br>"; } } oss << getPositionInfoString(core, flags); if (angularSize>0 && flags&Size) oss << q_("Size: %1").arg(StelUtils::radToDmsStr(angularSize*M_PI/180.)) << "<br>"; postProcessInfoString(str, flags); return str; }