int ln_get_object_rst_horizon_offset (double JD, struct ln_lnlat_posn * observer, struct ln_equ_posn * object, long double horizon, struct ln_rst_time * rst, double ut_offset) { int jd; long double O, JD_UT, H0, H1; double Hat, Har, Has, altr, alts; double mt, mr, ms, mst, msr, mss; double dmt, dmr, dms; int ret, i; if (isnan (ut_offset)) { JD_UT = JD; } else { /* convert local sidereal time into degrees for 0h of UT on day JD */ jd = (int)JD; JD_UT = jd + ut_offset; } O = ln_get_apparent_sidereal_time (JD_UT); O *= 15.0; /* equ 15.1 */ H0 = (sin (ln_deg_to_rad (horizon)) - sin (ln_deg_to_rad (observer->lat)) * sin (ln_deg_to_rad (object->dec))); H1 = (cos (ln_deg_to_rad (observer->lat)) * cos (ln_deg_to_rad (object->dec))); H1 = H0 / H1; ret = check_coords (observer, H1, horizon, object); if (ret) return ret; H0 = acos (H1); H0 = ln_rad_to_deg (H0); /* equ 15.2 */ mt = (object->ra - observer->lng - O) / 360.0; mr = mt - H0 / 360.0; ms = mt + H0 / 360.0; for (i = 0; i < 3; i++) { /* put in correct range */ if (mt > 1.0) mt--; else if (mt < 0) mt++; if (mr > 1.0) mr--; else if (mr < 0) mr++; if (ms > 1.0) ms--; else if (ms < 0) ms++; /* find sidereal time at Greenwich, in degrees, for each m */ mst = O + 360.985647 * mt; msr = O + 360.985647 * mr; mss = O + 360.985647 * ms; /* find local hour angle */ Hat = mst + observer->lng - object->ra; Har = msr + observer->lng - object->ra; Has = mss + observer->lng - object->ra; /* find altitude for rise and set */ altr = sin (ln_deg_to_rad (observer->lat)) * sin (ln_deg_to_rad (object->dec)) + cos (ln_deg_to_rad (observer->lat)) * cos (ln_deg_to_rad (object->dec)) * cos (ln_deg_to_rad (Har)); alts = sin (ln_deg_to_rad (observer->lat)) * sin (ln_deg_to_rad (object->dec)) + cos (ln_deg_to_rad (observer->lat)) * cos (ln_deg_to_rad (object->dec)) * cos (ln_deg_to_rad (Has)); /* must be in degrees */ altr = ln_rad_to_deg (altr); alts = ln_rad_to_deg (alts); /* corrections for m */ ln_range_degrees (Hat); if (Hat > 180.0) Hat -= 360; dmt = -(Hat / 360.0); dmr = (altr - horizon) / (360 * cos (ln_deg_to_rad (object->dec)) * cos (ln_deg_to_rad (observer->lat)) * sin (ln_deg_to_rad (Har))); dms = (alts - horizon) / (360 * cos (ln_deg_to_rad (object->dec)) * cos (ln_deg_to_rad (observer->lat)) * sin (ln_deg_to_rad (Has))); /* add corrections and change to JD */ mt += dmt; mr += dmr; ms += dms; if (mt <= 1 && mt >= 0 && mr <= 1 && mr >= 0 && ms <= 1 && ms >= 0) break; } rst->rise = JD_UT + mr; rst->transit = JD_UT + mt; rst->set = JD_UT + ms; /* not circumpolar */ return 0; }
// update_bars() is called if anything changes that will cause the scroll // bars to change (move/resize etc). This will happen if total_, page_ // or line_ sizes change, the window is resized, font changed, etc. // If the parameter 'newpos' is not null_point then the display position // will be moved to that position. Note that the display may be redrawn. void CScrView::update_bars(CPointAp newpos) { if (in_update_ || m_hWnd == NULL) return; in_update_ = TRUE; // TRACE0("--- update_bars\n"); check_coords(); // Check that mapping mode not changed caret_hide(); // Get info needed in later calcs TEXTMETRIC tm; { CClientDC dc(this); OnPrepareDC(&dc); dc.GetTextMetrics(&tm); } // Get display area and convert to logical units (but with +ve values) CRect cli; GetDisplayRect(&cli); //CRectAp doc_rect = ConvertFromDP(cli) - GetScroll(); // If newpos not specified use old pos if (newpos == null_point) newpos = scrollpos_; ASSERT(newpos.x >= 0 && newpos.y >= 0); if (!page_specified_ || !line_specified_) { // Calculate amount of line and page scroll based on size of font if (!page_specified_) { // Recalc page size int lines = cli.Height()/tm.tmHeight + tm.tmExternalLeading - 1; if (lines < 1) lines = 1; page_.cx = cli.Width() - tm.tmAveCharWidth; page_.cy = lines * (tm.tmHeight + tm.tmExternalLeading); } if (!line_specified_) { // Recalc line size line_.cx = tm.tmAveCharWidth; line_.cy = tm.tmHeight + tm.tmExternalLeading; } } // Update display and scroll bars. ASSERT(total_.cx >= 0 && total_.cy >= 0); // If display position has changed redraw/scroll to it if (newpos != scrollpos_) { scroll_up_ = newpos.y < scrollpos_.y; // Get scroll & new positions in real logical coords CPointAp t_scroll = scrollpos_; if (negx()) t_scroll.x = -t_scroll.x; if (negy()) t_scroll.y = -t_scroll.y; CPointAp t_newpos = newpos; if (negx()) t_newpos.x = -t_newpos.x; if (negy()) t_newpos.y = -t_newpos.y; // // For OWNDC window and mapping mode != MM_TEXT ScrollWindow // // does not move caret properly!?!? - so we do it ourselves! __int64 tmp = t_scroll.y < t_newpos.y ? t_newpos.y - t_scroll.y : t_scroll.y - t_newpos.y; if (abs(int(t_scroll.x - t_newpos.x)) > cli.Width() || tmp > __int64(cli.Height())) DoInvalidate(); // ScrollWindow() can't handle big numbers else { // Work out scroll amount in device coordinates // LPtoDP can't handle more than 16 bits (signed) CPoint dev_scroll, dev_newpos; dev_scroll.x = t_scroll.x; dev_scroll.y = int(t_scroll.y); dev_newpos.x = t_newpos.x; dev_newpos.y = int(t_newpos.y); { // Put in compound statement so DC released ASAP CClientDC dc(this); OnPrepareDC(&dc); dc.LPtoDP(&dev_scroll); dc.LPtoDP(&dev_newpos); } DoScrollWindow(dev_scroll.x - dev_newpos.x, dev_scroll.y - dev_newpos.y); } } if (total_.cx <= 0) DoHScroll(0, 0, 0); // disable scroll bar else if (newpos.x > total_.cx - cli.Width()) { // Handle scroll position past right edge DoHScroll(int(((__int64)(newpos.x + cli.Width()) * maxbar_.cx) / total_.cx), (cli.Width() * maxbar_.cx) / total_.cx + 1, int(((__int64)newpos.x * maxbar_.cx) / total_.cx) ); } else { DoHScroll(maxbar_.cx, (cli.Width() * maxbar_.cx) / total_.cx + 1, int(((__int64)newpos.x * maxbar_.cx) / total_.cx) ); } if (total_.cy <= 0) DoVScroll(0, 0, 0); // disable scroll bar else if (newpos.y > total_.cy - cli.Height()) { // Handle scroll position if (somehow) moved past end DoVScroll(int(((__int64)(newpos.y + cli.Height()) * maxbar_.cy) / total_.cy), int((cli.Height() * maxbar_.cy) / total_.cy + 1), int(((__int64)newpos.y * maxbar_.cy) / total_.cy) ); } else { DoVScroll(int(maxbar_.cy), int((cli.Height() * maxbar_.cy) / total_.cy + 1), int(((__int64)newpos.y * maxbar_.cy) / total_.cy) ); } // Store new position and force redraw before restore of scroll_up_ scrollpos_ = newpos; // Keep track of where we moved to ASSERT(scrollpos_.x >= 0 && scrollpos_.y >= 0); // if (GetFocus() == this) caret_show(); DoUpdateWindow(); // Force redraw before changing scroll_up_ scroll_up_ = FALSE; // Make sure redraw defaults to downwards // Get client window again as changing the scroll bars may have changed it // (and nested size event was blocked by in_update_ flag) GetDisplayRect(&cli); CRectAp doc_rect = ConvertFromDP(cli); win_height_ = doc_rect.bottom - doc_rect.top; win_width_ = doc_rect.right - doc_rect.left; AfterScroll(newpos); in_update_ = FALSE; }
int ln_get_motion_body_rst_horizon_offset (double JD, struct ln_lnlat_posn * observer, get_motion_body_coords_t get_motion_body_coords, void * orbit, double horizon, struct ln_rst_time * rst, double ut_offset) { int jd; double T, O, JD_UT, H0, H1; double Hat, Har, Has, altr, alts; double mt, mr, ms, mst, msr, mss, nt, nr, ns; struct ln_equ_posn sol1, sol2, sol3, post, posr, poss; double dmt, dmr, dms; int ret, i; /* dynamical time diff */ T = ln_get_dynamical_time_diff (JD); if (isnan (ut_offset)) { JD_UT = JD; } else { jd = (int)JD; JD_UT = jd + ut_offset; } O = ln_get_apparent_sidereal_time (JD_UT); O *= 15.0; /* get body coords for JD_UT -1, JD_UT and JD_UT + 1 */ get_motion_body_coords (JD_UT - 1.0, orbit, &sol1); get_motion_body_coords (JD_UT, orbit, &sol2); get_motion_body_coords (JD_UT + 1.0, orbit, &sol3); /* equ 15.1 */ H0 = (sin(ln_deg_to_rad (horizon)) - sin(ln_deg_to_rad(observer->lat)) * sin(ln_deg_to_rad(sol2.dec))); H1 = (cos(ln_deg_to_rad(observer->lat)) * cos(ln_deg_to_rad(sol2.dec))); H1 = H0 / H1; ret = check_coords (observer, H1, horizon, &sol2); if (ret) return ret; H0 = acos (H1); H0 = ln_rad_to_deg (H0); /* correct ra values for interpolation - put them to the same side of circle */ if ((sol1.ra - sol2.ra) > 180.0) sol2.ra += 360; if ((sol2.ra - sol3.ra) > 180.0) sol3.ra += 360; if ((sol3.ra - sol2.ra) > 180.0) sol3.ra -= 360; if ((sol2.ra - sol1.ra) > 180.0) sol3.ra -= 360; for (i = 0; i < 3; i++) { /* equ 15.2 */ mt = (sol2.ra - observer->lng - O) / 360.0; mr = mt - H0 / 360.0; ms = mt + H0 / 360.0; /* put in correct range */ if (mt > 1.0 ) mt--; else if (mt < 0.0) mt++; if (mr > 1.0 ) mr--; else if (mr < 0.0) mr++; if (ms > 1.0 ) ms--; else if (ms < 0.0) ms++; /* find sidereal time at Greenwich, in degrees, for each m*/ mst = O + 360.985647 * mt; msr = O + 360.985647 * mr; mss = O + 360.985647 * ms; nt = mt + T / 86400.0; nr = mr + T / 86400.0; ns = ms + T / 86400.0; /* interpolate ra and dec for each m, except for transit dec (dec2) */ posr.ra = ln_interpolate3 (nr, sol1.ra, sol2.ra, sol3.ra); posr.dec = ln_interpolate3 (nr, sol1.dec, sol2.dec, sol3.dec); post.ra = ln_interpolate3 (nt, sol1.ra, sol2.ra, sol3.ra); poss.ra = ln_interpolate3 (ns, sol1.ra, sol2.ra, sol3.ra); poss.dec = ln_interpolate3 (ns, sol1.dec, sol2.dec, sol3.dec); /* find local hour angle */ Hat = mst + observer->lng - post.ra; Har = msr + observer->lng - posr.ra; Has = mss + observer->lng - poss.ra; /* find altitude for rise and set */ altr = sin(ln_deg_to_rad(observer->lat)) * sin(ln_deg_to_rad(posr.dec)) + cos(ln_deg_to_rad(observer->lat)) * cos(ln_deg_to_rad(posr.dec)) * cos(ln_deg_to_rad (Har)); alts = sin(ln_deg_to_rad(observer->lat)) * sin(ln_deg_to_rad(poss.dec)) + cos(ln_deg_to_rad(observer->lat)) * cos(ln_deg_to_rad(poss.dec)) * cos(ln_deg_to_rad (Has)); /* corrections for m */ dmt = - (Hat / 360.0); dmr = (altr - horizon) / (360 * cos(ln_deg_to_rad(posr.dec)) * cos(ln_deg_to_rad(observer->lat)) * sin(ln_deg_to_rad(Har))); dms = (alts - horizon) / (360 * cos(ln_deg_to_rad(poss.dec)) * cos(ln_deg_to_rad(observer->lat)) * sin(ln_deg_to_rad(Has))); /* add corrections and change to JD */ mt += dmt; mr += dmr; ms += dms; if (mt <= 1 && mt >= 0 && mr <= 1 && mr >= 0 && ms <= 1 && ms >= 0) break; } rst->rise = JD_UT + mr; rst->transit = JD_UT + mt; rst->set = JD_UT + ms; /* not circumpolar */ return 0; }
void CScrView::OnInitialUpdate() { check_coords(); CView::OnInitialUpdate(); }