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).
22 * TODO: Clip RA grid lines at 80 and -80 on DEC. This needs cairo_arc_to() or
23 * someone who knows another solution.
26 #define _GNU_SOURCE /* for NAN and INF */
30 #include "astro_object.h"
34 #define D2R (1.7453292519943295769e-2) /* deg->radian */
35 #define R2D (5.7295779513082320877e1) /* radian->deg */
37 #define ARC_MAGIC 1000.0 /* need better method to determine line from arc */
38 #define GRID_BISECT 128.0
39 #define GRID_NIGHT_ALPHA 0.35
40 #define GRID_DAY_ALPHA 0.55
43 /* RA grid in arcsecs */
44 static const gdouble grid_hms_ra
[] = {
56 /* DEC drid in arcsecs */
57 static const gdouble grid_dms_dec
[] = {
70 /* get grid RA step size for projection in arcsecs */
71 static gdouble
get_ra_step_delta(struct projection
*proj
)
75 for (i
= 0; i
< nsize(grid_hms_ra
); i
++) {
76 if (proj
->fov
/ 1.1 > grid_hms_ra
[i
] / 3600.0)
77 return grid_hms_ra
[i
] / 3600.0;
79 return grid_hms_ra
[i
] / 3600.0;
82 /* get grid DEC step size for projection in arcsecs */
83 static gdouble
get_dec_step_delta(struct projection
*proj
)
87 for (i
= 0; i
< nsize(grid_dms_dec
); i
++) {
88 if (proj
->fov
/ 1.1 > grid_dms_dec
[i
] / 3600.0)
89 return grid_dms_dec
[i
] / 3600.0;
91 return grid_dms_dec
[i
] / 3600.0;
94 /* clip DEC grid to current projection FOV */
95 static void clip_dec_equ_grid(struct projection
*proj
, gdouble step_size
,
96 gdouble
*south
, gdouble
*north
)
98 *south
= proj
->centre_dec
- proj
->fov
/ 2.0;
100 *south
= -90.0 + step_size
;
102 *south
= floor(*south
/ step_size
) * step_size
;
104 *north
= proj
->centre_dec
+ proj
->fov
/ 2.0;
106 *north
= 90.0 - step_size
;
108 *north
= floor(*north
/ step_size
) * step_size
;
111 /* clip RA grid to current projection FOV */
112 static void clip_ra_equ_grid(struct projection
*proj
, gdouble step_size
,
113 gdouble
*start
, gdouble
*end
)
115 struct render_object robject
;
116 struct ln_equ_posn pos
[4];
117 gdouble start_
, end_
;
120 /* get RA at each projection corner */
121 robject
.coord
[0].x
= 0;
122 robject
.coord
[0].y
= 0;
123 robject
.coord
[0].posn
= &pos
[0];
124 proj
->trans
->proj_to_sky_hrz(proj
, &robject
.coord
[0]);
127 else if (pos
[0].ra
>= 360.0)
130 robject
.coord
[0].x
= proj
->sky_width
;
131 robject
.coord
[0].y
= 0;
132 robject
.coord
[0].posn
= &pos
[1];
133 proj
->trans
->proj_to_sky_hrz(proj
, &robject
.coord
[0]);
136 else if (pos
[1].ra
>= 360.0)
139 robject
.coord
[0].x
= 0;
140 robject
.coord
[0].y
= proj
->sky_height
;
141 robject
.coord
[0].posn
= &pos
[2];
142 proj
->trans
->proj_to_sky_hrz(proj
, &robject
.coord
[0]);
145 else if (pos
[2].ra
>= 360.0)
148 robject
.coord
[0].x
= proj
->sky_width
;
149 robject
.coord
[0].y
= proj
->sky_height
;
150 robject
.coord
[0].posn
= &pos
[3];
151 proj
->trans
->proj_to_sky_hrz(proj
, &robject
.coord
[0]);
154 else if (pos
[3].ra
>= 360.0)
157 /* get highest and lowest RA from corners */
160 for (i
= 0; i
< 4; i
++) {
161 printf("pos %d ra %3.2f dec %3.2f\n",i
, pos
[i
].ra
, pos
[i
].dec
);
162 if (start_
> pos
[i
].ra
)
164 if (end_
< pos
[i
].ra
)
168 start_
= floor(start_
/ step_size
) * step_size
;
171 else if (start_
>= 360.0)
174 end_
= ceil(end_
/ step_size
) * step_size
;
177 else if (end_
>= 360.0)
188 printf("start %3.2f end %3.2f\n", *start
, *end
);
191 /* should we render a line of this radius as an arc or a straight line */
192 static inline gint
is_arc_line(struct projection
*proj
, gdouble radius
)
194 /* magic number - must refine */
195 if (radius
> proj
->sky_width
* ARC_MAGIC
||
196 radius
< proj
->sky_width
* -ARC_MAGIC
) {
197 //printf("%s rad %f\n", __func__, radius);
203 /* is this arc visible in projection */
204 static gint
is_arc_visible(struct projection
*proj
, gdouble x
, gdouble y
,
207 gdouble x1
, y1
, x2
, y2
;
211 || radius
== FP_INFINITE
212 || radius
== -FP_INFINITE
) {
216 /* create clip area sky size + radius */
219 x2
= proj
->sky_width
+ radius
;
220 y2
= proj
->sky_height
+ radius
;
222 /* are we inside ? */
223 if (x
>= x1
&& x
<= x2
&& y
>= y1
&& y
<= y2
)
229 static inline void do_ra_line(struct render_object
*robject
,
230 struct projection
*proj
, gdouble x
, gdouble y
, gdouble my
)
232 gdouble x1
, y1
, x2
, y2
;
236 x2
= my
* (proj
->sky_height
- y
) + x
;
237 y2
= proj
->sky_height
;
239 cairo_move_to(robject
->cr
, x1
, y1
);
240 cairo_line_to(robject
->cr
, x2
, y2
);
243 /* draw a straight RA grid line */
244 static inline void draw_ra_line(struct render_object
*robject
,
245 struct projection
*proj
, gdouble step
)
247 struct ln_equ_posn pos1
, pos2
;
250 /* calc based on small RA line */
251 pos1
.dec
= proj
->centre_dec
+ 1.0;
252 pos2
.dec
= proj
->centre_dec
-1.0;
255 pos2
.ra
= step
+ 180.0;
257 robject
->coord
[0].posn
= &pos1
;
258 robject
->coord
[1].posn
= &pos2
;
260 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[0]);
261 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[1]);
263 /* calculate line gradient */
264 my
= (robject
->coord
[1].x
- robject
->coord
[0].x
) /
265 (robject
->coord
[1].y
- robject
->coord
[0].y
);
267 do_ra_line(robject
, proj
,
268 robject
->coord
[0].x
, robject
->coord
[0].y
, my
);
271 static inline void do_dec_line(struct render_object
*robject
,
272 struct projection
*proj
, gdouble x
, gdouble y
, gdouble mx
)
274 gdouble x1
, y1
, x2
, y2
;
278 x2
= proj
->sky_width
;
279 y2
= mx
* (proj
->sky_width
- x
) + y
;
281 cairo_move_to(robject
->cr
, x1
, y1
);
282 cairo_line_to(robject
->cr
, x2
, y2
);
285 /* draw a straight DEC grid line */
286 static inline void draw_dec_line(struct render_object
*robject
,
287 struct projection
*proj
, gdouble step
)
289 struct ln_equ_posn pos1
, pos2
;
292 /* calc based on small DEC line */
293 pos1
.ra
= proj
->centre_ra
+ 1.0;
294 pos2
.ra
= proj
->centre_ra
-1.0;
299 robject
->coord
[0].posn
= &pos1
;
300 robject
->coord
[1].posn
= &pos2
;
302 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[0]);
303 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[1]);
305 /* calculate line gradient */
306 mx
= (robject
->coord
[1].y
- robject
->coord
[0].y
) /
307 (robject
->coord
[1].x
- robject
->coord
[0].x
);
309 do_dec_line(robject
, proj
,
310 robject
->coord
[0].x
, robject
->coord
[0].y
, mx
);
314 /* render all visible RA grid lines */
315 static void equ_render_ra(struct render_object
*robject
,
316 struct projection
*proj
, gint labels
)
318 gdouble centre_x
, centre_y
, radius
, x
, y
, step
,
319 step_delta
, ra_start
, ra_end
;
320 struct ln_equ_posn pos1
, pos2
;
322 pos1
.dec
= -proj
->centre_dec
;
323 pos2
.dec
= -proj
->centre_dec
;
325 step_delta
= get_ra_step_delta(proj
);
326 clip_ra_equ_grid(proj
, step_delta
, &ra_start
, &ra_end
);
328 for (step
= ra_start
; step
<= ra_end
; step
+= step_delta
) {
331 pos2
.ra
= step
+ 180.0;
333 robject
->coord
[0].posn
= &pos1
;
334 robject
->coord
[1].posn
= &pos2
;
336 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[0]);
337 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[1]);
339 centre_x
= robject
->coord
[0].x
+
340 ((robject
->coord
[1].x
- robject
->coord
[0].x
) / 2.0);
341 centre_y
= robject
->coord
[0].y
+
342 ((robject
->coord
[1].y
- robject
->coord
[0].y
) / 2.0);
343 x
= centre_x
- robject
->coord
[0].x
;
344 y
= centre_y
- robject
->coord
[0].y
;
345 radius
= sqrt(x
* x
+ y
* y
);
347 if (!is_arc_visible(proj
, centre_x
, centre_y
, radius
) &&
348 step
!= proj
->centre_ra
)
351 /* need cairo_arc_to() */
353 if (step
== 0.0 || step
== 90.0 ||
354 step
== 180.0 || step
== 270.0) {
355 struct ln_equ_posn pos1
, pos2
;
361 robject
->num_coords
= 2;
363 robject
->coord
[0].posn
= &pos1
;
364 robject
->coord
[1].posn
= &pos2
;
365 proj
->trans
->sky_to_proj_equ(proj
, robject
);
367 cairo_new_sub_path(robject
->cr
);
368 cairo_arc_to(robject
->cr
,
369 robject
->coord
[0].x
, robject
->coord
[0].y
,
370 robject
->coord
[1].x
, robject
->coord
[1].y
,
373 if (is_arc_line(proj
, centre_x
))
374 draw_ra_line(robject
, proj
, step
);
376 cairo_new_sub_path(robject
->cr
);
377 cairo_arc(robject
->cr
, centre_x
, centre_y
,
378 radius
, circle_start
, circle_end
);
382 if (is_arc_line(proj
, centre_x
))
383 draw_ra_line(robject
, proj
, step
);
385 cairo_new_sub_path(robject
->cr
);
386 cairo_arc(robject
->cr
, centre_x
, centre_y
,
387 radius
, 0, 2 * M_PI
);
395 /* render all visible DEC grid lines */
396 static void equ_render_dec(struct render_object
*robject
,
397 struct projection
*proj
, gint labels
)
399 gdouble centre_x
, centre_y
, radius
, x
, y
, step
,
400 step_delta
, dec_start
, dec_end
;
401 struct ln_equ_posn pos1
, pos2
;
403 pos1
.ra
= proj
->centre_ra
;
404 pos2
.ra
= proj
->centre_ra
+ 180.0;
406 step_delta
= get_dec_step_delta(proj
);
407 clip_dec_equ_grid(proj
, step_delta
, &dec_start
, &dec_end
);
409 for (step
= dec_start
; step
<= dec_end
; step
+= step_delta
) {
414 robject
->coord
[0].posn
= &pos1
;
415 robject
->coord
[1].posn
= &pos2
;
417 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[0]);
418 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[1]);
420 centre_x
= robject
->coord
[0].x
+
421 ((robject
->coord
[1].x
- robject
->coord
[0].x
) / 2.0);
422 centre_y
= robject
->coord
[0].y
+
423 ((robject
->coord
[1].y
- robject
->coord
[0].y
) / 2.0);
424 x
= centre_x
- robject
->coord
[0].x
;
425 y
= centre_y
- robject
->coord
[0].y
;
426 radius
= sqrt(x
* x
+ y
* y
);
428 if (!is_arc_visible(proj
, centre_x
, centre_y
, radius
) &&
429 step
!= proj
->centre_dec
)
432 cairo_new_sub_path(robject
->cr
);
434 if (is_arc_line(proj
, centre_x
))
435 draw_dec_line(robject
, proj
, step
);
437 cairo_arc(robject
->cr
, centre_x
, centre_y
,
438 radius
, 0, 2 * M_PI
);
443 /* render all visible RA grid lines */
444 static void hrz_render_ra(struct render_object
*robject
,
445 struct projection
*proj
, gint labels
)
447 gdouble centre_x
, centre_y
, radius
, x
, y
, step
,
448 step_delta
, ra_start
, ra_end
;
449 struct ln_equ_posn pos1
, pos2
;
451 pos1
.dec
= -proj
->centre_dec
;
452 pos2
.dec
= -proj
->centre_dec
;
454 step_delta
= get_ra_step_delta(proj
);
455 clip_ra_equ_grid(proj
, step_delta
, &ra_start
, &ra_end
);
457 for (step
= ra_start
; step
<= ra_end
; step
+= step_delta
) {
460 pos2
.ra
= step
+ 180.0;
462 robject
->coord
[0].posn
= &pos1
;
463 robject
->coord
[1].posn
= &pos2
;
465 proj
->trans
->sky_to_proj_hrz(proj
, &robject
->coord
[0]);
466 proj
->trans
->sky_to_proj_hrz(proj
, &robject
->coord
[1]);
468 centre_x
= robject
->coord
[0].x
+
469 ((robject
->coord
[1].x
- robject
->coord
[0].x
) / 2.0);
470 centre_y
= robject
->coord
[0].y
+
471 ((robject
->coord
[1].y
- robject
->coord
[0].y
) / 2.0);
472 x
= centre_x
- robject
->coord
[0].x
;
473 y
= centre_y
- robject
->coord
[0].y
;
474 radius
= sqrt(x
* x
+ y
* y
);
476 if (!is_arc_visible(proj
, centre_x
, centre_y
, radius
) &&
477 step
!= proj
->centre_ra
)
480 /* need cairo_arc_to() */
482 if (step
== 0.0 || step
== 90.0 ||
483 step
== 180.0 || step
== 270.0) {
484 struct ln_equ_posn pos1
, pos2
;
490 robject
->num_coords
= 2;
492 robject
->coord
[0].posn
= &pos1
;
493 robject
->coord
[1].posn
= &pos2
;
494 proj
->trans
->sky_to_proj_hrz(proj
, robject
);
496 cairo_new_sub_path(robject
->cr
);
497 cairo_arc_to(robject
->cr
,
498 robject
->coord
[0].x
, robject
->coord
[0].y
,
499 robject
->coord
[1].x
, robject
->coord
[1].y
,
502 if (is_arc_line(proj
, centre_x
))
503 draw_ra_line(robject
, proj
, step
);
505 cairo_new_sub_path(robject
->cr
);
506 cairo_arc(robject
->cr
, centre_x
, centre_y
,
507 radius
, circle_start
, circle_end
);
511 if (is_arc_line(proj
, centre_x
))
512 draw_ra_line(robject
, proj
, step
);
514 cairo_new_sub_path(robject
->cr
);
515 cairo_arc(robject
->cr
, centre_x
, centre_y
,
516 radius
, 0, 2 * M_PI
);
522 /* render all visible DEC grid lines */
523 static void hrz_render_dec(struct render_object
*robject
,
524 struct projection
*proj
, gint labels
)
526 gdouble centre_x
, centre_y
, radius
, x
, y
, step
,
527 step_delta
, dec_start
, dec_end
;
528 struct ln_equ_posn pos1
, pos2
;
530 pos1
.ra
= proj
->centre_ra
;
531 pos2
.ra
= proj
->centre_ra
+ 180.0;
533 step_delta
= get_dec_step_delta(proj
);
534 clip_dec_equ_grid(proj
, step_delta
, &dec_start
, &dec_end
);
536 for (step
= dec_start
; step
<= dec_end
; step
+= step_delta
) {
541 robject
->coord
[0].posn
= &pos1
;
542 robject
->coord
[1].posn
= &pos2
;
544 proj
->trans
->sky_to_proj_hrz(proj
, &robject
->coord
[0]);
545 proj
->trans
->sky_to_proj_hrz(proj
, &robject
->coord
[1]);
547 centre_x
= robject
->coord
[0].x
+
548 ((robject
->coord
[1].x
- robject
->coord
[0].x
) / 2.0);
549 centre_y
= robject
->coord
[0].y
+
550 ((robject
->coord
[1].y
- robject
->coord
[0].y
) / 2.0);
551 x
= centre_x
- robject
->coord
[0].x
;
552 y
= centre_y
- robject
->coord
[0].y
;
553 radius
= sqrt(x
* x
+ y
* y
);
555 if (!is_arc_visible(proj
, centre_x
, centre_y
, radius
) &&
556 step
!= proj
->centre_dec
)
559 cairo_new_sub_path(robject
->cr
);
561 if (is_arc_line(proj
, centre_x
))
562 draw_dec_line(robject
, proj
, step
);
564 cairo_arc(robject
->cr
, centre_x
, centre_y
,
565 radius
, 0, 2 * M_PI
);
569 static void render_dec_labels_at(struct projection
*proj
,
570 struct render_object
*robject
, gdouble dec
)
573 gdouble step_delta
, delta_div
= 2.0;
574 struct ln_equ_posn pos_start
, pos_end
;
577 step_delta
= get_dec_step_delta(proj
);
579 pos_start
.ra
= proj
->centre_ra
;
580 pos_end
.ra
= proj
->centre_ra
;
581 pos_start
.dec
= pos_end
.dec
= dec
;
582 robject
->coord
[0].posn
= &pos_start
;
583 robject
->coord
[1].posn
= &pos_end
;
585 /* find start position */
587 pos_start
.ra
-= step_delta
;
588 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[0]);
589 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[1]);
590 } while (projection_is_visible0(proj
, robject
) &&
591 proj
->centre_ra
- pos_start
.ra
< 90.0);
592 pos_start
.ra
+= step_delta
;
594 /* binary chop start */
596 pos_start
.ra
-= step_delta
/ delta_div
;
597 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[0]);
598 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[1]);
599 if (!projection_is_visible0(proj
, robject
))
600 pos_start
.ra
+= step_delta
/ delta_div
;
602 } while (delta_div
< GRID_BISECT
);
604 /* find end position */
606 pos_end
.ra
+= step_delta
;
607 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[0]);
608 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[1]);
609 } while (projection_is_visible1(proj
, robject
) &&
610 pos_end
.ra
- proj
->centre_ra
< 90.0);
611 pos_end
.ra
-= step_delta
;
613 /* binary chop end */
616 pos_end
.ra
+= step_delta
/ delta_div
;
617 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[0]);
618 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[1]);
619 if (!projection_is_visible1(proj
, robject
))
620 pos_end
.ra
-= step_delta
/ delta_div
;
622 } while (delta_div
< GRID_BISECT
);
624 ln_deg_to_dms(dec
, &dms
);
629 if (dms
.minutes
== 0 && dms
.seconds
== 0.0)
630 sprintf(&text
[1], "%2.2dº", dms
.degrees
);
631 else if (dms
.seconds
< 0.1)
632 sprintf(&text
[1], "%2.2dº%2.2dm", dms
.degrees
, dms
.minutes
);
634 sprintf(&text
[1], "%2.2dº%2.2dm%2.0f", dms
.degrees
, dms
.minutes
,
637 cairo_move_to(robject
->cr
,
638 robject
->coord
[0].x
- 30.0,
639 robject
->coord
[0].y
- 1.0);
640 cairo_show_text(robject
->cr
, text
);
641 cairo_move_to(robject
->cr
,
642 robject
->coord
[1].x
+ 1.0,
643 robject
->coord
[1].y
- 1.0);
644 cairo_show_text(robject
->cr
, text
);
647 static void render_ra_labels_at(struct projection
*proj
,
648 struct render_object
*robject
, gdouble ra
)
651 gdouble step_delta
, delta_div
= 2.0;
652 struct ln_equ_posn pos_start
, pos_end
;
655 step_delta
= get_ra_step_delta(proj
);
657 pos_start
.dec
= proj
->centre_dec
;
658 pos_end
.dec
= proj
->centre_dec
;
659 pos_start
.ra
= pos_end
.ra
= ra
;
660 robject
->coord
[0].posn
= &pos_start
;
661 robject
->coord
[1].posn
= &pos_end
;
663 /* find start position */
665 pos_start
.dec
-= step_delta
;
666 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[0]);
667 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[1]);
668 } while (projection_is_visible0(proj
, robject
) &&
669 proj
->centre_dec
- pos_start
.dec
< 90.0);
670 pos_start
.dec
+= step_delta
;
672 /* binary chop start */
674 pos_start
.dec
-= step_delta
/ delta_div
;
675 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[0]);
676 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[1]);
677 if (!projection_is_visible0(proj
, robject
))
678 pos_start
.dec
+= step_delta
/ delta_div
;
680 } while (delta_div
< GRID_BISECT
);
682 /* find end position */
684 pos_end
.dec
+= step_delta
;
685 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[0]);
686 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[1]);
687 } while (projection_is_visible1(proj
, robject
) &&
688 pos_end
.dec
- proj
->centre_dec
< 90.0);
689 pos_end
.dec
-= step_delta
;
691 /* binary chop end */
694 pos_end
.dec
+= step_delta
/ delta_div
;
695 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[0]);
696 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[1]);
697 if (!projection_is_visible1(proj
, robject
))
698 pos_end
.dec
-= step_delta
/ delta_div
;
700 } while (delta_div
< GRID_BISECT
);
702 ln_deg_to_hms(ra
, &hms
);
703 if (hms
.minutes
== 0 && hms
.seconds
== 0.0)
704 sprintf(text
, "%2.0dh", hms
.hours
);
705 else if (hms
.seconds
< 0.1)
706 sprintf(text
, "%2.0dh%2.2dm", hms
.hours
, hms
.minutes
);
708 sprintf(text
, "%2.0dh%2.2dm%2.0f", hms
.hours
, hms
.minutes
,
711 cairo_move_to(robject
->cr
,
713 robject
->coord
[0].y
);
714 cairo_show_text(robject
->cr
, text
);
715 cairo_move_to(robject
->cr
,
717 robject
->coord
[1].y
+ 15.0); // font size
718 cairo_show_text(robject
->cr
, text
);
722 void equ_render_dec_labels(struct render_object
*robject
, struct projection
*proj
)
724 gdouble step
, step_delta
, dec_start
, dec_end
;
725 struct ln_equ_posn pos1
;
727 pos1
.ra
= proj
->centre_ra
;
729 step_delta
= get_dec_step_delta(proj
);
730 clip_dec_equ_grid(proj
, step_delta
, &dec_start
, &dec_end
);
731 robject
->coord
[0].posn
= &pos1
;
733 for (step
= dec_start
; step
<= dec_end
; step
+= step_delta
) {
735 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[0]);
736 render_dec_labels_at(proj
, robject
, step
);
740 void equ_render_ra_labels(struct render_object
*robject
, struct projection
*proj
)
742 gdouble step
, step_delta
, ra_start
, ra_end
;
743 struct ln_equ_posn pos1
;
745 pos1
.ra
= proj
->centre_dec
;
747 step_delta
= get_ra_step_delta(proj
);
748 clip_ra_equ_grid(proj
, step_delta
, &ra_start
, &ra_end
);
749 robject
->coord
[0].posn
= &pos1
;
751 for (step
= ra_start
; step
<= ra_end
; step
+= step_delta
) {
753 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[0]);
754 render_ra_labels_at(proj
, robject
, step
);
758 void hrz_render_dec_labels(struct render_object
*robject
, struct projection
*proj
)
760 gdouble step
, step_delta
, dec_start
, dec_end
;
761 struct ln_equ_posn pos1
;
763 pos1
.ra
= proj
->centre_ra
;
765 step_delta
= get_dec_step_delta(proj
);
766 clip_dec_equ_grid(proj
, step_delta
, &dec_start
, &dec_end
);
767 robject
->coord
[0].posn
= &pos1
;
769 for (step
= dec_start
; step
<= dec_end
; step
+= step_delta
) {
771 proj
->trans
->sky_to_proj_hrz(proj
, &robject
->coord
[0]);
772 render_dec_labels_at(proj
, robject
, step
);
776 void hrz_render_ra_labels(struct render_object
*robject
, struct projection
*proj
)
778 gdouble step
, step_delta
, ra_start
, ra_end
;
779 struct ln_equ_posn pos1
;
781 pos1
.ra
= proj
->centre_dec
;
783 step_delta
= get_ra_step_delta(proj
);
784 clip_ra_equ_grid(proj
, step_delta
, &ra_start
, &ra_end
);
785 robject
->coord
[0].posn
= &pos1
;
787 for (step
= ra_start
; step
<= ra_end
; step
+= step_delta
) {
789 proj
->trans
->sky_to_proj_hrz(proj
, &robject
->coord
[0]);
790 render_ra_labels_at(proj
, robject
, step
);
794 static void equ_render_dec(struct render_object
*robject
,
795 struct projection
*proj
, gint labels
)
797 gdouble step
, dec_start
= -90, dec_end
= 90, step_delta
;
798 struct ln_equ_posn pos1
;
799 int start_visible
, end_visible
;
801 step_delta
= get_dec_step_delta(proj
);
802 //clip_dec_equ_grid(proj, step_delta, &dec_start, &dec_end);
803 robject
->coord
[0].posn
= &pos1
;
805 for (pos1
.dec
= dec_start
; pos1
.dec
<= dec_end
; pos1
.dec
+= step_delta
) {
808 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[0]);
809 start_visible
= projection_is_visible0(proj
, robject
);
810 cairo_move_to(robject
->cr
,
812 robject
->coord
[0].y
);
814 for (step
= 5; step
<= 360; step
+= 5) {
816 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[0]);
817 end_visible
= projection_is_visible0(proj
, robject
);
818 if (start_visible
|| end_visible
)
819 cairo_line_to(robject
->cr
,
821 robject
->coord
[0].y
);
823 cairo_move_to(robject
->cr
,
825 robject
->coord
[0].y
);
826 start_visible
= end_visible
;
831 static void equ_render_ra(struct render_object
*robject
,
832 struct projection
*proj
, gint labels
)
834 gdouble step
, ra_start
=0, ra_end
= 360, step_delta
;
835 struct ln_equ_posn pos1
;
836 int start_visible
, end_visible
;
838 step_delta
= get_ra_step_delta(proj
);
839 //clip_ra_equ_grid(proj, step_delta, &ra_start, &ra_end);
840 robject
->coord
[0].posn
= &pos1
;
842 for (pos1
.ra
= ra_start
; pos1
.ra
<= ra_end
; pos1
.ra
+= step_delta
) {
845 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[0]);
846 start_visible
= projection_is_visible0(proj
, robject
);
847 cairo_move_to(robject
->cr
,
849 robject
->coord
[0].y
);
851 for (step
= -75; step
<= 80; step
+= 5) {
853 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[0]);
854 end_visible
= projection_is_visible0(proj
, robject
);
855 if (start_visible
|| end_visible
)
856 cairo_line_to(robject
->cr
,
858 robject
->coord
[0].y
);
860 cairo_move_to(robject
->cr
,
862 robject
->coord
[0].y
);
863 start_visible
= end_visible
;
868 void grid_horizon_ra(struct render_object
*robject
, struct projection
*proj
)
871 struct ln_equ_posn pos1
;
872 int start_visible
, end_visible
;
876 robject
->coord
[0].posn
= &pos1
;
877 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[0]);
878 start_visible
= projection_is_visible0(proj
, robject
);
879 cairo_move_to(robject
->cr
,
881 robject
->coord
[0].y
);
883 for (step
= 10; step
<= 360; step
+= 10) {
885 proj
->trans
->sky_to_proj_equ(proj
, &robject
->coord
[0]);
886 end_visible
= projection_is_visible0(proj
, robject
);
887 if (start_visible
|| end_visible
)
888 cairo_line_to(robject
->cr
,
890 robject
->coord
[0].y
);
892 cairo_move_to(robject
->cr
,
894 robject
->coord
[0].y
);
895 start_visible
= end_visible
;
899 void grid_horizon_altaz(struct render_object
*robject
, struct projection
*proj
)
902 struct ln_equ_posn pos1
;
903 int start_visible
, end_visible
;
905 cairo_save(robject
->cr
);
906 cairo_set_source_rgba(robject
->cr
, 1, 0.35, 0.55, 0.7);
910 robject
->coord
[0].posn
= &pos1
;
912 proj
->trans
->sky_to_proj_hrz(proj
, &robject
->coord
[0]);
913 start_visible
= projection_is_visible0(proj
, robject
);
914 cairo_move_to(robject
->cr
,
916 robject
->coord
[0].y
);
918 for (step
= 10; step
<= 360; step
+= 10) {
920 proj
->trans
->sky_to_proj_hrz(proj
, &robject
->coord
[0]);
921 end_visible
= projection_is_visible0(proj
, robject
);
922 if (start_visible
|| end_visible
)
923 cairo_line_to(robject
->cr
,
925 robject
->coord
[0].y
);
927 cairo_move_to(robject
->cr
,
929 robject
->coord
[0].y
);
930 start_visible
= end_visible
;
932 cairo_stroke(robject
->cr
);
933 cairo_restore(robject
->cr
);
936 void grid_horizon_news(struct render_object
*robject
, struct projection
*proj
)
938 struct ln_equ_posn pos1
;
940 cairo_save(robject
->cr
);
941 cairo_set_font_size (robject
->cr
, 18.0);
942 cairo_set_source_rgba(robject
->cr
, 1, 0.35, 0.55, 0.7);
943 robject
->coord
[0].posn
= &pos1
;
947 proj
->trans
->sky_to_proj_hrz(proj
, &robject
->coord
[0]);
948 cairo_move_to(robject
->cr
,
950 robject
->coord
[0].y
);
951 cairo_show_text(robject
->cr
, "S");
954 proj
->trans
->sky_to_proj_hrz(proj
, &robject
->coord
[0]);
955 cairo_move_to(robject
->cr
,
957 robject
->coord
[0].y
);
958 cairo_show_text(robject
->cr
, "W");
961 proj
->trans
->sky_to_proj_hrz(proj
, &robject
->coord
[0]);
962 cairo_move_to(robject
->cr
,
964 robject
->coord
[0].y
);
965 cairo_show_text(robject
->cr
, "N");
968 proj
->trans
->sky_to_proj_hrz(proj
, &robject
->coord
[0]);
969 cairo_move_to(robject
->cr
,
971 robject
->coord
[0].y
);
972 cairo_show_text(robject
->cr
, "E");
974 cairo_restore(robject
->cr
);
977 void grid_render(Sky
*sky
)
979 struct render_object
*robject
= &sky
->robject
;
980 struct projection
*proj
= &sky
->projection
;
981 gint labels
= sky
->marker_settings
.show_grid_labels
;
984 if (robject
->flags
.night_mode
)
985 alpha
= GRID_NIGHT_ALPHA
;
987 alpha
= GRID_DAY_ALPHA
;
989 cairo_save(robject
->cr
);
990 cairo_set_source_rgba(robject
->cr
, 0, 0.35, 0.55, alpha
);
991 cairo_set_font_size (robject
->cr
, 13.0);
993 if (robject
->type
== RT_FAST
) //TODO make step size * 2.0 when fast
994 cairo_set_tolerance (robject
->cr
, 1.0);
996 switch (proj
->grid_coords
) {
998 equ_render_ra(robject
, proj
, labels
);
999 equ_render_dec(robject
, proj
, labels
);
1000 equ_render_dec_labels(robject
, proj
);
1001 equ_render_ra_labels(robject
, proj
);
1004 hrz_render_ra(robject
, proj
, labels
);
1005 hrz_render_dec(robject
, proj
, labels
);
1006 hrz_render_dec_labels(robject
, proj
);
1007 hrz_render_ra_labels(robject
, proj
);
1010 cairo_stroke(robject
->cr
);
1012 //grid_horizon_ra(robject, proj);
1013 grid_horizon_altaz(robject
, proj
);
1016 grid_horizon_news(robject
, proj
);
1018 if (robject
->type
== RT_FAST
)
1019 cairo_set_tolerance (robject
->cr
, 0.1); /* do we need this */
1020 cairo_restore(robject
->cr
);