UNPKG

15.2 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6
7var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); /**
8 * @copyright 2013 Sonia Keys
9 * @copyright 2016 commenthol
10 * @license MIT
11 * @module sundial
12 */
13/**
14 * Sundial: Chapter 58, Calculation of a Planar Sundial.
15 */
16
17exports.general = general;
18exports.equatorial = equatorial;
19exports.horizontal = horizontal;
20exports.vertical = vertical;
21
22var _base = require('./base');
23
24var _base2 = _interopRequireDefault(_base);
25
26function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
27
28/**
29 * Point return type represents a point to be used in constructing the sundial.
30 */
31function Point(x, y) {
32 this.x = x || 0;
33 this.y = y || 0;
34}
35
36/**
37 * Line holds data to draw an hour line on the sundial.
38 */
39function Line(hour, points) {
40 this.hour = hour; // 0 to 24
41 this.points = points || []; // One or more points corresponding to the hour.
42}
43
44var m = [-23.44, -20.15, -11.47, 0, 11.47, 20.15, 23.44];
45
46/**
47 * General computes data for the general case of a planar sundial.
48 *
49 * Argument φ is geographic latitude at which the sundial will be located.
50 * D is gnomonic declination, the azimuth of the perpendicular to the plane
51 * of the sundial, measured from the southern meridian towards the west.
52 * Argument a is the length of a straight stylus perpendicular to the plane
53 * of the sundial, z is zenithal distance of the direction defined by the
54 * stylus. Angles φ, D, and z are in radians. Units of stylus length a
55 * are arbitrary.
56 *
57 * Results consist of a set of lines, a center point, u, the length of a
58 * polar stylus, and ψ, the angle which the polar stylus makes with the plane
59 * of the sundial. The center point, the points defining the hour lines, and
60 * u are in units of a, the stylus length. ψ is in radians.
61 */
62function general(φ, D, a, z) {
63 // (φ, D, a, z float64) (lines []Line, center Point, u, ψ float64)
64 var _base$sincos = _base2.default.sincos(φ),
65 _base$sincos2 = _slicedToArray(_base$sincos, 2),
66 sφ = _base$sincos2[0],
67 cφ = _base$sincos2[1];
68
69 var tφ = sφ / cφ;
70
71 var _base$sincos3 = _base2.default.sincos(D),
72 _base$sincos4 = _slicedToArray(_base$sincos3, 2),
73 sD = _base$sincos4[0],
74 cD = _base$sincos4[1];
75
76 var _base$sincos5 = _base2.default.sincos(z),
77 _base$sincos6 = _slicedToArray(_base$sincos5, 2),
78 sz = _base$sincos6[0],
79 cz = _base$sincos6[1];
80
81 var P = sφ * cz - cφ * sz * cD;
82 var lines = [];
83 for (var i = 0; i < 24; i++) {
84 var l = new Line(i);
85 var H = (i - 12) * 15 * Math.PI / 180;
86 var aH = Math.abs(H);
87
88 var _base$sincos7 = _base2.default.sincos(H),
89 _base$sincos8 = _slicedToArray(_base$sincos7, 2),
90 sH = _base$sincos8[0],
91 cH = _base$sincos8[1];
92
93 var _iteratorNormalCompletion = true;
94 var _didIteratorError = false;
95 var _iteratorError = undefined;
96
97 try {
98 for (var _iterator = m[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
99 var d = _step.value;
100
101 var tδ = Math.tan(d * Math.PI / 180);
102 var H0 = Math.acos(-tφ * tδ);
103 if (aH > H0) {
104 continue; // sun below horizon
105 }
106 var Q = sD * sz * sH + (cφ * cz + sφ * sz * cD) * cH + P * tδ;
107 if (Q < 0) {
108 continue; // sun below plane of sundial
109 }
110 var Nx = cD * sH - sD * (sφ * cH - cφ * tδ);
111 var Ny = cz * sD * sH - (cφ * sz - sφ * cz * cD) * cH - (sφ * sz + cφ * cz * cD) * tδ;
112 l.points.push(new Point(a * Nx / Q, a * Ny / Q));
113 }
114 } catch (err) {
115 _didIteratorError = true;
116 _iteratorError = err;
117 } finally {
118 try {
119 if (!_iteratorNormalCompletion && _iterator.return) {
120 _iterator.return();
121 }
122 } finally {
123 if (_didIteratorError) {
124 throw _iteratorError;
125 }
126 }
127 }
128
129 if (l.points.length > 0) {
130 lines.push(l);
131 }
132 }
133 var center = new Point();
134 center.x = a / P * cφ * sD;
135 center.y = -a / P * (sφ * sz + cφ * cz * cD);
136 var aP = Math.abs(P);
137 var u = a / aP;
138 var ψ = Math.asin(aP);
139 return {
140 lines: lines,
141 center: center,
142 length: u,
143 angle: ψ
144 };
145}
146
147/**
148 * Equatorial computes data for a sundial level with the equator.
149 *
150 * Argument φ is geographic latitude at which the sundial will be located;
151 * a is the length of a straight stylus perpendicular to the plane of the
152 * sundial.
153 *
154 * The sundial will have two sides, north and south. Results n and s define
155 * lines on the north and south sides of the sundial. Result coordinates
156 * are in units of a, the stylus length.
157 */
158function equatorial(φ, a) {
159 // (φ, a float64) (n, s []Line)
160 var tφ = Math.tan(φ);
161 var n = [];
162 var s = [];
163 for (var i = 0; i < 24; i++) {
164 var nl = new Line(i);
165 var sl = new Line(i);
166 var H = (i - 12) * 15 * Math.PI / 180;
167 var aH = Math.abs(H);
168
169 var _base$sincos9 = _base2.default.sincos(H),
170 _base$sincos10 = _slicedToArray(_base$sincos9, 2),
171 sH = _base$sincos10[0],
172 cH = _base$sincos10[1];
173
174 var _iteratorNormalCompletion2 = true;
175 var _didIteratorError2 = false;
176 var _iteratorError2 = undefined;
177
178 try {
179 for (var _iterator2 = m[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
180 var d = _step2.value;
181
182 var tδ = Math.tan(d * Math.PI / 180);
183 var H0 = Math.acos(-tφ * tδ);
184 if (aH > H0) {
185 continue;
186 }
187 var x = -a * sH / tδ;
188 var yy = a * cH / tδ;
189 if (tδ < 0) {
190 sl.points.push(new Point(x, yy));
191 } else {
192 nl.points.push(new Point(x, -yy));
193 }
194 }
195 } catch (err) {
196 _didIteratorError2 = true;
197 _iteratorError2 = err;
198 } finally {
199 try {
200 if (!_iteratorNormalCompletion2 && _iterator2.return) {
201 _iterator2.return();
202 }
203 } finally {
204 if (_didIteratorError2) {
205 throw _iteratorError2;
206 }
207 }
208 }
209
210 if (nl.points.length > 0) {
211 n.push(nl);
212 }
213 if (sl.points.length > 0) {
214 s.push(sl);
215 }
216 }
217 return {
218 north: n,
219 south: s
220 };
221}
222
223/**
224 * Horizontal computes data for a horizontal sundial.
225 *
226 * Argument φ is geographic latitude at which the sundial will be located,
227 * a is the length of a straight stylus perpendicular to the plane of the
228 * sundial.
229 *
230 * Results consist of a set of lines, a center point, and u, the length of a
231 * polar stylus. They are in units of a, the stylus length.
232 */
233function horizontal(φ, a) {
234 // (φ, a float64) (lines []Line, center Point, u float64)
235 var _base$sincos11 = _base2.default.sincos(φ),
236 _base$sincos12 = _slicedToArray(_base$sincos11, 2),
237 sφ = _base$sincos12[0],
238 cφ = _base$sincos12[1];
239
240 var tφ = sφ / cφ;
241 var lines = [];
242 for (var i = 0; i < 24; i++) {
243 var l = new Line(i);
244 var H = (i - 12) * 15 * Math.PI / 180;
245 var aH = Math.abs(H);
246
247 var _base$sincos13 = _base2.default.sincos(H),
248 _base$sincos14 = _slicedToArray(_base$sincos13, 2),
249 sH = _base$sincos14[0],
250 cH = _base$sincos14[1];
251
252 var _iteratorNormalCompletion3 = true;
253 var _didIteratorError3 = false;
254 var _iteratorError3 = undefined;
255
256 try {
257 for (var _iterator3 = m[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
258 var d = _step3.value;
259
260 var tδ = Math.tan(d * Math.PI / 180);
261 var H0 = Math.acos(-tφ * tδ);
262 if (aH > H0) {
263 continue; // sun below horizon
264 }
265 var Q = cφ * cH + sφ * tδ;
266 var x = a * sH / Q;
267 var y = a * (sφ * cH - cφ * tδ) / Q;
268 l.points.push(new Point(x, y));
269 }
270 } catch (err) {
271 _didIteratorError3 = true;
272 _iteratorError3 = err;
273 } finally {
274 try {
275 if (!_iteratorNormalCompletion3 && _iterator3.return) {
276 _iterator3.return();
277 }
278 } finally {
279 if (_didIteratorError3) {
280 throw _iteratorError3;
281 }
282 }
283 }
284
285 if (l.points.length > 0) {
286 lines.push(l);
287 }
288 }
289 var center = new Point(0, -a / tφ);
290 var u = a / Math.abs(sφ);
291 return {
292 lines: lines,
293 center: center,
294 length: u
295 };
296}
297
298/**
299 * Vertical computes data for a vertical sundial.
300 *
301 * Argument φ is geographic latitude at which the sundial will be located.
302 * D is gnomonic declination, the azimuth of the perpendicular to the plane
303 * of the sundial, measured from the southern meridian towards the west.
304 * Argument a is the length of a straight stylus perpendicular to the plane
305 * of the sundial.
306 *
307 * Results consist of a set of lines, a center point, and u, the length of a
308 * polar stylus. They are in units of a, the stylus length.
309 */
310function vertical(φ, D, a) {
311 // (φ, D, a float64) (lines []Line, center Point, u float64)
312 var _base$sincos15 = _base2.default.sincos(φ),
313 _base$sincos16 = _slicedToArray(_base$sincos15, 2),
314 sφ = _base$sincos16[0],
315 cφ = _base$sincos16[1];
316
317 var tφ = sφ / cφ;
318
319 var _base$sincos17 = _base2.default.sincos(D),
320 _base$sincos18 = _slicedToArray(_base$sincos17, 2),
321 sD = _base$sincos18[0],
322 cD = _base$sincos18[1];
323
324 var lines = [];
325 for (var i = 0; i < 24; i++) {
326 var l = new Line(i);
327 var H = (i - 12) * 15 * Math.PI / 180;
328 var aH = Math.abs(H);
329
330 var _base$sincos19 = _base2.default.sincos(H),
331 _base$sincos20 = _slicedToArray(_base$sincos19, 2),
332 sH = _base$sincos20[0],
333 cH = _base$sincos20[1];
334
335 var _iteratorNormalCompletion4 = true;
336 var _didIteratorError4 = false;
337 var _iteratorError4 = undefined;
338
339 try {
340 for (var _iterator4 = m[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
341 var d = _step4.value;
342
343 var tδ = Math.tan(d * Math.PI / 180);
344 var H0 = Math.acos(-tφ * tδ);
345 if (aH > H0) {
346 continue; // sun below horizon
347 }
348 var Q = sD * sH + sφ * cD * cH - cφ * cD * tδ;
349 if (Q < 0) {
350 continue; // sun below plane of sundial
351 }
352 var x = a * (cD * sH - sφ * sD * cH + cφ * sD * tδ) / Q;
353 var y = -a * (cφ * cH + sφ * tδ) / Q;
354 l.points.push(new Point(x, y));
355 }
356 } catch (err) {
357 _didIteratorError4 = true;
358 _iteratorError4 = err;
359 } finally {
360 try {
361 if (!_iteratorNormalCompletion4 && _iterator4.return) {
362 _iterator4.return();
363 }
364 } finally {
365 if (_didIteratorError4) {
366 throw _iteratorError4;
367 }
368 }
369 }
370
371 if (l.points.length > 0) {
372 lines.push(l);
373 }
374 }
375 var center = new Point();
376 center.x = -a * sD / cD;
377 center.y = a * tφ / cD;
378 var u = a / Math.abs(cφ * cD);
379 return {
380 lines: lines,
381 center: center,
382 length: u
383 };
384}
385
386exports.default = {
387 general: general,
388 equatorial: equatorial,
389 horizontal: horizontal,
390 vertical: vertical
391};
\No newline at end of file