EquatorialCoordinateGrid::EquatorialCoordinateGrid( SkyComposite *parent ) : CoordinateGrid( parent, i18n("Equatorial Coordinate Grid" ) ) { KStarsData *data = KStarsData::Instance(); intro(); double eps = 0.1; double minRa = 0.0; double maxRa = 23.0; double dRa = 2.0; double minDec = -80.0; double maxDec = 90.0; double dDec = 20.0; double dDec2 = 4.0; double dRa2 = 0.2; double max, dec, dec2, ra, ra2; LineList* lineList; for ( ra = minRa; ra < maxRa; ra += dRa ) { for ( dec = -90.0; dec < maxDec - eps; dec += dDec ) { lineList = new LineList(); max = dec + dDec; if ( max > 90.0 ) max = 90.0; for ( dec2 = dec; dec2 <= max + eps; dec2 += dDec2 ) { SkyPoint* p = new SkyPoint( ra, dec2 ); p->EquatorialToHorizontal( data->lst(), data->geo()->lat() ); lineList->append( p ); } appendLine( lineList ); } } for ( dec = minDec; dec < maxDec + eps; dec += dDec ) { // Do not paint the line on the equator if ( dec < 0.1 && dec > -0.1 ) continue; // Adjust point density int nPoints = int(round( fabs(cos(dec* dms::PI / 180.0)) * dRa / dRa2 )); if ( nPoints < 5 ) nPoints = 5; double dRa3 = dRa / nPoints; for ( ra = minRa; ra < maxRa + eps; ra += dRa ) { lineList = new LineList(); for ( ra2 = ra; ra2 <= ra + dRa + eps; ra2 += dRa3 ) { SkyPoint* p = new SkyPoint( ra2, dec ); p->EquatorialToHorizontal( data->lst(), data->geo()->lat() ); lineList->append( p ); } appendLine( lineList ); } } summary(); }
void modCalcAzel::slotComputeCoords() { SkyPoint sp; double epoch0 = getEpoch( epochName->text() ); KStarsDateTime dt; dt.setFromEpoch( epoch0 ); long double jd = getDateTime().djd(); long double jd0 = dt.djd(); dms LST( getDateTime().gst().Degrees() + getLongitude().Degrees() ); if(radioApCoords->isChecked()) { sp = getEquCoords(); sp.apparentCoord(jd0, jd); dms lat(getLatitude()); sp.EquatorialToHorizontal( &LST, &lat ); showHorCoords( sp ); } else { sp = getHorCoords(); dms lat(getLatitude()); sp.HorizontalToEquatorial( &LST, &lat ); showEquCoords( sp ); } }
void Ecliptic::drawCompassLabels() { const Projector* proj = SkyMap::Instance()->projector(); KStarsData* data = KStarsData::Instance(); SkyLabeler* skyLabeler = SkyLabeler::Instance(); // Set proper color for labels QColor color( data->colorScheme()->colorNamed( "CompassColor" ) ); skyLabeler->setPen( QPen( QBrush(color), 1, Qt::SolidLine) ); KSNumbers num( data->ut().djd() ); dms elat(0.0), elng(0.0); QString label; for( int ra = 0; ra < 23; ra += 6 ) { elng.setH( ra ); SkyPoint o; o.setFromEcliptic( num.obliquity(), elng, elat ); o.setRA0( o.ra() ); o.setDec0( o.dec() ); o.EquatorialToHorizontal( data->lst(), data->geo()->lat() ); bool visible; QPointF cpoint = proj->toScreen( &o, false, &visible ); if( visible && proj->checkVisibility( &o ) ) { label.setNum( o.ra().reduce().Degrees() ); skyLabeler->drawGuideLabel( cpoint, label, 0.0 ); } } }
Ecliptic::Ecliptic(SkyComposite *parent ) : LineListIndex( parent, i18n("Ecliptic") ), m_label( name() ) { KStarsData *data = KStarsData::Instance(); KSNumbers num( data->ut().djd() ); dms elat(0.0), elng(0.0); const double eps = 0.1; const double minRa = 0.0; const double maxRa = 23.0; const double dRa = 2.0; const double dRa2 = 2. / 5.; for(double ra = minRa; ra < maxRa; ra += dRa ) { LineList* lineList = new LineList(); for(double ra2 = ra; ra2 <= ra + dRa + eps; ra2 += dRa2 ) { elng.setH( ra2 ); SkyPoint* o = new SkyPoint(); o->setFromEcliptic( num.obliquity(), elng, elat ); o->setRA0( o->ra().Hours() ); o->setDec0( o->dec().Degrees() ); o->EquatorialToHorizontal( data->lst(), data->geo()->lat() ); lineList->append( o ); } appendLine( lineList ); } }
SkyPoint EquirectangularProjector::fromScreen(const QPointF& p, dms* LST, const dms* lat) const { SkyPoint result; //Convert pixel position to x and y offsets in radians double dx = (0.5*m_vp.width - p.x())/m_vp.zoomFactor; double dy = (0.5*m_vp.height - p.y())/m_vp.zoomFactor; if ( m_vp.useAltAz ) { dms az, alt; dx = -1.0*dx; //Azimuth goes in opposite direction compared to RA az.setRadians( dx + m_vp.focus->az().radians() ); alt.setRadians( dy + m_vp.focus->alt().radians() ); result.setAz( az.reduce() ); if ( m_vp.useRefraction ) alt = SkyPoint::unrefract( alt ); result.setAlt( alt ); result.HorizontalToEquatorial( LST, lat ); return result; } else { dms ra, dec; ra.setRadians( dx + m_vp.focus->ra().radians() ); dec.setRadians( dy + m_vp.focus->dec().radians() ); result.set( ra.reduce(), dec ); result.EquatorialToHorizontal( LST, lat ); return result; } }
void SkyObjItem::setPosition(SkyObject* so) { KStarsData *data = KStarsData::Instance(); KStarsDateTime ut = data->geo()->LTtoUT(KStarsDateTime(KDateTime::currentLocalDateTime())); SkyPoint sp = so->recomputeCoords(ut, data->geo()); //check altitude of object at this time. sp.EquatorialToHorizontal(data->lst(), data->geo()->lat()); double rounded_altitude = (int)(sp.alt().Degrees()/5.0)*5.0; m_Position = i18n("Now visible: About %1 degrees above the %2 horizon", rounded_altitude, KSUtils::toDirectionString( sp.az() ) ); }
SkyPoint SkyPoint::timeTransformed( const SkyPoint *p, const KStarsDateTime &dt, const GeoLocation *geo, const double hour ) { Q_ASSERT( p ); if( !p ) return SkyPoint( NaN::d, NaN::d ); // Jasem 2015-08-24 Using correct procedure to find altitude SkyPoint sp = *p; // make a copy KStarsDateTime targetDateTime = dt.addSecs( hour * 3600.0 ); dms LST = geo->GSTtoLST( targetDateTime.gst() ); sp.EquatorialToHorizontal( &LST, geo->lat() ); return sp; }
SkyPoint Projector::fromScreen(const QPointF& p, dms* LST, const dms* lat) const { dms c; double sinc, cosc; /** N.B. We don't cache these sin/cos values in the inverse * projection because it causes 'shaking' when moving the sky. */ double sinY0, cosY0; //Convert pixel position to x and y offsets in radians double dx = (0.5*m_vp.width - p.x())/m_vp.zoomFactor; double dy = (0.5*m_vp.height - p.y())/m_vp.zoomFactor; double r = sqrt( dx*dx + dy*dy ); c.setRadians( projectionL(r) ); c.SinCos( sinc, cosc ); if( m_vp.useAltAz ) { dx = -1.0*dx; //Azimuth goes in opposite direction compared to RA m_vp.focus->alt().SinCos( sinY0, cosY0 ); } else { m_vp.focus->dec().SinCos( sinY0, cosY0 ); } double Y = asin( cosc*sinY0 + ( dy*sinc*cosY0 )/r ); double atop = dx*sinc; double abot = r*cosY0*cosc - dy*sinY0*sinc; double A = atan2( atop, abot ); SkyPoint result; if ( m_vp.useAltAz ) { dms alt, az; alt.setRadians( Y ); az.setRadians( A + m_vp.focus->az().radians() ); if ( m_vp.useRefraction ) alt = SkyPoint::unrefract( alt ); result.setAlt( alt ); result.setAz( az ); result.HorizontalToEquatorial( LST, lat ); } else { dms ra, dec; dec.setRadians( Y ); ra.setRadians( A + m_vp.focus->ra().radians() ); result.set( ra.reduce(), dec ); result.EquatorialToHorizontal( LST, lat ); } return result; }
QTime SkyObject::riseSetTime( const KStarsDateTime &dt, const GeoLocation *geo, bool rst ) { //this object does not rise or set; return an invalid time if ( checkCircumpolar(geo->lat()) ) return QTime( 25, 0, 0 ); //First of all, if the object is below the horizon at date/time dt, adjust the time //to bring it above the horizon KStarsDateTime dt2 = dt; SkyPoint p = recomputeCoords( dt, geo ); p.EquatorialToHorizontal( &(geo->GSTtoLST( dt.gst() )), geo->lat() ); if ( p.alt()->Degrees() < 0.0 ) { if ( p.az()->Degrees() < 180.0 ) { //object has not risen yet dt2 = dt.addSecs( 12.*3600. ); } else { //object has already set dt2 = dt.addSecs( -12.*3600. ); } } return geo->UTtoLT( KStarsDateTime( dt2.date(), riseSetTimeUT( dt2, geo, rst ) ) ).time(); }
void KSPlanetBase::updateTrail( dms *LST, const dms *lat ) { for ( SkyPoint *sp = Trail.first(); sp; sp = Trail.next() ) sp->EquatorialToHorizontal( LST, lat ); }
void modCalcAzel::processLines( QTextStream &istream ) { // we open the output file // QTextStream istream(&fIn); QString outputFileName; outputFileName = OutputLineEditBatch->text(); QFile fOut( outputFileName ); fOut.open(IO_WriteOnly); QTextStream ostream(&fOut); QString line; QString space = " "; int i = 0; long double jd0, jdf; dms LST; SkyPoint sp; dms raB, decB, latB, longB, azB, elB; double epoch0B; QTime utB; ExtDate dtB; while ( ! istream.eof() ) { line = istream.readLine(); line.stripWhiteSpace(); //Go through the line, looking for parameters QStringList fields = QStringList::split( " ", line ); i = 0; // Read Ut and write in ostream if corresponds if(utCheckBatch->isChecked() ) { utB = QTime::fromString( fields[i] ); i++; } else utB = utBoxBatch->time(); if ( allRadioBatch->isChecked() ) ostream << utB.toString() << space; else if(utCheckBatch->isChecked() ) ostream << utB.toString() << space; // Read date and write in ostream if corresponds if(dateCheckBatch->isChecked() ) { dtB = ExtDate::fromString( fields[i] ); i++; } else dtB = dateBoxBatch->date(); if ( allRadioBatch->isChecked() ) ostream << dtB.toString().append(space); else if(dateCheckBatch->isChecked() ) ostream << dtB.toString().append(space); // Read Longitude and write in ostream if corresponds if (longCheckBatch->isChecked() ) { longB = dms::fromString( fields[i],TRUE); i++; } else longB = longBoxBatch->createDms(TRUE); if ( allRadioBatch->isChecked() ) ostream << longB.toDMSString() << space; else if (longCheckBatch->isChecked() ) ostream << longB.toDMSString() << space; // Read Latitude if (latCheckBatch->isChecked() ) { latB = dms::fromString( fields[i], TRUE); i++; } else latB = latBoxBatch->createDms(TRUE); if ( allRadioBatch->isChecked() ) ostream << latB.toDMSString() << space; else if (latCheckBatch->isChecked() ) ostream << latB.toDMSString() << space; // Read Epoch and write in ostream if corresponds if(epochCheckBatch->isChecked() ) { epoch0B = fields[i].toDouble(); i++; } else epoch0B = getEpoch( epochBoxBatch->text() ); if ( allRadioBatch->isChecked() ) ostream << epoch0B << space; else if(epochCheckBatch->isChecked() ) ostream << epoch0B << space; // We make the first calculations KStarsDateTime dt; dt.setFromEpoch( epoch0B ); jdf = KStarsDateTime(dtB,utB).djd(); jd0 = dt.djd(); LST = KStarsDateTime(dtB,utB).gst().Degrees() + longB.Degrees(); // Equatorial coordinates are the input coords. if (!horInputCoords) { // Read RA and write in ostream if corresponds if(raCheckBatch->isChecked() ) { raB = dms::fromString( fields[i],FALSE); i++; } else raB = raBoxBatch->createDms(FALSE); if ( allRadioBatch->isChecked() ) ostream << raB.toHMSString() << space; else if(raCheckBatch->isChecked() ) ostream << raB.toHMSString() << space; // Read DEC and write in ostream if corresponds if(decCheckBatch->isChecked() ) { decB = dms::fromString( fields[i], TRUE); i++; } else decB = decBoxBatch->createDms(); if ( allRadioBatch->isChecked() ) ostream << decB.toDMSString() << space; else if(decCheckBatch->isChecked() ) ostream << decB.toDMSString() << space; sp = SkyPoint (raB, decB); sp.apparentCoord(jd0, jdf); sp.EquatorialToHorizontal( &LST, &latB ); ostream << sp.az()->toDMSString() << space << sp.alt()->toDMSString() << endl; // Input coords are horizontal coordinates } else { if(azCheckBatch->isChecked() ) { azB = dms::fromString( fields[i],FALSE); i++; } else azB = azBoxBatch->createDms(); if ( allRadioBatch->isChecked() ) ostream << azB.toHMSString() << space; else if(raCheckBatch->isChecked() ) ostream << azB.toHMSString() << space; // Read DEC and write in ostream if corresponds if(elCheckBatch->isChecked() ) { elB = dms::fromString( fields[i], TRUE); i++; } else elB = decBoxBatch->createDms(); if ( allRadioBatch->isChecked() ) ostream << elB.toDMSString() << space; else if(elCheckBatch->isChecked() ) ostream << elB.toDMSString() << space; sp.setAz(azB); sp.setAlt(elB); sp.HorizontalToEquatorial( &LST, &latB ); ostream << sp.ra()->toHMSString() << space << sp.dec()->toDMSString() << endl; } } fOut.close(); }
Vector2f Projector::clipLineVec( SkyPoint *p1, SkyPoint *p2 ) const { /* ASSUMES p1 was not clipped but p2 was. * Return the QPoint that barely clips in the line twixt p1 and p2. */ //TODO: iteration = ceil( 0.5*log2( w^2 + h^2) )?? // also possibly rewrite this // --hdevalence int iteration = 15; // For "perfect" clipping: // 2^interations should be >= max pixels/line bool isVisible = true; // so we start at midpoint SkyPoint mid; Vector2f oMid; double x, y, z, dx, dy, dz, ra, dec; int newx, newy, oldx, oldy; oldx = oldy = -10000; // any old value that is not the first omid toXYZ( p1, &x, &y, &z ); // -jbb printf("\np1: %6.4f %6.4f %6.4f\n", x, y, z); toXYZ( p2, &dx, &dy, &dz ); // -jbb printf("p2: %6.4f %6.4f %6.4f\n", dx, dy, dz); dx -= x; dy -= y; dz -= z; // Successive approximation to point on line that just clips. while(iteration-- > 0) { dx *= .5; dy *= .5; dz *= .5; if ( ! isVisible ) { // move back toward visible p1 x -= dx; y -= dy; z -= dz; } else { // move out toward clipped p2 x += dx; y += dy; z += dz; } // -jbb printf(" : %6.4f %6.4f %6.4f\n", x, y, z); // [x, y, z] => [ra, dec] ra = atan2( y, x ); dec = asin( z / sqrt(x*x + y*y + z*z) ); mid = SkyPoint( ra * 12. / dms::PI, dec * 180. / dms::PI ); mid.EquatorialToHorizontal( m_data->lst(), m_data->geo()->lat() ); oMid = toScreenVec( &mid, false, &isVisible ); //AND the result with checkVisibility to clip things going below horizon isVisible &= checkVisibility(&mid); newx = (int) oMid.x(); newy = (int) oMid.y(); // -jbb printf("new x/y: %4d %4d", newx, newy); if ( (oldx == newx) && (oldy == newy) ) { break; } oldx = newx; oldy = newy; } return oMid; }
void ObservingList::slotAddObject( SkyObject *obj, bool session, bool update ) { bool addToWishList=true; if( ! obj ) obj = ks->map()->clickedObject(); if( obj->name() == "star" ) { KMessageBox::sorry(0, i18n( "Unnamed stars are not supported in the observing lists")); return; } //First, make sure object is not already in the list if ( obsList().contains( obj ) ) { addToWishList = false; if( ! session ) { ks->statusBar()->changeItem( i18n( "%1 is already in your wishlist.", obj->name() ), 0 ); return; } } if ( session && sessionList().contains( obj ) ) { ks->statusBar()->changeItem( i18n( "%1 is already in the session plan.", obj->name() ), 0 ); return; } QString smag = "--"; if ( - 30.0 < obj->mag() && obj->mag() < 90.0 ) smag = QString::number( obj->mag(), 'g', 2 ); // The lower limit to avoid display of unrealistic comet magnitudes SkyPoint p = obj->recomputeCoords( dt, geo ); //Insert object in the Wish List if( addToWishList ) { m_ObservingList.append( obj ); m_CurrentObject = obj; QList<QStandardItem*> itemList; QString ra, dec; if(obj->name() == "star" ) { ra = obj->ra0().toHMSString(); dec = obj->dec0().toDMSString(); } else { ra = p.ra().toHMSString(); dec = p.dec().toDMSString(); } itemList << new QStandardItem( obj->translatedName() ) << new QStandardItem( ra ) << new QStandardItem( dec ) << new QStandardItem( smag ) << new QStandardItem( obj->typeName() ); m_Model->appendRow( itemList ); //Note addition in statusbar ks->statusBar()->changeItem( i18n( "Added %1 to observing list.", obj->name() ), 0 ); ui->TableView->resizeColumnsToContents(); if( ! update ) slotSaveList(); } //Insert object in the Session List if( session ){ m_SessionList.append(obj); dt.setTime( TimeHash.value( obj->name(), obj->transitTime( dt, geo ) ) ); dms lst(geo->GSTtoLST( dt.gst() )); p.EquatorialToHorizontal( &lst, geo->lat() ); QList<QStandardItem*> itemList; QString ra, dec, time = "--", alt = "--", az = "--"; QStandardItem *BestTime = new QStandardItem(); if(obj->name() == "star" ) { ra = obj->ra0().toHMSString(); dec = obj->dec0().toDMSString(); BestTime->setData( QString( "--" ), Qt::DisplayRole ); } else { ra = p.ra().toHMSString(); dec = p.dec().toDMSString(); BestTime->setData( TimeHash.value( obj->name(), obj->transitTime( dt, geo ) ), Qt::DisplayRole ); alt = p.alt().toDMSString(); az = p.az().toDMSString(); } // TODO: Change the rest of the parameters to their appropriate datatypes. itemList << new QStandardItem( obj->translatedName() ) << new QStandardItem( ra ) << new QStandardItem( dec ) << new QStandardItem( smag ) << new QStandardItem( obj->typeName() ) << BestTime << new QStandardItem( alt ) << new QStandardItem( az ); m_Session->appendRow( itemList ); //Adding an object should trigger the modified flag isModified = true; ui->SessionView->resizeColumnsToContents(); //Note addition in statusbar ks->statusBar()->changeItem( i18n( "Added %1 to session list.", obj->name() ), 0 ); } setSaveImagesButton(); }