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(); }
QTime SkyObject::transitTimeUT( const KStarsDateTime &dt, const GeoLocation *geo ) { dms LST = geo->GSTtoLST( dt.gst() ); //dSec is the number of seconds until the object transits. dms HourAngle = dms( LST.Degrees() - ra()->Degrees() ); int dSec = int( -3600.*HourAngle.Hours() ); //dt0 is the first guess at the transit time. KStarsDateTime dt0 = dt.addSecs( dSec ); //recompute object's position at UT0 and then find //transit time of this refined position SkyPoint sp = recomputeCoords( dt0, geo ); const dms *ram = sp.ra0(); HourAngle = dms ( LST.Degrees() - ram->Degrees() ); dSec = int( -3600.*HourAngle.Hours() ); return dt.addSecs( dSec ).time(); }
void modCalcAltAz::slotCompute() { //Determine whether we are calculating Alt/Az coordinates from RA/Dec, //or vice versa. We calculate Alt/Az by default, unless the signal //was sent by changing the Az or Alt value. if ( sender()->objectName() == "Az" || sender()->objectName() == "Alt" ) { //Validate Az and Alt coordinates bool ok( false ); dms alt; dms az = Az->createDms( true, &ok ); if ( ok ) alt = Alt->createDms( true, &ok ); if ( ok ) { SkyPoint sp; sp.setAz( az ); sp.setAlt( alt ); sp.HorizontalToEquatorial( &LST, geoPlace->lat() ); RA->showInHours( sp.ra() ); Dec->showInDegrees( sp.dec() ); } } else { //Validate RA and Dec coordinates bool ok( false ); dms ra; dms dec = Dec->createDms( true, &ok ); if ( ok ) ra = RA->createDms( false, &ok ); if ( ok ) { SkyPoint sp( ra, dec ); sp.EquatorialToHorizontal( &LST, geoPlace->lat() ); Az->showInDegrees( sp.az() ); Alt->showInDegrees( sp.alt() ); } } }
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; } }
double SkyPoint::vRSun(long double jd0) { double ca, sa, cd, sd, vsun; double cosRA, sinRA, cosDec, sinDec; /* Sun apex (where the sun goes) coordinates */ dms asun(270.9592); // Right ascention: 18h 3m 50.2s [J2000] dms dsun(30.00467); // Declination: 30^o 0' 16.8'' [J2000] vsun=20.; // [km/s] asun.SinCos(sa,ca); dsun.SinCos(sd,cd); /* We need an auxiliary SkyPoint since we need the * source referred to the J2000 equinox and we do not want to ovewrite * the current values */ SkyPoint aux; aux.set(RA0,Dec0); aux.precessFromAnyEpoch(jd0, J2000); aux.ra().SinCos( sinRA, cosRA ); aux.dec().SinCos( sinDec, cosDec ); /* Computation is done performing the scalar product of a unitary vector in the direction of the source with the vector velocity of Sun, both being in the LSR reference system: Vlsr = Vhel + Vsun.u_radial => Vlsr = Vhel + vsun(cos D cos A,cos D sen A,sen D).(cos d cos a,cos d sen a,sen d) Vhel = Vlsr - Vsun.u_radial */ return vsun *(cd*cosDec*(cosRA*ca + sa*sinRA) + sd*sinDec); }
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; }
int ObservationCache::create(RunGeometry &geom, Catalog *cat, ObservationCalculator *calc) { const int blockSize = 10000; int recordCount = cat->recordCount(); cout << setprecision(6); MJD d0 = geom.tstart - 4./24.; // cout << d0 << "\n"; cout << "\n"; const int maxiter = 10; int hist[maxiter+1] = {0}; // start progress bar cout << "Progress [ "; cout.flush(); // calculate cache vector<Asteroid> obj; vector<Observation> obsv; int i = 0, prog = 0; double tref; while(i < recordCount) { int read = cat->read(obj, i, i+blockSize); // calculate positions for the time of TDI scan start (0th approximation) calc->calculateObservations(obsv, geom.tstart, obj, ObsFlags::pos | ObsFlags::vel, CalcFlags::twoBody); // start iterative approximation for TDI display for(int k = 0; k != obsv.size(); k++) { Observation &o = obsv[k]; coordinates::equgcs(geom.node, geom.inc, o.ra, o.dec, o.ra, o.dec); o.t0 = geom.tstart; int j; SkyPoint old; for(j = 0; j != maxiter; j++) { // if(i == 1023) { cout << setprecision(10) << j << " " << o.ra/ctn::d2r << " " << o.dec/ctn::d2r << " " << o.t0 << "\n"; cout.flush();} old = SkyPoint(o.ra, o.dec); // deal with compact (ra, dec) coordinate system #if 0 // this piece contained a _very_ subtle bug if the slew rate was != 1/360deg... o.t0 = geom.tstart + (o.ra - geom.muStart)/(ctn::pi2*361./360.); // o.t0 = geom.tstart + (o.ra - geom.muStart)/(ctn::pi2); #else Radians len = o.ra > geom.muStart ? o.ra - geom.muStart : o.ra + ctn::pi2 - geom.muStart; o.t0 = geom.tstart + len/(ctn::pi2*1.00273791); // o.t0 = geom.tstart + len/(ctn::pi2); #endif while(o.t0 > d0 + 1) o.t0 -= 1; while(o.t0 < d0 ) o.t0 += 1; // new approximation calc->calculateObservation(o, o.t0, obj[k], ObsFlags::pos | ObsFlags::vel, CalcFlags::twoBody); coordinates::equgcs(geom.node, geom.inc, o.ra, o.dec, o.ra, o.dec); // check convergence double dist = old.distance(SkyPoint(o.ra, o.dec)); /* if(!strcmp(o.name, "2005 SV285")) { fprintf(stderr, "t0,t1=%f,%f, iter=%d, dist=%f, t=%f, name=%s, muOld=%f, mu=%f, nu=%f]\n", geom.tstart, geom.tend, j, dist/ctn::s2r, o.t0, o.name, old.ra/ctn::d2r, o.ra/ctn::d2r, o.dec/ctn::d2r); } */ if(dist < 0.01*ctn::s2r) break; } if(j == maxiter && (fabs(o.t0 - d0) > 0.04 && fabs(o.t0 - d0) < 0.96)) { // didn't converge - sound a warning fprintf(stderr, "A TDI position calculation didn't converge [id=%d, name=%s, raOld=%f, ra=%f, dec=%f]\n", o.id, o.name, old.ra/ctn::d2r, o.ra/ctn::d2r, o.dec/ctn::d2r); fprintf(stderr, "t0,t1=%f,%f,%f iter=%d, t=%f, name=%s, muOld=%f, mu=%f, nu=%f]\n", geom.tstart, geom.tend, o.t0-d0, j, o.t0, o.name, old.ra/ctn::d2r, o.ra/ctn::d2r, o.dec/ctn::d2r); } hist[j]++; } fwrite(reinterpret_cast<void *>(&*obsv.begin()), sizeof(Observation), obsv.size(), f); i += read; // progress bar while(int(50*double(i)/double(recordCount)) > prog) { cout << "#"; cout.flush(); prog++; } } // finish progress bar cout << " ]\n"; cout.flush(); // construct and write the true header Header h; memset(&h, 0, sizeof(h)); h.geom = geom; h.len = i; strcpy(h.catalog, "NATIVE"); // cat->identify(h.catalog); setHeader(h); closeCache(); for(int i = 0; i != maxiter; i++) { cout << i+1 << ":" << hist[i] << (i+1 != maxiter ? " | " : "\n"); } return 0; }
void KSPlanetBase::updateTrail( dms *LST, const dms *lat ) { for ( SkyPoint *sp = Trail.first(); sp; sp = Trail.next() ) sp->EquatorialToHorizontal( LST, lat ); }
void ExportEyepieceView::render() { float baseWidth = m_renderChart->width(); float baseHeight = m_renderChart->height(); if( m_renderImage ) m_output = QImage( int(baseWidth * 2.25), int(baseHeight), QImage::Format_ARGB32 ); // 0.25 * baseWidth gap between the images else m_output = QImage( int(baseWidth), int(baseHeight), QImage::Format_ARGB32 ); m_output.fill( Qt::white ); QPainter op( &m_output ); op.drawPixmap( QPointF(0,0), *m_renderChart ); if( m_renderImage ) op.drawPixmap( QPointF(baseWidth * 1.25,0), *m_renderImage ); if( m_tickConfig != 0 && Options::useAltAz() ) { // FIXME: this is very skymap-state-heavy for my happiness --asimha // we must draw ticks QImage tickOverlay( baseWidth, baseHeight, QImage::Format_ARGB32 ); tickOverlay.fill( Qt::transparent ); QPainter p( &tickOverlay ); p.setPen( Qt::red ); // FIXME: Determine color depending on situation, or make it configurable double rEnd = 0.85 * ( baseWidth / 2.); double rStart = 0.8 * ( baseWidth / 2.); QFont font; font.setPixelSize( ( rEnd - rStart ) ); p.setFont( font ); GeoLocation *geo = KStarsData::Instance()->geo(); double alt0 = m_sp->alt().Degrees(); // altitude when hour = 0, i.e. at m_dt (see below). dms northAngle0 = EyepieceField::findNorthAngle( m_sp, geo->lat() ); for( float hour = -3.5; hour <= 3.5; hour += 0.5 ) { dms rotation; // rotation // FIXME: Code duplication : code duplicated from EyepieceField. This should really be a member of SkyPoint or something. SkyPoint sp = SkyPoint::timeTransformed( m_sp, m_dt, geo, hour ); double alt = sp.alt().Degrees(); dms northAngle = EyepieceField::findNorthAngle( &sp, geo->lat() ); rotation = ( northAngle - northAngle0 ); if( m_tickConfig == 2 ) { // Dobsonian: add additional CW rotation by altitude, but compensate for the fact that we've already rotated by alt0 rotation = rotation - dms( ( alt - alt0 ) ); } rotation = rotation.reduce(); p.save(); p.translate( baseWidth/2.0, baseHeight/2.0 ); p.rotate( -( rotation.Degrees() + 90.0 ) ); p.drawLine( QPointF( rStart, 0 ), QPointF( rEnd, 0 ) ); QTime ct = geo->UTtoLT( m_dt.addSecs( 3600.0 * hour ) ).time(); p.drawText( QPointF( rEnd + 0.01 * baseWidth, 0 ), QString().sprintf( "%02d:%02d", ct.hour(), ct.minute() ) ); p.restore(); } p.end(); op.drawImage( QPointF(0,0), tickOverlay ); if( m_renderImage ) { op.drawImage( QPointF(baseWidth * 1.25, 0), tickOverlay ); } } op.end(); m_outputDisplay->setPixmap( (QPixmap::fromImage( m_output )).scaled( m_outputDisplay->width(), m_outputDisplay->height(), Qt::KeepAspectRatio, Qt::SmoothTransformation ) ); }
void modCalcVlsr::processLines( QTextStream &istream ) { // we open the output file // QTextStream istream(&fIn); QString outputFileName; outputFileName = OutputFileBoxBatch->url().toLocalFile(); QFile fOut( outputFileName ); fOut.open(QIODevice::WriteOnly); QTextStream ostream(&fOut); QString line; QChar space = ' '; int i = 0; long double jd0; SkyPoint spB; double sra, cra, sdc, cdc; dms raB, decB, latB, longB; QString epoch0B; double vhB, vgB, vtB, vlsrB, heightB; double vtopo[3]; QTime utB; QDate dtB; KStarsDateTime dt0B; while ( ! istream.atEnd() ) { line = istream.readLine(); line.trimmed(); //Go through the line, looking for parameters QStringList fields = line.split( ' ' ); 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 << KGlobal::locale()->formatTime( utB ) << space; else if(UTCheckBatch->isChecked() ) ostream << KGlobal::locale()->formatTime( utB ) << space; // Read date and write in ostream if corresponds if(DateCheckBatch->isChecked() ) { dtB = QDate::fromString( fields[i] ); i++; } else dtB = DateBoxBatch->date(); if ( AllRadioBatch->isChecked() ) ostream << KGlobal::locale()->formatDate( dtB, KLocale::LongDate ).append(space); else if(DateCheckBatch->isChecked() ) ostream << KGlobal::locale()->formatDate( dtB, KLocale::LongDate ).append(space); // 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; // Read Epoch and write in ostream if corresponds if(EpochCheckBatch->isChecked() ) { epoch0B = fields[i]; i++; } else epoch0B = EpochBoxBatch->text(); if ( AllRadioBatch->isChecked() ) ostream << epoch0B << space; else if(EpochCheckBatch->isChecked() ) ostream << epoch0B << space; // Read vlsr and write in ostream if corresponds if(InputVelocityCheckBatch->isChecked() ) { vlsrB = fields[i].toDouble(); i++; } else vlsrB = InputVelocityComboBatch->currentText().toDouble(); if ( AllRadioBatch->isChecked() ) ostream << vlsrB << space; else if(InputVelocityCheckBatch->isChecked() ) ostream << vlsrB << space; // Read Longitude and write in ostream if corresponds if (LongCheckBatch->isChecked() ) { longB = dms::fromString( fields[i],true); i++; } else longB = LongitudeBoxBatch->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 = LatitudeBoxBatch->createDms(true); if ( AllRadioBatch->isChecked() ) ostream << latB.toDMSString() << space; else if (LatCheckBatch->isChecked() ) ostream << latB.toDMSString() << space; // Read height and write in ostream if corresponds if(ElevationCheckBatch->isChecked() ) { heightB = fields[i].toDouble(); i++; } else heightB = ElevationBoxBatch->text().toDouble(); if ( AllRadioBatch->isChecked() ) ostream << heightB << space; else if(ElevationCheckBatch->isChecked() ) ostream << heightB << space; // We make the first calculations spB = SkyPoint (raB, decB); dt0B.setFromEpoch(epoch0B); vhB = spB.vHeliocentric(vlsrB, dt0B.djd()); jd0 = KStarsDateTime(dtB,utB).djd(); vgB = spB.vGeocentric(vlsrB, jd0); geoPlace->setLong( longB ); geoPlace->setLat( latB ); geoPlace->setHeight( heightB ); dms gsidt = KStarsDateTime(dtB,utB).gst(); geoPlace->TopocentricVelocity(vtopo, gsidt); spB.ra().SinCos(sra, cra); spB.dec().SinCos(sdc, cdc); vtB = vgB - (vtopo[0]*cdc*cra + vtopo[1]*cdc*sra + vtopo[2]*sdc); ostream << vhB << space << vgB << space << vtB << endl; } fOut.close(); }
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(); }
void modCalcAzel::showEquCoords ( SkyPoint sp ) { raBox->show( sp.ra(), FALSE ); decBox->show( sp.dec() ); showEpoch( getDateTime() ); }
QList<const StarObject *> StarHopper::computePath( const SkyPoint &src, const SkyPoint &dest, float fov_, float maglim_ ) { fov = fov_; maglim = maglim_; start = &src; end = &dest; came_from.clear(); result_path.clear(); // Implements the A* search algorithm QList<SkyPoint const *> cSet; QList<SkyPoint const *> oSet; QHash<SkyPoint const *, double> g_score; QHash<SkyPoint const *, double> f_score; QHash<SkyPoint const *, double> h_score; kDebug() << "StarHopper is trying to compute a path from source: " << src.ra().toHMSString() << src.dec().toDMSString() << " to destination: " << dest.ra().toHMSString() << dest.dec().toDMSString() << "; a starhop of " << src.angularDistanceTo( &dest ).Degrees() << " degrees!"; oSet.append( &src ); g_score[ &src ] = 0; h_score[ &src ] = src.angularDistanceTo( &dest ).Degrees()/fov; f_score[ &src ] = h_score[ &src ]; while( !oSet.isEmpty() ) { kDebug() << "Next step"; // Find the node with the lowest f_score value SkyPoint const *curr_node = NULL; double lowfscore = 1.0e8; foreach( const SkyPoint *sp, oSet ) { if( f_score[ sp ] < lowfscore ) { lowfscore = f_score[ sp ]; curr_node = sp; } } kDebug() << "Lowest fscore (vertex distance-plus-cost score) is " << lowfscore << " with coords: " << curr_node->ra().toHMSString() << curr_node->dec().toDMSString() << ". Considering this node now."; if( curr_node == &dest || (curr_node != &src && h_score[ curr_node ] < 0.5) ) { // We are at destination reconstructPath( came_from[ curr_node ] ); kDebug() << "We've arrived at the destination! Yay! Result path count: " << result_path.count(); // Just a test -- try to print out useful instructions to the debug console. Once we make star hopper unexperimental, we should move this to some sort of a display kDebug() << "Star Hopping Directions: "; const SkyPoint *prevHop = start; foreach( const StarObject *hopStar, result_path ) { QString direction; double pa; // should be 0 to 2pi dms angDist = prevHop->angularDistanceTo( hopStar, &pa ); dms dmsPA; dmsPA.setRadians( pa ); direction = KSUtils::toDirectionString( dmsPA ); kDebug() << " Slew " << angDist.Degrees() << " degrees " << direction << " to find a " << hopStar->spchar() << " star of mag " << hopStar->mag(); prevHop = hopStar; } kDebug() << " The destination is within a field-of-view"; return result_path; }
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(); }
int main(int argc, char* argv[]) { PRINT_VERSION_IF_ASKED(argc, argv); if(argc != 6) { cout << "Usage: " << argv[0] << " <output_file> <radius> <input_file> <catalog> <cache>\n"; cout << "Catalog must be in NATIVE format\n"; return -1; } out.open(argv[1]); const double matchRadius = atof(argv[2]); ifstream f(argv[3]); Catalog *cat = Catalog::open(argv[4], "NATIVE"); ObservationCache cache(argv[5], "r"); cout << "Radius : " << matchRadius << "\"\n"; cout << "Catalog : " << argv[4] << "\n"; cout << "Cache : " << argv[5] << "\n"; ObservationCalculator oc; vector<Asteroid> o; vector<Observation> obsv; int i; // unidentified observation dummy object Observation unmached; unmached.name[0] = 0; unmached.ra = unmached.dec = unmached.ddec = unmached.dra = unmached.mag = 0; Asteroid unmachedAst; // header out << "#run\tsloanId\tastorbId\ttime\tname\terrRa\terrDec\tra\tdec\tmag\tdra\tddec\ttra\ttswc\ttmag\ttdra\ttddec\tl\tb\tphi\n"; cout << setiosflags( ios::fixed ); MJD t2; SkyPoint target; double v, rowv, colw; int sloanID, run; double r_mag; int plus = 0, minus = 0; while(!f.eof()) { f >> r_mag >> run >> sloanID >> t2 >> v >> rowv >> colw >> target.ra >> target.dec; target.ra *= ctn::d2r; target.dec *= ctn::d2r; double err = 1E5; if(cache.getCandidates(obsv, t2, target, .2*ctn::d2r) > 0) { // load Asteroids for all candidates int *ids = new int[obsv.size()]; for(i = 0; i != obsv.size(); i++) ids[i] = obsv[i].id; cat->read(o, ids, obsv.size()); delete [] ids; // calculate exact position oc.calculateObservations(obsv, t2, o, ObsFlags::pos | ObsFlags::vel, CalcFlags::twoBody); // find best int bestMatch; for(i = 0; i != obsv.size(); i++) { double d = target.distance(SkyPoint(obsv[i].ra, obsv[i].dec)); if(d < err) { bestMatch = i; err = d; } } // show our best candidate err /= ctn::s2r; if(err < matchRadius) { double errRa, errDec; errRa = (obsv[bestMatch].ra - target.ra) / ctn::s2r; errDec = (obsv[bestMatch].dec - target.dec) / ctn::s2r; printMatch(t2, errRa, errDec, &o[bestMatch], obsv[bestMatch], target, run, sloanID, rowv, colw, r_mag); plus++; } } // absolutely nothing was found if(err >= matchRadius) { printMatch(t2, 0, 0, &unmachedAst, unmached, target, run, sloanID, rowv, colw, r_mag); minus++; } // progress info if((plus + minus) % 50 == 0) { cout << " [" << plus << "/" << minus << "/" << plus+minus << " : " << setprecision(1) << r_mag << "m]\n"; } cout << "#"; cout.flush(); } cout << "\nTotals (+/-/total) : " << plus << "/" << minus << "/" << plus+minus << "\n"; delete cat; return 0; }
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; }
QVector< Vector2f > EquirectangularProjector::groundPoly(SkyPoint* labelpoint, bool* drawLabel) const { float x0 = m_vp.width/2.; float y0 = m_vp.width/2.; if( m_vp.useAltAz ) { float dX = m_vp.zoomFactor*M_PI; float dY = m_vp.zoomFactor*M_PI; SkyPoint belowFocus; belowFocus.setAz( m_vp.focus->az().Degrees() ); belowFocus.setAlt( 0.0 ); Vector2f obf = toScreenVec( &belowFocus, false ); //If the horizon is off the bottom edge of the screen, //we can return immediately if ( obf.y() > m_vp.height ) { if( drawLabel ) *drawLabel = false; return QVector<Vector2f>(); } //We can also return if the horizon is off the top edge, //as long as the ground poly is not being drawn if ( obf.y() < 0. && m_vp.fillGround == false ) { if( drawLabel ) *drawLabel = false; return QVector<Vector2f>(); } QVector<Vector2f> ground; //Construct the ground polygon, which is a simple rectangle in this case ground << Vector2f( x0 - dX, obf.y() ) << Vector2f( x0 + dX, obf.y() ) << Vector2f( x0 + dX, y0 + dY ) << Vector2f( x0 - dX, y0 + dY ); if( labelpoint ) { QPointF pLabel( x0 -dX -50., obf.y() ); KStarsData *data = KStarsData::Instance(); *labelpoint = fromScreen(pLabel, data->lst(), data->geo()->lat()); } if( drawLabel ) *drawLabel = true; return ground; } else { float dX = m_vp.zoomFactor*M_PI/2; float dY = m_vp.zoomFactor*M_PI/2; QVector<Vector2f> ground; static const QString horizonLabel = i18n("Horizon"); float marginLeft, marginRight, marginTop, marginBot; SkyLabeler::Instance()->getMargins( horizonLabel, &marginLeft, &marginRight, &marginTop, &marginBot ); double daz = 90.; double faz = m_vp.focus->az().Degrees(); double az1 = faz -daz; double az2 = faz +daz; bool allGround = true; bool allSky = true; double inc = 1.0; //Add points along horizon for(double az = az1; az <= az2 + inc; az += inc) { SkyPoint p = pointAt(az); bool visible = false; Vector2f o = toScreenVec(&p, false, &visible); if( visible ) { ground.append( o ); //Set the label point if this point is onscreen if ( labelpoint && o.x() < marginRight && o.y() > marginTop && o.y() < marginBot ) *labelpoint = p; if ( o.y() > 0. ) allGround = false; if ( o.y() < m_vp.height ) allSky = false; } } if( allSky ) { if( drawLabel) *drawLabel = false; return QVector<Vector2f>(); } if( allGround ) { ground.clear(); ground.append( Vector2f( x0 - dX, y0 - dY ) ); ground.append( Vector2f( x0 + dX, y0 - dY ) ); ground.append( Vector2f( x0 + dX, y0 + dY ) ); ground.append( Vector2f( x0 - dX, y0 + dY ) ); if( drawLabel) *drawLabel = false; return ground; } if( labelpoint ) { QPointF pLabel( x0 -dX -50., ground.last().y() ); KStarsData *data = KStarsData::Instance(); *labelpoint = fromScreen(pLabel, data->lst(), data->geo()->lat()); } if( drawLabel ) *drawLabel = true; //Now add points along the ground ground.append( Vector2f( x0 + dX, ground.last().y() ) ); ground.append( Vector2f( x0 + dX, y0 + dY ) ); ground.append( Vector2f( x0 - dX, y0 + dY ) ); ground.append( Vector2f( x0 - dX, ground.first().y() ) ); return ground; } }
void CatalogDB::GetAllObjects(const QString &catalog, QList< SkyObject* > &sky_list, QList < QPair <int, QString> > &object_names, CatalogComponent *catalog_ptr) { sky_list.clear(); QString selected_catalog = QString::number(FindCatalog(catalog)); skydb_.open(); QSqlQuery get_query(skydb_); get_query.prepare("SELECT Epoch, Type, RA, Dec, Magnitude, Prefix, " "IDNumber, LongName, MajorAxis, MinorAxis, " "PositionAngle, Flux FROM ObjectDesignation JOIN DSO " "JOIN Catalog WHERE Catalog.id = :catID AND " "ObjectDesignation.id_Catalog = Catalog.id AND " "ObjectDesignation.UID_DSO = DSO.UID"); get_query.bindValue("catID", selected_catalog); // kWarning() << get_query.lastQuery(); // kWarning() << get_query.lastError(); // kWarning() << FindCatalog(catalog); if (!get_query.exec()) { kWarning() << get_query.lastQuery(); kWarning() << get_query.lastError(); } while (get_query.next()) { int cat_epoch = get_query.value(0).toInt(); unsigned char iType = get_query.value(1).toInt(); dms RA(get_query.value(2).toDouble()); dms Dec(get_query.value(3).toDouble()); float mag = get_query.value(4).toFloat(); QString catPrefix = get_query.value(5).toString(); int id_number_in_catalog = get_query.value(6).toInt(); QString lname = get_query.value(7).toString(); float a = get_query.value(8).toFloat(); float b = get_query.value(9).toFloat(); float PA = get_query.value(10).toFloat(); float flux = get_query.value(11).toFloat(); QString name = catPrefix + ' ' + QString::number(id_number_in_catalog); SkyPoint t; t.set(RA, Dec); if (cat_epoch == 1950) { // Assume B1950 epoch t.B1950ToJ2000(); // t.ra() and t.dec() are now J2000.0 // coordinates } else if (cat_epoch == 2000) { // Do nothing { } } else { // FIXME: What should we do? // FIXME: This warning will be printed for each line in the // catalog rather than once for the entire catalog kWarning() << "Unknown epoch while dealing with custom " "catalog. Will ignore the epoch and assume" " J2000.0"; } RA = t.ra(); Dec = t.dec(); if (iType == 0) { // Add a star StarObject *o = new StarObject(RA, Dec, mag, lname); sky_list.append(o); } else { // Add a deep-sky object DeepSkyObject *o = new DeepSkyObject(iType, RA, Dec, mag, name, QString(), lname, catPrefix, a, b, -PA); o->setFlux(flux); o->setCustomCatalog(catalog_ptr); sky_list.append(o); // Add name to the list of object names if (!name.isEmpty()) { object_names.append(qMakePair<int,QString>(iType, name)); } } if (!lname.isEmpty() && lname != name) { object_names.append(qMakePair<int,QString>(iType, lname)); } } get_query.clear(); skydb_.close(); }
void modCalcGalCoord::processLines( QTextStream &istream ) { // we open the output file // QTextStream istream(&fIn); const QString outputFileName = OutputFileBoxBatch->url().toLocalFile(); QFile fOut( outputFileName ); fOut.open(QIODevice::WriteOnly); QTextStream ostream(&fOut); QString line; QChar space = ' '; int i = 0; SkyPoint sp; dms raB, decB, galLatB, galLongB; QString epoch0B; while ( ! istream.atEnd() ) { line = istream.readLine(); line.trimmed(); //Go through the line, looking for parameters QStringList fields = line.split( ' ' ); i = 0; // Input coords are galactic coordinates: if (galInputCoords) { // Read Galactic Longitude and write in ostream if corresponds if(galLongCheckBatch->isChecked() ) { galLongB = dms::fromString( fields[i], true); i++; } else galLongB = galLongBoxBatch->createDms(true); if ( allRadioBatch->isChecked() ) ostream << galLongB.toDMSString() << space; else if(galLongCheckBatch->isChecked() ) ostream << galLongB.toDMSString() << space; // Read Galactic Latitude and write in ostream if corresponds if(galLatCheckBatch->isChecked() ) { galLatB = dms::fromString( fields[i], true); i++; } else galLatB = galLatBoxBatch->createDms(true); if ( allRadioBatch->isChecked() ) ostream << galLatB.toDMSString() << space; else if(galLatCheckBatch->isChecked() ) ostream << galLatB.toDMSString() << space; sp = SkyPoint (); sp.GalacticToEquatorial1950(&galLongB, &galLatB); ostream << sp.ra().toHMSString() << space << sp.dec().toDMSString() << epoch0B << endl; // Input coords. are equatorial coordinates: } else { // 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; // Read Epoch and write in ostream if corresponds if(epochCheckBatch->isChecked() ) { epoch0B = fields[i]; i++; } else epoch0B = epochBoxBatch->text(); if ( allRadioBatch->isChecked() ) ostream << epoch0B << space; else if(epochCheckBatch->isChecked() ) ostream << epoch0B << space; sp = SkyPoint (raB, decB); sp.J2000ToB1950(); sp.Equatorial1950ToGalactic(galLongB, galLatB); ostream << galLongB.toDMSString() << space << galLatB.toDMSString() << endl; } } fOut.close(); }