// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// Copyright Liam Girdwood 2003
#include "sky_spherical.hh"
#include <libgnomecanvasmm/line.h>
#include <libgnomecanvasmm/bpath.h>
#include <libgnomecanvasmm/ellipse.h>
#include <math.h>
/*! \namespace Vega
* \brief Nova Virtual Sky Engine
*/
namespace Vega
{
/*! \fn SkySpherical::SkySpherical(double x_size, double y_size)
* \param x_size Virtual sky x size
* \param y_size Virtual sky y size
*
* Constructor
*/
SkySpherical::SkySpherical()
{
m_spherical = true;
}
/*! \fn SkySpherical::~SkySpherical()
* Destructor
*/
SkySpherical::~SkySpherical()
{
}
void SkySpherical::render_planets()
{
struct ln_equ_posn equ;
double ra, dec;
double ra_offset;
// calc offset
if (m_is_ra_over)
ra_offset = MIN_RA;
else
ra_offset = m_ra_offset;
if (m_mercury.get_mag(m_JD) < m_clip_mag_max) {
m_mercury.get_equ_posn(m_JD, ra, dec);
transform (ra, dec, ra_offset);
m_mercury.set_render_jd(m_JD);
m_mercury.render (ra, dec, m_clip_mag_max, *m_object_group, false, m_ra_ppd);
}
if (m_venus.get_mag(m_JD) < m_clip_mag_max) {
m_venus.get_equ_posn(m_JD, ra, dec);
transform (ra, dec, ra_offset);
m_venus.set_render_jd(m_JD);
m_venus.render (ra, dec, m_clip_mag_max, *m_object_group, false, m_ra_ppd);
}
if (m_mars.get_mag(m_JD) < m_clip_mag_max) {
m_mars.get_equ_posn(m_JD, ra, dec);
transform (ra, dec, ra_offset);
m_mars.set_render_jd(m_JD);
m_mars.render (ra, dec, m_clip_mag_max, *m_object_group, false, m_ra_ppd);
}
if (m_jupiter.get_mag(m_JD) < m_clip_mag_max) {
m_jupiter.get_equ_posn(m_JD, ra, dec);
transform (ra, dec, ra_offset);
m_jupiter.set_render_jd(m_JD);
m_jupiter.render (ra, dec, m_clip_mag_max, *m_object_group, false, m_ra_ppd);
}
if (m_saturn.get_mag(m_JD) < m_clip_mag_max) {
m_saturn.get_equ_posn(m_JD, ra, dec);
transform (ra, dec, ra_offset);
m_saturn.set_render_jd(m_JD);
m_saturn.render (ra, dec, m_clip_mag_max, *m_object_group, false, m_ra_ppd);
}
if (m_uranus.get_mag(m_JD) < m_clip_mag_max) {
m_uranus.get_equ_posn(m_JD, ra, dec);
transform (ra, dec, ra_offset);
m_uranus.set_render_jd(m_JD);
m_uranus.render (ra, dec, m_clip_mag_max, *m_object_group, false, m_ra_ppd);
}
if (m_neptune.get_mag(m_JD) < m_clip_mag_max) {
m_neptune.get_equ_posn(m_JD, ra, dec);
transform (ra, dec, ra_offset);
m_neptune.set_render_jd(m_JD);
m_neptune.render (ra, dec, m_clip_mag_max, *m_object_group, false, m_ra_ppd);
}
if (m_pluto.get_mag(m_JD) < m_clip_mag_max) {
m_pluto.get_equ_posn(m_JD, ra, dec);
transform (ra, dec, ra_offset);
m_pluto.set_render_jd(m_JD);
m_pluto.render (ra, dec, m_clip_mag_max, *m_object_group, false, m_ra_ppd);
}
if (m_is_ra_over || m_is_ra_under) {
// get ra offset
if (m_is_ra_under)
ra_offset = m_ra_offset + MAX_RA; //rhs
else
ra_offset = -MAX_RA; //lhs
if (m_mercury.get_mag(m_JD) < m_clip_mag_max) {
m_mercury.get_equ_posn(m_JD, ra, dec);
transform (ra, dec, ra_offset);
m_mercury.set_render_jd(m_JD);
m_mercury.render (ra, dec, m_clip_mag_max, *m_object_group, false, m_ra_ppd);
}
if (m_venus.get_mag(m_JD) < m_clip_mag_max) {
m_venus.get_equ_posn(m_JD, ra, dec);
transform (ra, dec, ra_offset);
m_venus.set_render_jd(m_JD);
m_venus.render (ra, dec, m_clip_mag_max, *m_object_group, false, m_ra_ppd);
}
if (m_mars.get_mag(m_JD) < m_clip_mag_max) {
m_mars.get_equ_posn(m_JD, ra, dec);
transform (ra, dec, ra_offset);
m_mars.set_render_jd(m_JD);
m_mars.render (ra, dec, m_clip_mag_max, *m_object_group, false, m_ra_ppd);
}
if (m_jupiter.get_mag(m_JD) < m_clip_mag_max) {
m_jupiter.get_equ_posn(m_JD, ra, dec);
transform (ra, dec, ra_offset);
m_jupiter.set_render_jd(m_JD);
m_jupiter.render (ra, dec, m_clip_mag_max, *m_object_group, false, m_ra_ppd);
}
if (m_saturn.get_mag(m_JD) < m_clip_mag_max) {
m_saturn.get_equ_posn(m_JD, ra, dec);
transform (ra, dec, ra_offset);
m_saturn.set_render_jd(m_JD);
m_saturn.render (ra, dec, m_clip_mag_max, *m_object_group, false, m_ra_ppd);
}
if (m_uranus.get_mag(m_JD) < m_clip_mag_max) {
m_uranus.get_equ_posn(m_JD, ra, dec);
transform (ra, dec, ra_offset);
m_uranus.set_render_jd(m_JD);
m_uranus.render (ra, dec, m_clip_mag_max, *m_object_group, false, m_ra_ppd);
}
if (m_neptune.get_mag(m_JD) < m_clip_mag_max) {
m_neptune.get_equ_posn(m_JD, ra, dec);
transform (ra, dec, ra_offset);
m_neptune.set_render_jd(m_JD);
m_neptune.render (ra, dec, m_clip_mag_max, *m_object_group, false, m_ra_ppd);
}
if (m_pluto.get_mag(m_JD) < m_clip_mag_max) {
m_pluto.get_equ_posn(m_JD, ra, dec);
transform (ra, dec, ra_offset);
m_pluto.set_render_jd(m_JD);
m_pluto.render (ra, dec, m_clip_mag_max, *m_object_group, false, m_ra_ppd);
}
}
}
/*! \fn void SkySpherical::render_grid()
*
* Render grid on virtual sky.
*/
void SkySpherical::render_grid()
{
return; // for now
std::vector<Grid::GridLine> ra_points, ra_overlap_points;
std::vector<Grid::GridLine> dec_points, dec_overlap_points;
std::vector<Grid::GridLine>::iterator ra;
std::vector<Grid::GridLine>::iterator dec;
double ra_offset;
// clip and get lines
m_grid.clip(m_clip_ra_min, m_clip_dec_min, m_clip_ra_max, m_clip_dec_max);
std::cout << " bpath ra lines " << m_grid.get_ra_lines(ra_points);
std::cout << " bpath dec lines " << m_grid.get_dec_lines(dec_points);
// are we overlapping
if (m_is_ra_over || m_is_ra_under) {
m_grid.clip(m_clip_ra_min_overlap, m_clip_dec_min, m_clip_ra_max_overlap, m_clip_dec_max);
m_grid.get_ra_lines(ra_overlap_points, true);
m_grid.get_dec_lines(dec_overlap_points);
}
// calc offset
if (m_is_ra_over)
ra_offset = MIN_RA;
else
ra_offset = m_ra_offset;
// now render ra grid
for (ra = ra_points.begin(); ra != ra_points.end(); ra++) {
double mid_x, mid_y;
Glib::RefPtr<Gnome::Canvas::PathDef> path
= Gnome::Canvas::PathDef::create();
mid_x = (*ra).x1 + (((*ra).x2 - (*ra).x1) / 2.0);
mid_y = (*ra).y1 + (((*ra).y2 - (*ra).y1) / 2.0);
transform_grid((*ra).x1, (*ra).y1, ra_offset);
transform_grid(mid_x, mid_y, ra_offset);
transform_grid((*ra).x2, (*ra).y2, ra_offset);
path->moveto((*ra).x1, (*ra).y1);
path->curveto((*ra).x1, (*ra).y1, mid_x, mid_y, (*ra).x2, (*ra).y2);
Gnome::Canvas::Bpath* line = manage(new Gnome::Canvas::Bpath(*m_grid_group));
line->set_bpath(path);
line->property_outline_color () = "grey";
line->property_width_pixels () = 1;
}
// render dec grid
for (dec = dec_points.begin(); dec != dec_points.end(); dec++) {
double mid_x, mid_y;
Glib::RefPtr<Gnome::Canvas::PathDef> path
= Gnome::Canvas::PathDef::create();
mid_x = (*dec).x1 + (((*dec).x2 - (*dec).x1) / 2.0);
mid_y = (*dec).y1 + (((*dec).y2 - (*dec).y1) / 2.0);
transform_grid((*dec).x1, (*dec).y1, ra_offset);
transform_grid(mid_x, mid_y, ra_offset);
transform_grid((*dec).x2, (*dec).y2, ra_offset);
path->moveto((*dec).x1, (*dec).y1);
path->curveto((*dec).x1, (*dec).y1,
mid_x, mid_y,
(*dec).x2, (*dec).y2);
Gnome::Canvas::Bpath* line = manage(new Gnome::Canvas::Bpath(*m_grid_group));
line->set_bpath(path);
line->property_outline_color () = "grey";
line->property_width_pixels () = 1;
}
if (m_is_ra_over || m_is_ra_under) {
// get ra offset
if (m_is_ra_under)
ra_offset = m_ra_offset + MAX_RA; //rhs
else
ra_offset = -MAX_RA; //lhs
// now render ra grid
for (ra = ra_overlap_points.begin(); ra != ra_overlap_points.end(); ra++) {
double mid_x, mid_y;
Glib::RefPtr<Gnome::Canvas::PathDef> path
= Gnome::Canvas::PathDef::create();
mid_x = (*ra).x1 + (((*ra).x2 - (*ra).x1) / 2.0);
mid_y = (*ra).y1 + (((*ra).y2 - (*ra).y1) / 2.0);
transform_grid((*ra).x1, (*ra).y1, ra_offset);
transform_grid(mid_x, mid_y, ra_offset);
transform_grid((*ra).x2, (*ra).y2, ra_offset);
path->moveto((*ra).x1, (*ra).y1);
path->curveto((*ra).x1, (*ra).y1,
mid_x, mid_y,
(*ra).x2, (*ra).y2);
Gnome::Canvas::Bpath* line = manage(new Gnome::Canvas::Bpath(*m_grid_group));
line->set_bpath(path);
line->property_outline_color () = "grey";
line->property_width_pixels () = 1;
}
// render dec grid
for (dec = dec_overlap_points.begin(); dec != dec_overlap_points.end(); dec++) {
double mid_x, mid_y;
Glib::RefPtr<Gnome::Canvas::PathDef> path
= Gnome::Canvas::PathDef::create();
mid_x = (*dec).x1 + (((*dec).x2 - (*dec).x1) / 2.0);
mid_y = (*dec).y1 + (((*dec).y2 - (*dec).y1) / 2.0);
transform_grid((*dec).x1, (*dec).y1, ra_offset);
transform_grid(mid_x, mid_y, ra_offset);
transform_grid((*dec).x2, (*dec).y2, ra_offset);
path->moveto((*dec).x1, (*dec).y1);
path->curveto((*dec).x1, (*dec).y1,
mid_x, mid_y,
(*dec).x2, (*dec).y2);
Gnome::Canvas::Bpath* line = manage(new Gnome::Canvas::Bpath(*m_grid_group));
line->set_bpath(path);
line->property_outline_color () = "grey";
line->property_width_pixels () = 1;
}
}
}
/*! \fn void SkySpherical::render_const_lines()
*
* Render virtual sky constellation lines.
*/
void SkySpherical::render_const_lines()
{
std::vector<Constellation::ConstLine> lines, overlap_lines;
std::vector<Constellation::ConstLine>::iterator i;
Gnome::Canvas::Line* line;
double ra_offset;
// delete constellations
delete m_const_group;
m_const_group = Gtk::manage (new Gnome::Canvas::Group (*m_root, 0, 0));
// clip and get lines
m_constellation.clip(m_clip_ra_min, m_clip_dec_min, m_clip_ra_max, m_clip_dec_max);
std::cout << " ra lines " << m_constellation.get_lines(lines);
std::cout << " ratio " << m_canvas_ratio << std::endl;
// are we overlapping
if (m_is_ra_over || m_is_ra_under) {
m_constellation.clip(m_clip_ra_min_overlap, m_clip_dec_min, m_clip_ra_max_overlap, m_clip_dec_max);
m_constellation.get_lines(overlap_lines);
}
// calc offset
if (m_is_ra_over)
ra_offset = MIN_RA;
else
ra_offset = m_ra_offset;
// now render each line
for (i = lines.begin(); i != lines.end(); i++) {
Gnome::Canvas::Points line_points;
transform((*i).ra1, (*i).dec1, ra_offset);
if (!is_visible((*i).ra1, (*i).dec1))
continue;
transform((*i).ra2, (*i).dec2, ra_offset);
if (!is_visible((*i).ra2, (*i).dec2))
continue;
line_points.push_back(Gnome::Art::Point((*i).ra1, (*i).dec1));
line_points.push_back(Gnome::Art::Point((*i).ra2, (*i).dec2));
line = Gtk::manage(new Gnome::Canvas::Line(*m_const_group, line_points));
*line << Gnome::Canvas::Properties::fill_color("blue");
}
if (m_is_ra_over || m_is_ra_under) {
// get ra offset
if (m_is_ra_under)
ra_offset = m_ra_offset + MAX_RA; //rhs
else
ra_offset = -MAX_RA; //lhs
// now render lines
for (i = overlap_lines.begin(); i != overlap_lines.end(); i++) {
Gnome::Canvas::Points line_points;
transform((*i).ra1, (*i).dec1, ra_offset);
if (!is_visible((*i).ra1, (*i).dec1))
continue;
transform((*i).ra2, (*i).dec2, ra_offset);
if (!is_visible((*i).ra2, (*i).dec2))
continue;
line_points.push_back(Gnome::Art::Point((*i).ra1, (*i).dec1));
line_points.push_back(Gnome::Art::Point((*i).ra2, (*i).dec2));
line = Gtk::manage(new Gnome::Canvas::Line(*m_const_group, line_points));
*line << Gnome::Canvas::Properties::fill_color("blue");
}
}
}
/*! \fn void SkySpherical::render_const_bounds()
*
* Render virtual sky constellation boundaries
*/
void SkySpherical::render_const_bounds()
{
}
/*! \fn void SkySpherical::render_const_names()
*
* Render virtual sky constellation names.
*/
void SkySpherical::render_const_names()
{
}
/*! \fn void SkySpherical::get_position (double x, double y, double& ra, double& dec);
* \brief get sky ra,dec at x,y coordinates
*/
void SkySpherical::get_position (double x, double y, double& ra, double& dec)
{
}
/*! \fn void SkySpherical::transform_grid (double& x, double& y, double dec_offset)
* \param x X coordinate
* \param y Y coordinate
* \param object Astro object
*
* Transform the objects RA nad DEC into virtual sky coordinates.
*/
void SkySpherical::transform_grid (double& x, double& y, double ra_offset)
{
y += m_centre_dec;
transform(x, y, ra_offset);
}
/*! \fn void SkySpherical::transform(double& x, double& y, Castor::AstroObject* object)
* \param x X coordinate
* \param y Y coordinate
* \param object Astro object
*
* Transform the objects RA nad DEC into virtual sky coordinates.
*/
void SkySpherical::transform(double& x, double& y, double ra_offset)
{
double xd,yd,zd;
double ratio;
// subtract centre
x -= m_centre_ra;
y -= m_centre_dec;
// convert to radians
x = (x / 360.0) * 2.0 * M_PI;
y = (y / 360.0) * 2.0 * M_PI;
// project to spherical vsky
xd = cos(y) * sin(x);
yd = sin(y);
zd = cos(y) * cos(x);
x = xd / (1.0 + zd);
y = yd / (1.0 + zd);
//std::cout << x << " " << y << std::endl;
// convert back to canvas scale
ratio = MAX_FOV / m_fov;
x = (m_canvas_width / 2) - ((x * m_canvas_height / 2.0) * ratio);
y = (m_canvas_height / 2) - ((y * m_canvas_height / 2.0) * ratio);
}
/*! \fn virtual bool is_visible(double x, double y) = 0;
* Is the object visible ?
*/
bool SkySpherical::is_visible(double x, double y)
{
double dx = x - (m_canvas_width / 2);
double dy = y - (m_canvas_height / 2);
double dist = dx * dx + dy * dy;
dist = sqrt (dist);
if (dist > m_outer_size)
return false;
else
return true;
}
void SkySpherical::render_basic()
{
// delete existing
delete m_object_group;
m_object_group = Gtk::manage (new Gnome::Canvas::Group (*m_root, 0, 0));
// render outer circle
m_outer_size = ((m_canvas_height / 2.0) * (MAX_FOV / m_fov));
if (m_outer_size > 1.5 * m_canvas_width)
return;
double xmin = m_canvas_width / 2.0 - m_outer_size;
double xmax = m_canvas_width / 2.0 + m_outer_size;
double ymin = m_canvas_height / 2.0 - m_outer_size;
double ymax = m_canvas_height / 2.0 + m_outer_size;
Gnome::Canvas::Ellipse * outer_bounds = manage(new Gnome::Canvas::Ellipse(*m_object_group,
xmin, ymin, xmax, ymax));
outer_bounds->property_outline_color () = "grey";
outer_bounds->property_width_pixels () = 1;
std::cout <<" outer size " << m_outer_size << std::endl;
}
};
syntax highlighted by Code2HTML, v. 0.9.1