-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathalmanac_bg.py
144 lines (130 loc) · 5.98 KB
/
almanac_bg.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright (C) 2011 Mehmet Atakan Gürkan
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 3 as
# published by the Free Software Foundation.
#
# 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 (probably in a file named COPYING).
# If not, see <http://www.gnu.org/licenses/>.
from __future__ import division, print_function
from math import floor, fmod, fabs, atan2, atan, asin, sqrt, sin, cos
import datetime, calendar, ephem, pytz, pyx
from datetime import timedelta as TD
from pyx import path, canvas, color, style, text, graph
from almanac_utils import to_chart_coord
def make_alm_bg(bclc, begin_day_datetime, no_days, chart, obs,
sun, sun_set, sun_rise) :
''' bclc: background clipped canvas'''
# make a gradient of dark blue to black in the bg
daycolor = color.rgb(0,82/255.0,137/255.0)
nightcolor = color.rgb(0,0,0)
DNcolgrad = color.lineargradient(daycolor,nightcolor)
# First try: Drawing thick lines, does not really work.
#for i in range(41) :
# horangle = 18.0*i/40
# obs.horizon = '-%d' % (horangle)
# eve_twi_grad = []
# mor_twi_grad = []
# for doy in range(no_days) :
# obs.date = begin_day + doy
# eve_twi_grad.append(obs.next_setting(sun))
# mor_twi_grad.append(obs.next_rising(sun))
# eve_twi_gradp = event_to_path(eve_twi_grad, chart)
# mor_twi_gradp = event_to_path(mor_twi_grad, chart)
# clc.stroke(eve_twi_gradp,[style.linewidth(0.24),DNcolgrad.getcolor(i/40.0)])
# clc.stroke(mor_twi_gradp,[style.linewidth(0.24),DNcolgrad.getcolor(i/40.0)])
## Second try: using rectangles for each day. Leads to a very big file
## and artifacts on screen, especially with antialiasing, hopefully fine
## when printed.
#def draw_LR_colgrad_rect(canv, LLx, LLy, W, H, colgrad, n) :
# ''' Draw a rectangle consisting of n sub rectangles, each selecting its
# color from the given color gradient.'''
# for i in range(n) :
# llx = (i+0.0)/n * W + LLx
# lly = LLy
# # XXX multiplication by 1.02 below is to make sure that
# # XXX sub-rectangles overlap
# w = 1.0/n * W * 1.02
# h = H
# canv.fill(path.rect(llx, lly, w, h), [colgrad.getcolor((i+0.0)/n)])
#
#day_thickness = chart.height/no_days
#for doy in range(no_days) :
# # XXX w/o the little addition of 0.2*ephem.hour below, we would have
# # XXX small empty triangular regions.
# SS = to_chart_coord(sun_set[doy]-0.2*ephem.hour, chart)
# ET = to_chart_coord(eve_twilight[doy], chart)
# MT = to_chart_coord(mor_twilight[doy], chart)
# SR = to_chart_coord(sun_rise[doy]+0.2*ephem.hour, chart)
## evening twilight to darkness
# LLx = SS[0]
# LLy = SS[1] - day_thickness/2.0
# W = ET[0] - SS[0]
# H = day_thickness
# draw_LR_colgrad_rect(clc, LLx, LLy, W, H, DNcolgrad, 18)
## darkness to morning twilight
# LLx = SR[0]
# W = MT[0] - SR[0] # XXX note: negative width
# draw_LR_colgrad_rect(clc, LLx, LLy, W, H, DNcolgrad, 18)
## Darkness between twilights
#rev_eve_twilight = eve_twilight[:]
#rev_eve_twilight.reverse()
#darknesspath = event_to_path_no_check(rev_eve_twilight[:] + mor_twilight[:], chart)
#darknesspath.append(path.closepath())
#clc.stroke(darknesspath, [nightcolor])
#clc.fill(darknesspath, [nightcolor])
# Third try: Per Alp Akoğlu's request let's try to this right.
# This way it will also be more general and easier to adapt to higher
# latitudes where twilight never ends on some days of the year.
gdata = []
for doy in range(0, no_days, 10) :
for tt in range(16*6+1) : # for 16 hours, every 10 minutes
sun_tt = chart.ULcorn + doy + tt*ephem.minute*10
x, y = to_chart_coord(sun_tt, chart)
obs.date = sun_tt
sun.compute(obs)
z = sun.alt/ephem.degrees('-18:00:00')
if z>1 : z=1
if z<0 : z=0
z = z*z # this makes the twilight more prominent
gdata.append([x, y, z])
# XXX I found the magic numbers below by trial error
g = graph.graphxyz(size=1, xpos=11, ypos=16.73, xscale=12, yscale=18.31,
projector=graph.graphxyz.parallel(-90, 90),
x=graph.axis.linear(min=-1, max=chart.width+1, painter=None),
y=graph.axis.linear(min=-1, max=chart.height+1, painter=None),
z=graph.axis.linear(min=-1, max=2, painter=None))
g.plot(graph.data.points(gdata, x=1, y=2, z=3, color=3),
[graph.style.surface(gradient=DNcolgrad,
gridcolor=None,
backcolor=color.rgb.black)])
bclc.insert(g)
# the following is for the debugging the graph above
#c.stroke(path.line(0, 0, chart.width, chart.height), [color.cmyk.Red])
def make_alm_bg_vdots(bclc, first_sunday, no_days, chart) :
# vertical dots
# left side is 4pm, right side is 8am. We will draw dots every 1/2 hour
nlines = int(round((chart.URcorn-chart.ULcorn)/ephem.hour*2+1))
xincr = chart.width/(nlines-1)
h = chart.height
for i in range(nlines) :
bclc.stroke(path.line(i*xincr, 0, i*xincr, h),
[color.cmyk.Gray, style.linestyle(style.linecap.round,
style.dash([0, 2.6333*366.0/no_days]))])
def make_alm_bg_hdots(bclc, first_sunday, no_days, chart) :
# horizontal dots
# we start with the first Sunday of the year
for sunday in range(first_sunday, no_days, 7) :
x1 = 0
x2 = chart.width
y = chart.height - (sunday * chart.height / no_days)
bclc.stroke(path.line(x1, y, x2, y),
[color.cmyk.Gray, style.linestyle(style.linecap.round, style.dash([0, 3.248]))])