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
, gdouble divs
)
573 gdouble step
= (end
->dec
- pos
->dec
) / divs
;
576 for (pos
->dec
= pos
->dec
+ step
; i
> 0; pos
->dec
+= step
, i
--) {
578 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[0]);
579 cairo_line_to(robject
->cr
,
580 robject
->coord
[0].x
, robject
->coord
[0].y
);
584 static inline void equ_dec_line(struct render_object
*robject
,
585 struct projection
*proj
, struct ln_equ_posn
*pos
,
586 struct ln_equ_posn
*end
, gdouble divs
)
589 gdouble step
= (end
->ra
- pos
->ra
) / divs
;
591 /* draw to DEC end */
592 for (pos
->ra
= pos
->ra
+ step
; i
> 0; pos
->ra
+= step
, i
--) {
594 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[0]);
595 cairo_line_to(robject
->cr
,
596 robject
->coord
[0].x
, robject
->coord
[0].y
);
600 static inline void hrz_ra_line(struct render_object
*robject
,
601 struct projection
*proj
, struct ln_equ_posn
*pos
,
602 struct ln_equ_posn
*end
, gdouble divs
)
605 gdouble step
= (end
->dec
- pos
->dec
) / divs
;
608 for (pos
->dec
= pos
->dec
+ step
; i
> 0; pos
->dec
+= step
, i
--) {
610 proj
->trans
->sky_to_proj_hrz(proj
, &robject
->coord
[0]);
611 cairo_line_to(robject
->cr
,
612 robject
->coord
[0].x
, robject
->coord
[0].y
);
616 static inline void hrz_dec_line(struct render_object
*robject
,
617 struct projection
*proj
, struct ln_equ_posn
*pos
,
618 struct ln_equ_posn
*end
, gdouble divs
)
621 gdouble step
= (end
->ra
- pos
->ra
) / divs
;
623 /* draw to DEC end */
624 for (pos
->ra
= pos
->ra
+ step
; i
> 0; pos
->ra
+= step
, i
--) {
626 proj
->trans
->sky_to_proj_hrz(proj
, &robject
->coord
[0]);
627 cairo_line_to(robject
->cr
,
628 robject
->coord
[0].x
, robject
->coord
[0].y
);
632 static inline void equ_render_square(struct render_object
*robject
,
633 struct projection
*proj
, gint ra
, gint dec
, gdouble divs
)
635 gdouble ra_step_delta
, dec_step_delta
;
636 struct ln_equ_posn pos
, start_pos
, end_pos
;
638 ra_step_delta
= get_ra_step_delta(proj
);
639 dec_step_delta
= get_dec_step_delta(proj
);
640 robject
->coord
[0].posn
= &pos
;
643 start_pos
.ra
= pos
.ra
= ra
* GRID_RA_TILE_SIZE
;
644 start_pos
.dec
= pos
.dec
= PROJ_MIN_DEC
+ dec
* GRID_DEC_TILE_SIZE
;
647 end_pos
.ra
= start_pos
.ra
+ GRID_RA_TILE_SIZE
;
648 end_pos
.dec
= start_pos
.dec
+ GRID_DEC_TILE_SIZE
;
651 for (; pos
.ra
<= end_pos
.ra
; pos
.ra
+= ra_step_delta
) {
653 /* move to RA start */
654 pos
.dec
= start_pos
.dec
;
655 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[0]);
656 cairo_move_to(robject
->cr
,
657 robject
->coord
[0].x
, robject
->coord
[0].y
);
659 equ_ra_line(robject
, proj
, &pos
, &end_pos
, divs
);
663 for (pos
.dec
= start_pos
.dec
; pos
.dec
<= end_pos
.dec
;
664 pos
.dec
+= dec_step_delta
) {
666 /* move to DEC start */
667 pos
.ra
= start_pos
.ra
;
668 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[0]);
669 cairo_move_to(robject
->cr
,
670 robject
->coord
[0].x
, robject
->coord
[0].y
);
672 equ_dec_line(robject
, proj
, &pos
, &end_pos
, divs
);
676 static inline void hrz_render_square(struct render_object
*robject
,
677 struct projection
*proj
, gint ra
, gint dec
, gdouble divs
)
679 gdouble ra_step_delta
, dec_step_delta
;
680 struct ln_equ_posn pos
, start_pos
, end_pos
;
682 ra_step_delta
= get_ra_step_delta(proj
);
683 dec_step_delta
= get_dec_step_delta(proj
);
684 robject
->coord
[0].posn
= &pos
;
687 start_pos
.ra
= pos
.ra
= ra
* GRID_RA_TILE_SIZE
;
688 start_pos
.dec
= pos
.dec
= PROJ_MIN_DEC
+ dec
* GRID_DEC_TILE_SIZE
;
691 end_pos
.ra
= start_pos
.ra
+ GRID_RA_TILE_SIZE
;
692 end_pos
.dec
= start_pos
.dec
+ GRID_DEC_TILE_SIZE
;
695 for (; pos
.ra
<= end_pos
.ra
; pos
.ra
+= ra_step_delta
) {
697 /* move to RA start */
698 pos
.dec
= start_pos
.dec
;
699 proj
->trans
->sky_to_proj_hrz(proj
, &robject
->coord
[0]);
700 cairo_move_to(robject
->cr
,
701 robject
->coord
[0].x
, robject
->coord
[0].y
);
703 hrz_ra_line(robject
, proj
, &pos
, &end_pos
, divs
);
707 for (pos
.dec
= start_pos
.dec
; pos
.dec
<= end_pos
.dec
;
708 pos
.dec
+= dec_step_delta
) {
710 /* move to DEC start */
711 pos
.ra
= start_pos
.ra
;
712 proj
->trans
->sky_to_proj_hrz(proj
, &robject
->coord
[0]);
713 cairo_move_to(robject
->cr
,
714 robject
->coord
[0].x
, robject
->coord
[0].y
);
716 hrz_dec_line(robject
, proj
, &pos
, &end_pos
, divs
);
720 void equ_render_grid(struct render_object
*robject
, struct projection
*proj
,
721 gint labels
, gdouble divs
)
725 /* render grid squares */
726 for (ra
= 0; ra
< GRID_RA_TILES
; ra
++) {
727 for (dec
= 1; dec
< GRID_DEC_TILES
- 1; dec
++)
728 if (proj
->grid_tile
[ra
][dec
])
729 equ_render_square(robject
, proj
, ra
, dec
, divs
);
735 /* render DEC labels */
736 for (dec
= 1; dec
< GRID_DEC_TILES
- 1; dec
++) {
737 for (ra
= 0; ra
< GRID_RA_TILES
; ra
++) {
738 if (proj
->grid_tile
[ra
][dec
]) {
739 gdouble dec_s
= (dec
- 9) * GRID_DEC_TILE_SIZE
,
740 dec_e
= dec_s
+ GRID_DEC_TILE_SIZE
;
745 equ_render_dec_labels(robject
, proj
, dec_s
, dec_e
);
751 /* render RA labels */
752 for (ra
= 0; ra
< GRID_RA_TILES
; ra
++) {
753 for (dec
= 1; dec
< GRID_DEC_TILES
- 1; dec
++)
754 if (proj
->grid_tile
[ra
][dec
]) {
755 gdouble ra_s
= ra
* GRID_RA_TILE_SIZE
,
756 ra_e
= ra_s
+ GRID_RA_TILE_SIZE
;
758 if (ra_e
>= PROJ_MAX_RA
)
761 equ_render_ra_labels(robject
, proj
, ra_s
, ra_e
);
767 void hrz_render_grid(struct render_object
*robject
, struct projection
*proj
,
768 gint labels
, gdouble divs
)
772 /* render grid squares */
773 for (ra
= 0; ra
< GRID_RA_TILES
; ra
++) {
774 for (dec
= 1; dec
< GRID_DEC_TILES
- 1; dec
++)
775 if (proj
->grid_tile
[ra
][dec
])
776 hrz_render_square(robject
, proj
, ra
, dec
, divs
);
782 /* render DEC labels */
783 for (dec
= 1; dec
< GRID_DEC_TILES
- 1; dec
++) {
784 for (ra
= 0; ra
< GRID_RA_TILES
; ra
++) {
785 if (proj
->grid_tile
[ra
][dec
]) {
786 gdouble dec_s
= (dec
- 9) * GRID_DEC_TILE_SIZE
,
787 dec_e
= dec_s
+ GRID_DEC_TILE_SIZE
;
792 hrz_render_dec_labels(robject
, proj
, dec_s
, dec_e
);
798 /* render RA labels */
799 for (ra
= 0; ra
< GRID_RA_TILES
; ra
++) {
800 for (dec
= 1; dec
< GRID_DEC_TILES
- 1; dec
++)
801 if (proj
->grid_tile
[ra
][dec
]) {
802 gdouble ra_s
= ra
* GRID_RA_TILE_SIZE
,
803 ra_e
= ra_s
+ GRID_RA_TILE_SIZE
;
805 if (ra_e
>= PROJ_MAX_RA
)
808 hrz_render_ra_labels(robject
, proj
, ra_s
, ra_e
);
814 static inline void render_ecliptic(struct render_object
*robject
,
815 struct projection
*proj
)
820 struct ln_equ_posn pos1
;
821 int start_visible
, end_visible
;
825 robject
->coord
[0].posn
= &pos1
;
826 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[0]);
827 start_visible
= projection_is_visible0(proj
, robject
);
828 cairo_move_to(robject
->cr
,
830 robject
->coord
[0].y
);
832 for (step
= 10; step
<= PROJ_MAX_RA
; step
+= 10) {
834 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[0]);
835 end_visible
= projection_is_visible0(proj
, robject
);
836 if (start_visible
|| end_visible
)
837 cairo_line_to(robject
->cr
,
839 robject
->coord
[0].y
);
841 cairo_move_to(robject
->cr
,
843 robject
->coord
[0].y
);
844 start_visible
= end_visible
;
849 static inline void render_horizon(struct render_object
*robject
,
850 struct projection
*proj
)
853 struct ln_equ_posn pos1
;
854 int start_visible
, end_visible
;
855 double dashes
[] = {3.0, 1.0, 3.0, 1.0};
857 cairo_save(robject
->cr
);
858 cairo_set_source_rgba(robject
->cr
, 0.6, 0.6, 0.6, 0.7);
859 cairo_set_dash (robject
->cr
, dashes
, 4, 0);
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 if (robject
->type
== RT_FAST
) {
872 cairo_set_tolerance(robject
->cr
, 1.0);
875 cairo_set_tolerance(robject
->cr
, 0.1);
879 for (step
= 10; step
<= PROJ_MAX_RA
; step
+= size
) {
881 proj
->trans
->sky_to_proj_hrz(proj
, &robject
->coord
[0]);
882 end_visible
= projection_is_visible0(proj
, robject
);
883 if (start_visible
|| end_visible
)
884 cairo_line_to(robject
->cr
,
886 robject
->coord
[0].y
);
888 cairo_move_to(robject
->cr
,
890 robject
->coord
[0].y
);
891 start_visible
= end_visible
;
893 cairo_stroke(robject
->cr
);
895 if (robject
->type
== RT_FAST
)
896 cairo_set_tolerance(robject
->cr
, 0.1); /* do we need this */
897 cairo_restore(robject
->cr
);
900 static inline void render_horizon_NEWS(struct render_object
*robject
,
901 struct projection
*proj
)
903 struct ln_equ_posn pos1
;
905 cairo_save(robject
->cr
);
906 cairo_set_font_size (robject
->cr
, 20.0);
907 cairo_set_source_rgba(robject
->cr
, 1, 0.35, 0.55, 0.7);
908 robject
->coord
[0].posn
= &pos1
;
913 proj
->trans
->sky_to_proj_hrz(proj
, &robject
->coord
[0]);
914 cairo_move_to(robject
->cr
,
916 robject
->coord
[0].y
);
917 cairo_show_text(robject
->cr
, "S");
921 proj
->trans
->sky_to_proj_hrz(proj
, &robject
->coord
[0]);
922 cairo_move_to(robject
->cr
,
924 robject
->coord
[0].y
);
925 cairo_show_text(robject
->cr
, "W");
929 proj
->trans
->sky_to_proj_hrz(proj
, &robject
->coord
[0]);
930 cairo_move_to(robject
->cr
,
932 robject
->coord
[0].y
);
933 cairo_show_text(robject
->cr
, "N");
937 proj
->trans
->sky_to_proj_hrz(proj
, &robject
->coord
[0]);
938 cairo_move_to(robject
->cr
,
940 robject
->coord
[0].y
);
941 cairo_show_text(robject
->cr
, "E");
943 cairo_restore(robject
->cr
);
946 void markers_grid_render(Sky
*sky
)
948 struct render_object
*robject
= &sky
->robject
;
949 struct projection
*proj
= &sky
->projection
;
950 gint labels
= sky
->marker_settings
.show_grid_labels
;
953 if (robject
->flags
.night_mode
)
954 alpha
= GRID_NIGHT_ALPHA
;
956 alpha
= GRID_DAY_ALPHA
;
958 cairo_save(robject
->cr
);
959 cairo_set_source_rgba(robject
->cr
, 0, 0.35, 0.55, alpha
);
960 cairo_set_font_size (robject
->cr
, 13.0);
962 if (robject
->type
== RT_FAST
) {
963 cairo_set_tolerance(robject
->cr
, 1.0);
966 cairo_set_tolerance(robject
->cr
, 0.1);
970 switch (proj
->grid_coords
) {
972 equ_get_visible_tiles(proj
);
973 equ_render_grid(robject
, proj
, labels
, divs
);
976 hrz_get_visible_tiles(proj
);
977 hrz_render_grid(robject
, proj
, labels
, divs
);
980 cairo_stroke(robject
->cr
);
982 if (robject
->type
== RT_FAST
)
983 cairo_set_tolerance(robject
->cr
, 0.1); /* do we need this */
984 cairo_restore(robject
->cr
);
987 void markers_horizon_render(Sky
*sky
)
989 struct render_object
*robject
= &sky
->robject
;
990 struct projection
*proj
= &sky
->projection
;
992 render_horizon(robject
, proj
);
995 void markers_horizon_NEWS_render(Sky
*sky
)
997 struct render_object
*robject
= &sky
->robject
;
998 struct projection
*proj
= &sky
->projection
;
1000 render_horizon_NEWS(robject
, proj
);
1003 void markers_ecliptic_render(Sky
*sky
)
1005 struct render_object
*robject
= &sky
->robject
;
1006 struct projection
*proj
= &sky
->projection
;
1008 render_ecliptic(robject
, proj
);
1011 void markers_galactic_poles_render(Sky
*sky
)