2 * Copyright (C) 2008 Liam Girdwood
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330,
17 * Boston, MA 02111-1307, USA.
19 * Fast sky grid render engine. Mostly working, although probably needs
20 * checking by a maths trig guru to further optimise (and clip RA line at 80).
24 #define _GNU_SOURCE /* for NAN and INF */
29 #include "astro_object.h"
32 #define D2R (1.7453292519943295769e-2) /* deg->radian */
33 #define R2D (5.7295779513082320877e1) /* radian->deg */
35 #define GRID_BISECT 128.0
36 #define GRID_NIGHT_ALPHA 0.35
37 #define GRID_DAY_ALPHA 0.45
38 #define GRID_HALF_MAX_FOV (PROJ_MAX_FOV / 2.0)
41 /* RA grid in arcsecs */
42 static const gdouble grid_hms_ra
[] = {
54 /* DEC drid in arcsecs */
55 static const gdouble grid_dms_dec
[] = {
68 static inline int equ_is_tile_visible(struct projection
*proj
, gint ra
, gint dec
)
70 struct render_object robject
;
71 struct ln_equ_posn pos
;
73 pos
.ra
= ra
* GRID_RA_TILE_SIZE
;
74 pos
.dec
= PROJ_MIN_DEC
+ dec
* GRID_DEC_TILE_SIZE
;
75 robject
.coord
[0].posn
= &pos
;
76 proj
->trans
->sky_to_proj_equ(proj
, &robject
.coord
[0]);
77 return projection_is_visible0(proj
, &robject
);
80 static inline int hrz_is_tile_visible(struct projection
*proj
, gint ra
, gint dec
)
82 struct render_object robject
;
83 struct ln_equ_posn pos
;
85 pos
.ra
= ra
* GRID_RA_TILE_SIZE
;
86 pos
.dec
= PROJ_MIN_DEC
+ dec
* GRID_DEC_TILE_SIZE
;
87 robject
.coord
[0].posn
= &pos
;
88 proj
->trans
->sky_to_proj_hrz(proj
, &robject
.coord
[0]);
89 return projection_is_visible0(proj
, &robject
);
92 static inline void mark_tiles(struct projection
*proj
,
95 gint ra_start
= ra
- 1, ra_end
= ra
+ 1;
96 gint dec_start
= dec
- 1, dec_end
= dec
+ 1;
99 ra_start
= GRID_RA_TILES
-1;
100 if (ra_end
== GRID_RA_TILES
)
104 if (dec_end
== GRID_DEC_TILES
)
105 dec_end
= GRID_DEC_TILES
- 1;
107 proj
->grid_tile
[ra
][dec
] = 1;
108 proj
->grid_tile
[ra_start
][dec_start
] = 1;
109 proj
->grid_tile
[ra_end
][dec_start
] = 1;
110 proj
->grid_tile
[ra_start
][dec_end
] = 1;
111 proj
->grid_tile
[ra_end
][dec_end
] = 1;
112 proj
->grid_tile
[ra
][dec_start
] = 1;
113 proj
->grid_tile
[ra
][dec_end
] = 1;
114 proj
->grid_tile
[ra_start
][dec
] = 1;
115 proj
->grid_tile
[ra_end
][dec
] = 1;
118 static void equ_get_visible_tiles(struct projection
*proj
)
122 /* clear all tiles first */
123 for (ra
= 0; ra
< GRID_RA_TILES
; ra
++) {
124 for (dec
= 0; dec
< GRID_DEC_TILES
; dec
++) {
125 proj
->grid_tile
[ra
][dec
] = 0;
129 /* check each tile */
130 for (ra
= 0; ra
< GRID_RA_TILES
; ra
++) {
131 for (dec
= 0; dec
< GRID_DEC_TILES
; dec
++) {
132 if (equ_is_tile_visible(proj
, ra
, dec
))
133 mark_tiles(proj
, ra
, dec
);
137 /* now check centre RA, DEC if tile size > fov */
138 if (proj
->fov
<= GRID_RA_TILE_SIZE
* 1.1)
139 mark_tiles(proj
, (gint
)(proj
->centre_az
/ GRID_RA_TILE_SIZE
),
140 (gint
)(proj
->centre_alt
/ GRID_DEC_TILE_SIZE
+ 9));
143 static void hrz_get_visible_tiles(struct projection
*proj
)
147 /* clear all tiles first */
148 for (ra
= 0; ra
< GRID_RA_TILES
; ra
++) {
149 for (dec
= 0; dec
< GRID_DEC_TILES
; dec
++) {
150 proj
->grid_tile
[ra
][dec
] = 0;
154 /* check each tile */
155 for (ra
= 0; ra
< GRID_RA_TILES
; ra
++) {
156 for (dec
= 0; dec
< GRID_DEC_TILES
; dec
++) {
157 if (hrz_is_tile_visible(proj
, ra
, dec
))
158 mark_tiles(proj
, ra
, dec
);
162 /* now check centre RA, DEC if tile size > fov */
163 if (proj
->fov
<= GRID_RA_TILE_SIZE
* 1.1)
164 mark_tiles(proj
, (gint
)(proj
->centre_az
/ GRID_RA_TILE_SIZE
),
165 (gint
)(proj
->centre_alt
/ GRID_DEC_TILE_SIZE
+ 9));
168 /* get grid RA step size for projection in arcsecs */
169 static gdouble
get_ra_step_delta(struct projection
*proj
)
173 for (i
= 0; i
< nsize(grid_hms_ra
); i
++) {
174 if (proj
->fov
/ 1.1 > grid_hms_ra
[i
] / 3600.0)
175 return grid_hms_ra
[i
] / 3600.0;
177 return grid_hms_ra
[i
] / 3600.0;
180 /* get grid DEC step size for projection in arcsecs */
181 static gdouble
get_dec_step_delta(struct projection
*proj
)
185 for (i
= 0; i
< nsize(grid_dms_dec
); i
++) {
186 if (proj
->fov
/ 1.1 > grid_dms_dec
[i
] / 3600.0)
187 return grid_dms_dec
[i
] / 3600.0;
189 return grid_dms_dec
[i
] / 3600.0;
192 static void equ_render_dec_labels_at(struct projection
*proj
,
193 struct render_object
*robject
, gdouble dec
)
196 gdouble step_delta
, delta_div
= 2.0;
197 struct ln_equ_posn pos_start
, pos_end
;
200 step_delta
= get_dec_step_delta(proj
);
202 pos_start
.ra
= proj
->centre_az
;
203 pos_end
.ra
= proj
->centre_az
;
204 pos_start
.dec
= pos_end
.dec
= dec
;
205 robject
->coord
[0].posn
= &pos_start
;
206 robject
->coord
[1].posn
= &pos_end
;
208 /* find start position */
210 pos_start
.ra
-= step_delta
;
211 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[0]);
212 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[1]);
213 } while (projection_is_visible0(proj
, robject
) &&
214 proj
->centre_az
- pos_start
.ra
< GRID_HALF_MAX_FOV
);
215 pos_start
.ra
+= step_delta
;
217 /* binary chop start */
219 pos_start
.ra
-= step_delta
/ delta_div
;
220 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[0]);
221 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[1]);
222 if (!projection_is_visible0(proj
, robject
))
223 pos_start
.ra
+= step_delta
/ delta_div
;
225 } while (delta_div
< GRID_BISECT
);
227 /* find end position */
229 pos_end
.ra
+= step_delta
;
230 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[0]);
231 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[1]);
232 } while (projection_is_visible1(proj
, robject
) &&
233 pos_end
.ra
- proj
->centre_az
< GRID_HALF_MAX_FOV
);
234 pos_end
.ra
-= step_delta
;
236 /* binary chop end */
239 pos_end
.ra
+= step_delta
/ delta_div
;
240 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[0]);
241 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[1]);
242 if (!projection_is_visible1(proj
, robject
))
243 pos_end
.ra
-= step_delta
/ delta_div
;
245 } while (delta_div
< GRID_BISECT
);
247 ln_deg_to_dms(dec
, &dms
);
252 if (dms
.minutes
== 0 && dms
.seconds
== 0.0)
253 sprintf(&text
[1], "%2.2dº", dms
.degrees
);
254 else if (dms
.seconds
< 0.1)
255 sprintf(&text
[1], "%2.2dº%2.2dm", dms
.degrees
, dms
.minutes
);
257 sprintf(&text
[1], "%2.2dº%2.2dm%2.0f", dms
.degrees
, dms
.minutes
,
260 cairo_move_to(robject
->cr
,
261 robject
->coord
[0].x
- 30.0,
262 robject
->coord
[0].y
- 1.0);
263 cairo_show_text(robject
->cr
, text
);
264 cairo_move_to(robject
->cr
,
265 robject
->coord
[1].x
+ 1.0,
266 robject
->coord
[1].y
- 1.0);
267 cairo_show_text(robject
->cr
, text
);
270 static void equ_render_ra_labels_at(struct projection
*proj
,
271 struct render_object
*robject
, gdouble ra
)
274 gdouble step_delta
, delta_div
= 2.0;
275 struct ln_equ_posn pos_start
, pos_end
;
278 step_delta
= get_ra_step_delta(proj
);
280 pos_start
.dec
= proj
->centre_alt
;
281 pos_end
.dec
= proj
->centre_alt
;
282 pos_start
.ra
= pos_end
.ra
= ra
;
283 robject
->coord
[0].posn
= &pos_start
;
284 robject
->coord
[1].posn
= &pos_end
;
286 /* find start position */
288 pos_start
.dec
-= step_delta
;
289 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[0]);
290 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[1]);
291 } while (projection_is_visible0(proj
, robject
) &&
292 proj
->centre_alt
- pos_start
.dec
< GRID_HALF_MAX_FOV
);
293 pos_start
.dec
+= step_delta
;
295 /* binary chop start */
297 pos_start
.dec
-= step_delta
/ delta_div
;
298 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[0]);
299 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[1]);
300 if (!projection_is_visible0(proj
, robject
))
301 pos_start
.dec
+= step_delta
/ delta_div
;
303 } while (delta_div
< GRID_BISECT
);
305 /* find end position */
307 pos_end
.dec
+= step_delta
;
308 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[0]);
309 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[1]);
310 } while (projection_is_visible1(proj
, robject
) &&
311 pos_end
.dec
- proj
->centre_alt
< GRID_HALF_MAX_FOV
);
312 pos_end
.dec
-= step_delta
;
314 /* binary chop end */
317 pos_end
.dec
+= step_delta
/ delta_div
;
318 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[0]);
319 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[1]);
320 if (!projection_is_visible1(proj
, robject
))
321 pos_end
.dec
-= step_delta
/ delta_div
;
323 } while (delta_div
< GRID_BISECT
);
325 ln_deg_to_hms(ra
, &hms
);
326 if (hms
.minutes
== 0 && hms
.seconds
== 0.0)
327 sprintf(text
, "%2.2dh", hms
.hours
);
328 else if (hms
.seconds
< 0.1)
329 sprintf(text
, "%2.0dh%2.2dm", hms
.hours
, hms
.minutes
);
331 sprintf(text
, "%2.0dh%2.2dm%2.0f", hms
.hours
, hms
.minutes
,
334 cairo_move_to(robject
->cr
,
336 robject
->coord
[0].y
);
337 cairo_show_text(robject
->cr
, text
);
338 cairo_move_to(robject
->cr
,
340 robject
->coord
[1].y
+ 15.0); // font size
341 cairo_show_text(robject
->cr
, text
);
344 static void hrz_render_dec_labels_at(struct projection
*proj
,
345 struct render_object
*robject
, gdouble dec
)
348 gdouble step_delta
, delta_div
= 2.0;
349 struct ln_equ_posn pos_start
, pos_end
;
352 step_delta
= get_dec_step_delta(proj
);
354 pos_start
.ra
= proj
->centre_ra
;
355 pos_end
.ra
= proj
->centre_ra
;
356 pos_start
.dec
= pos_end
.dec
= dec
;
357 robject
->coord
[0].posn
= &pos_start
;
358 robject
->coord
[1].posn
= &pos_end
;
360 /* find start position */
362 pos_start
.ra
-= step_delta
;
363 proj
->trans
->sky_to_proj_hrz(proj
, &robject
->coord
[0]);
364 proj
->trans
->sky_to_proj_hrz(proj
, &robject
->coord
[1]);
365 } while (projection_is_visible0(proj
, robject
) &&
366 proj
->centre_ra
- pos_start
.ra
< GRID_HALF_MAX_FOV
);
367 pos_start
.ra
+= step_delta
;
369 /* binary chop start */
371 pos_start
.ra
-= step_delta
/ delta_div
;
372 proj
->trans
->sky_to_proj_hrz(proj
, &robject
->coord
[0]);
373 proj
->trans
->sky_to_proj_hrz(proj
, &robject
->coord
[1]);
374 if (!projection_is_visible0(proj
, robject
))
375 pos_start
.ra
+= step_delta
/ delta_div
;
377 } while (delta_div
< GRID_BISECT
);
379 /* find end position */
381 pos_end
.ra
+= step_delta
;
382 proj
->trans
->sky_to_proj_hrz(proj
, &robject
->coord
[0]);
383 proj
->trans
->sky_to_proj_hrz(proj
, &robject
->coord
[1]);
384 } while (projection_is_visible1(proj
, robject
) &&
385 pos_end
.ra
- proj
->centre_ra
< GRID_HALF_MAX_FOV
);
386 pos_end
.ra
-= step_delta
;
388 /* binary chop end */
391 pos_end
.ra
+= step_delta
/ delta_div
;
392 proj
->trans
->sky_to_proj_hrz(proj
, &robject
->coord
[0]);
393 proj
->trans
->sky_to_proj_hrz(proj
, &robject
->coord
[1]);
394 if (!projection_is_visible1(proj
, robject
))
395 pos_end
.ra
-= step_delta
/ delta_div
;
397 } while (delta_div
< GRID_BISECT
);
399 ln_deg_to_dms(dec
, &dms
);
404 if (dms
.minutes
== 0 && dms
.seconds
== 0.0)
405 sprintf(&text
[1], "%2.2dº", dms
.degrees
);
406 else if (dms
.seconds
< 0.1)
407 sprintf(&text
[1], "%2.2dº%2.2dm", dms
.degrees
, dms
.minutes
);
409 sprintf(&text
[1], "%2.2dº%2.2dm%2.0f", dms
.degrees
, dms
.minutes
,
412 cairo_move_to(robject
->cr
,
413 robject
->coord
[0].x
- 30.0,
414 robject
->coord
[0].y
- 1.0);
415 cairo_show_text(robject
->cr
, text
);
416 cairo_move_to(robject
->cr
,
417 robject
->coord
[1].x
+ 1.0,
418 robject
->coord
[1].y
- 1.0);
419 cairo_show_text(robject
->cr
, text
);
422 static void hrz_render_ra_labels_at(struct projection
*proj
,
423 struct render_object
*robject
, gdouble ra
)
426 gdouble step_delta
, delta_div
= 2.0;
427 struct ln_equ_posn pos_start
, pos_end
;
430 step_delta
= get_ra_step_delta(proj
);
432 pos_start
.dec
= proj
->centre_dec
;
433 pos_end
.dec
= proj
->centre_dec
;
434 pos_start
.ra
= pos_end
.ra
= ra
;
435 robject
->coord
[0].posn
= &pos_start
;
436 robject
->coord
[1].posn
= &pos_end
;
438 /* find start position */
440 pos_start
.dec
-= step_delta
;
441 proj
->trans
->sky_to_proj_hrz(proj
, &robject
->coord
[0]);
442 proj
->trans
->sky_to_proj_hrz(proj
, &robject
->coord
[1]);
443 } while (projection_is_visible0(proj
, robject
) &&
444 proj
->centre_dec
- pos_start
.dec
< GRID_HALF_MAX_FOV
);
445 pos_start
.dec
+= step_delta
;
447 /* binary chop start */
449 pos_start
.dec
-= step_delta
/ delta_div
;
450 proj
->trans
->sky_to_proj_hrz(proj
, &robject
->coord
[0]);
451 proj
->trans
->sky_to_proj_hrz(proj
, &robject
->coord
[1]);
452 if (!projection_is_visible0(proj
, robject
))
453 pos_start
.dec
+= step_delta
/ delta_div
;
455 } while (delta_div
< GRID_BISECT
);
457 /* find end position */
459 pos_end
.dec
+= step_delta
;
460 proj
->trans
->sky_to_proj_hrz(proj
, &robject
->coord
[0]);
461 proj
->trans
->sky_to_proj_hrz(proj
, &robject
->coord
[1]);
462 } while (projection_is_visible1(proj
, robject
) &&
463 pos_end
.dec
- proj
->centre_dec
< GRID_HALF_MAX_FOV
);
464 pos_end
.dec
-= step_delta
;
466 /* binary chop end */
469 pos_end
.dec
+= step_delta
/ delta_div
;
470 proj
->trans
->sky_to_proj_hrz(proj
, &robject
->coord
[0]);
471 proj
->trans
->sky_to_proj_hrz(proj
, &robject
->coord
[1]);
472 if (!projection_is_visible1(proj
, robject
))
473 pos_end
.dec
-= step_delta
/ delta_div
;
475 } while (delta_div
< GRID_BISECT
);
477 ln_deg_to_hms(ra
, &hms
);
478 if (hms
.minutes
== 0 && hms
.seconds
== 0.0)
479 sprintf(text
, "%2.2dh", hms
.hours
);
480 else if (hms
.seconds
< 0.1)
481 sprintf(text
, "%2.0dh%2.2dm", hms
.hours
, hms
.minutes
);
483 sprintf(text
, "%2.0dh%2.2dm%2.0f", hms
.hours
, hms
.minutes
,
486 cairo_move_to(robject
->cr
,
488 robject
->coord
[0].y
);
489 cairo_show_text(robject
->cr
, text
);
490 cairo_move_to(robject
->cr
,
492 robject
->coord
[1].y
+ 15.0); // font size
493 cairo_show_text(robject
->cr
, text
);
496 void equ_render_dec_labels(struct render_object
*robject
,
497 struct projection
*proj
, gdouble dec_start
, gdouble dec_end
)
499 gdouble step
, step_delta
;
500 struct ln_equ_posn pos1
;
502 pos1
.ra
= proj
->centre_az
;
504 step_delta
= get_dec_step_delta(proj
);
505 robject
->coord
[0].posn
= &pos1
;
507 for (step
= dec_start
; step
<= dec_end
; step
+= step_delta
) {
509 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[0]);
510 equ_render_dec_labels_at(proj
, robject
, step
);
514 void equ_render_ra_labels(struct render_object
*robject
,
515 struct projection
*proj
, gdouble ra_start
, gdouble ra_end
)
517 gdouble step
, step_delta
;
518 struct ln_equ_posn pos1
;
520 pos1
.dec
= proj
->centre_alt
;
522 step_delta
= get_ra_step_delta(proj
);
523 robject
->coord
[0].posn
= &pos1
;
525 for (step
= ra_start
; step
<= ra_end
; step
+= step_delta
) {
527 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[0]);
528 equ_render_ra_labels_at(proj
, robject
, step
);
532 void hrz_render_dec_labels(struct render_object
*robject
,
533 struct projection
*proj
, gdouble dec_start
, gdouble dec_end
)
535 gdouble step
, step_delta
;
536 struct ln_equ_posn pos1
;
538 pos1
.ra
= proj
->centre_ra
;
540 step_delta
= get_dec_step_delta(proj
);
541 robject
->coord
[0].posn
= &pos1
;
543 for (step
= dec_start
; step
<= dec_end
; step
+= step_delta
) {
545 proj
->trans
->sky_to_proj_hrz(proj
, &robject
->coord
[0]);
546 hrz_render_dec_labels_at(proj
, robject
, step
);
550 void hrz_render_ra_labels(struct render_object
*robject
,
551 struct projection
*proj
, gdouble ra_start
, gdouble ra_end
)
553 gdouble step
, step_delta
;
554 struct ln_equ_posn pos1
;
556 pos1
.dec
= proj
->centre_dec
;
558 step_delta
= get_ra_step_delta(proj
);
559 robject
->coord
[0].posn
= &pos1
;
561 for (step
= ra_start
; step
<= ra_end
; step
+= step_delta
) {
563 proj
->trans
->sky_to_proj_hrz(proj
, &robject
->coord
[0]);
564 hrz_render_ra_labels_at(proj
, robject
, step
);
568 static inline void equ_ra_line(struct render_object
*robject
,
569 struct projection
*proj
, struct ln_equ_posn
*pos
,
570 struct ln_equ_posn
*end
)
572 gdouble divs
= 5.0;//proj->pixels_per_degree
573 gdouble step
= (end
->dec
- pos
->dec
) / divs
;
576 for (pos
->dec
= pos
->dec
+ step
;
577 pos
->dec
<= end
->dec
; pos
->dec
+= step
) {
579 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[0]);
580 cairo_line_to(robject
->cr
,
581 robject
->coord
[0].x
, robject
->coord
[0].y
);
585 static inline void equ_dec_line(struct render_object
*robject
,
586 struct projection
*proj
, struct ln_equ_posn
*pos
,
587 struct ln_equ_posn
*end
)
589 gdouble divs
= 5.0;//proj->pixels_per_degree
590 gdouble step
= (end
->ra
- pos
->ra
) / divs
;
592 /* draw to DEC end */
593 for (pos
->ra
= pos
->ra
+ step
;
594 pos
->ra
<= end
->ra
; pos
->ra
+= step
) {
596 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[0]);
597 cairo_line_to(robject
->cr
,
598 robject
->coord
[0].x
, robject
->coord
[0].y
);
602 static inline void hrz_ra_line(struct render_object
*robject
,
603 struct projection
*proj
, struct ln_equ_posn
*pos
,
604 struct ln_equ_posn
*end
)
606 gdouble divs
= 5.0;//proj->pixels_per_degree
607 gdouble step
= (end
->dec
- pos
->dec
) / divs
;
610 for (pos
->dec
= pos
->dec
+ step
;
611 pos
->dec
<= end
->dec
; pos
->dec
+= step
) {
613 proj
->trans
->sky_to_proj_hrz(proj
, &robject
->coord
[0]);
614 cairo_line_to(robject
->cr
,
615 robject
->coord
[0].x
, robject
->coord
[0].y
);
619 static inline void hrz_dec_line(struct render_object
*robject
,
620 struct projection
*proj
, struct ln_equ_posn
*pos
,
621 struct ln_equ_posn
*end
)
623 gdouble divs
= 5.0;//proj->pixels_per_degree
624 gdouble step
= (end
->ra
- pos
->ra
) / divs
;
626 /* draw to DEC end */
627 for (pos
->ra
= pos
->ra
+ step
;
628 pos
->ra
<= end
->ra
; pos
->ra
+= step
) {
630 proj
->trans
->sky_to_proj_hrz(proj
, &robject
->coord
[0]);
631 cairo_line_to(robject
->cr
,
632 robject
->coord
[0].x
, robject
->coord
[0].y
);
636 static inline void equ_render_square(struct render_object
*robject
,
637 struct projection
*proj
, gint ra
, gint dec
)
639 gdouble ra_step_delta
, dec_step_delta
;
640 struct ln_equ_posn pos
, start_pos
, end_pos
;
642 ra_step_delta
= get_ra_step_delta(proj
);
643 dec_step_delta
= get_dec_step_delta(proj
);
644 robject
->coord
[0].posn
= &pos
;
647 start_pos
.ra
= pos
.ra
= ra
* GRID_RA_TILE_SIZE
;
648 start_pos
.dec
= pos
.dec
= PROJ_MIN_DEC
+ dec
* GRID_DEC_TILE_SIZE
;
651 end_pos
.ra
= start_pos
.ra
+ GRID_RA_TILE_SIZE
;
652 end_pos
.dec
= start_pos
.dec
+ GRID_DEC_TILE_SIZE
;
655 for (; pos
.ra
<= end_pos
.ra
; pos
.ra
+= ra_step_delta
) {
657 /* move to RA start */
658 pos
.dec
= start_pos
.dec
;
659 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[0]);
660 cairo_move_to(robject
->cr
,
661 robject
->coord
[0].x
, robject
->coord
[0].y
);
663 equ_ra_line(robject
, proj
, &pos
, &end_pos
);
667 for (pos
.dec
= start_pos
.dec
; pos
.dec
<= end_pos
.dec
;
668 pos
.dec
+= dec_step_delta
) {
670 /* move to DEC start */
671 pos
.ra
= start_pos
.ra
;
672 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[0]);
673 cairo_move_to(robject
->cr
,
674 robject
->coord
[0].x
, robject
->coord
[0].y
);
676 equ_dec_line(robject
, proj
, &pos
, &end_pos
);
680 static inline void hrz_render_square(struct render_object
*robject
,
681 struct projection
*proj
, gint ra
, gint dec
)
683 gdouble ra_step_delta
, dec_step_delta
;
684 struct ln_equ_posn pos
, start_pos
, end_pos
;
686 ra_step_delta
= get_ra_step_delta(proj
);
687 dec_step_delta
= get_dec_step_delta(proj
);
688 robject
->coord
[0].posn
= &pos
;
691 start_pos
.ra
= pos
.ra
= ra
* GRID_RA_TILE_SIZE
;
692 start_pos
.dec
= pos
.dec
= PROJ_MIN_DEC
+ dec
* GRID_DEC_TILE_SIZE
;
695 end_pos
.ra
= start_pos
.ra
+ GRID_RA_TILE_SIZE
;
696 end_pos
.dec
= start_pos
.dec
+ GRID_DEC_TILE_SIZE
;
699 for (; pos
.ra
<= end_pos
.ra
; pos
.ra
+= ra_step_delta
) {
701 /* move to RA start */
702 pos
.dec
= start_pos
.dec
;
703 proj
->trans
->sky_to_proj_hrz(proj
, &robject
->coord
[0]);
704 cairo_move_to(robject
->cr
,
705 robject
->coord
[0].x
, robject
->coord
[0].y
);
707 hrz_ra_line(robject
, proj
, &pos
, &end_pos
);
711 for (pos
.dec
= start_pos
.dec
; pos
.dec
<= end_pos
.dec
;
712 pos
.dec
+= dec_step_delta
) {
714 /* move to DEC start */
715 pos
.ra
= start_pos
.ra
;
716 proj
->trans
->sky_to_proj_hrz(proj
, &robject
->coord
[0]);
717 cairo_move_to(robject
->cr
,
718 robject
->coord
[0].x
, robject
->coord
[0].y
);
720 hrz_dec_line(robject
, proj
, &pos
, &end_pos
);
724 void equ_render_grid(struct render_object
*robject
, struct projection
*proj
,
729 /* render grid squares */
730 for (ra
= 0; ra
< GRID_RA_TILES
; ra
++) {
731 for (dec
= 1; dec
< GRID_DEC_TILES
- 1; dec
++)
732 if (proj
->grid_tile
[ra
][dec
])
733 equ_render_square(robject
, proj
, ra
, dec
);
739 /* render DEC labels */
740 for (dec
= 1; dec
< GRID_DEC_TILES
- 1; dec
++) {
741 for (ra
= 0; ra
< GRID_RA_TILES
; ra
++) {
742 if (proj
->grid_tile
[ra
][dec
]) {
743 gdouble dec_s
= (dec
- 9) * GRID_DEC_TILE_SIZE
,
744 dec_e
= dec_s
+ GRID_DEC_TILE_SIZE
;
749 equ_render_dec_labels(robject
, proj
, dec_s
, dec_e
);
755 /* render RA labels */
756 for (ra
= 0; ra
< GRID_RA_TILES
; ra
++) {
757 for (dec
= 1; dec
< GRID_DEC_TILES
- 1; dec
++)
758 if (proj
->grid_tile
[ra
][dec
]) {
759 gdouble ra_s
= ra
* GRID_RA_TILE_SIZE
,
760 ra_e
= ra_s
+ GRID_RA_TILE_SIZE
;
762 if (ra_e
>= PROJ_MAX_RA
)
765 equ_render_ra_labels(robject
, proj
, ra_s
, ra_e
);
771 void hrz_render_grid(struct render_object
*robject
, struct projection
*proj
,
776 /* render grid squares */
777 for (ra
= 0; ra
< GRID_RA_TILES
; ra
++) {
778 for (dec
= 1; dec
< GRID_DEC_TILES
- 1; dec
++)
779 if (proj
->grid_tile
[ra
][dec
])
780 hrz_render_square(robject
, proj
, ra
, dec
);
786 /* render DEC labels */
787 for (dec
= 1; dec
< GRID_DEC_TILES
- 1; dec
++) {
788 for (ra
= 0; ra
< GRID_RA_TILES
; ra
++) {
789 if (proj
->grid_tile
[ra
][dec
]) {
790 gdouble dec_s
= (dec
- 9) * GRID_DEC_TILE_SIZE
,
791 dec_e
= dec_s
+ GRID_DEC_TILE_SIZE
;
796 hrz_render_dec_labels(robject
, proj
, dec_s
, dec_e
);
802 /* render RA labels */
803 for (ra
= 0; ra
< GRID_RA_TILES
; ra
++) {
804 for (dec
= 1; dec
< GRID_DEC_TILES
- 1; dec
++)
805 if (proj
->grid_tile
[ra
][dec
]) {
806 gdouble ra_s
= ra
* GRID_RA_TILE_SIZE
,
807 ra_e
= ra_s
+ GRID_RA_TILE_SIZE
;
809 if (ra_e
>= PROJ_MAX_RA
)
812 hrz_render_ra_labels(robject
, proj
, ra_s
, ra_e
);
818 void render_ecliptic(struct render_object
*robject
, struct projection
*proj
)
823 struct ln_equ_posn pos1
;
824 int start_visible
, end_visible
;
828 robject
->coord
[0].posn
= &pos1
;
829 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[0]);
830 start_visible
= projection_is_visible0(proj
, robject
);
831 cairo_move_to(robject
->cr
,
833 robject
->coord
[0].y
);
835 for (step
= 10; step
<= PROJ_MAX_RA
; step
+= 10) {
837 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[0]);
838 end_visible
= projection_is_visible0(proj
, robject
);
839 if (start_visible
|| end_visible
)
840 cairo_line_to(robject
->cr
,
842 robject
->coord
[0].y
);
844 cairo_move_to(robject
->cr
,
846 robject
->coord
[0].y
);
847 start_visible
= end_visible
;
852 void render_horizon(struct render_object
*robject
, struct projection
*proj
)
855 struct ln_equ_posn pos1
;
856 int start_visible
, end_visible
;
858 cairo_save(robject
->cr
);
859 cairo_set_source_rgba(robject
->cr
, 1, 0.35, 0.55, 0.7);
863 robject
->coord
[0].posn
= &pos1
;
865 proj
->trans
->sky_to_proj_hrz(proj
, &robject
->coord
[0]);
866 start_visible
= projection_is_visible0(proj
, robject
);
867 cairo_move_to(robject
->cr
,
869 robject
->coord
[0].y
);
871 for (step
= 10; step
<= PROJ_MAX_RA
; step
+= 10) {
873 proj
->trans
->sky_to_proj_hrz(proj
, &robject
->coord
[0]);
874 end_visible
= projection_is_visible0(proj
, robject
);
875 if (start_visible
|| end_visible
)
876 cairo_line_to(robject
->cr
,
878 robject
->coord
[0].y
);
880 cairo_move_to(robject
->cr
,
882 robject
->coord
[0].y
);
883 start_visible
= end_visible
;
885 cairo_stroke(robject
->cr
);
886 cairo_restore(robject
->cr
);
889 void render_horizon_NEWS(struct render_object
*robject
, struct projection
*proj
)
891 struct ln_equ_posn pos1
;
893 cairo_save(robject
->cr
);
894 cairo_set_font_size (robject
->cr
, 20.0);
895 cairo_set_source_rgba(robject
->cr
, 1, 0.35, 0.55, 0.7);
896 robject
->coord
[0].posn
= &pos1
;
901 proj
->trans
->sky_to_proj_hrz(proj
, &robject
->coord
[0]);
902 cairo_move_to(robject
->cr
,
904 robject
->coord
[0].y
);
905 cairo_show_text(robject
->cr
, "S");
909 proj
->trans
->sky_to_proj_hrz(proj
, &robject
->coord
[0]);
910 cairo_move_to(robject
->cr
,
912 robject
->coord
[0].y
);
913 cairo_show_text(robject
->cr
, "W");
917 proj
->trans
->sky_to_proj_hrz(proj
, &robject
->coord
[0]);
918 cairo_move_to(robject
->cr
,
920 robject
->coord
[0].y
);
921 cairo_show_text(robject
->cr
, "N");
925 proj
->trans
->sky_to_proj_hrz(proj
, &robject
->coord
[0]);
926 cairo_move_to(robject
->cr
,
928 robject
->coord
[0].y
);
929 cairo_show_text(robject
->cr
, "E");
931 cairo_restore(robject
->cr
);
934 void grid_render(Sky
*sky
)
936 struct render_object
*robject
= &sky
->robject
;
937 struct projection
*proj
= &sky
->projection
;
938 gint labels
= sky
->marker_settings
.show_grid_labels
;
941 if (robject
->flags
.night_mode
)
942 alpha
= GRID_NIGHT_ALPHA
;
944 alpha
= GRID_DAY_ALPHA
;
946 cairo_save(robject
->cr
);
947 cairo_set_source_rgba(robject
->cr
, 0, 0.35, 0.55, alpha
);
948 cairo_set_font_size (robject
->cr
, 13.0);
950 if (robject
->type
== RT_FAST
) //TODO make step size * 2.0 when fast
951 cairo_set_tolerance (robject
->cr
, 1.0);
953 switch (proj
->grid_coords
) {
955 equ_get_visible_tiles(proj
);
956 equ_render_grid(robject
, proj
, labels
);
959 hrz_get_visible_tiles(proj
);
960 hrz_render_grid(robject
, proj
, labels
);
963 cairo_stroke(robject
->cr
);
965 render_horizon(robject
, proj
);
966 render_horizon_NEWS(robject
, proj
);
968 if (robject
->type
== RT_FAST
)
969 cairo_set_tolerance (robject
->cr
, 0.1); /* do we need this */
970 cairo_restore(robject
->cr
);