2 * dms - calculate in degrees, minutes, and seconds (based on deg)
4 * Copyright (C) 1999,2010 David I. Bell and Landon Curt Noll
6 * Calc is open software; you can redistribute it and/or modify it under
7 * the terms of the version 2.1 of the GNU Lesser General Public License
8 * as published by the Free Software Foundation.
10 * Calc is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
13 * Public License for more details.
15 * A copy of version 2.1 of the GNU Lesser General Public License is
16 * distributed with calc under the filename COPYING-LGPL. You should have
17 * received a copy with calc; if not, write to Free Software Foundation, Inc.
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 * @(#) $Revision: 30.2 $
21 * @(#) $Id: dms.cal,v 30.2 2010/09/02 06:14:16 chongo Exp $
22 * @(#) $Source: /usr/local/src/bin/calc/cal/RCS/dms.cal,v $
24 * Under source code control: 1990/02/15 01:50:33
25 * File existed as early as: before 1990
27 * Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
31 obj dms {deg, min, sec};
33 define dms(deg, min, sec)
35 local obj dms ans; /* return value */
37 /* default missing args to 0 */
50 /* return properly formed object */
58 local obj dms ans; /* return value */
60 /* initalize value to 1st arg */
62 /* 1st arg is dms object, load it */
67 /* 1st arg is not dms, assume scalar degrees */
73 /* add value of 2nd arg */
75 /* 2nd arg is dms object, add it */
80 /* 2nd arg is not dms, add scalar degrees */
84 /* return normalized result */
92 local obj dms ans; /* return value */
96 /* 1st arg is dms object, load it */
101 /* 2nd arg is not dms, negate scalar degrees */
107 /* return normalized result */
115 local obj dms ans; /* return value */
117 /* initalize value to 1st arg */
118 if (istype(a, ans)) {
119 /* 1st arg is dms object, load it */
124 /* 1st arg is not dms, assume scalar degrees */
130 /* subtract value of 2nd arg */
131 if (istype(b, ans)) {
132 /* 2nd arg is dms object, subtract it */
137 /* 2nd arg is not dms, subtract scalar degrees */
141 /* return normalized result */
149 local obj dms ans; /* return value */
151 /* dms object multiplication */
152 if (istype(a, ans) && istype(b, ans)) {
153 ans.deg = dms_abs(a) * dms_abs(b);
157 /* scalar multiplication */
158 } else if (istype(a, ans)) {
168 /* return normalized result */
176 local obj dms ans; /* temp object for dms type testing */
178 /* firewall - arg must be a dms object */
179 if (! istype(a, ans)) {
180 quit "dms_print called with non dms object";
183 /* print in dms form */
184 print a.deg : 'd' : a.min : 'm' : a.sec : 's' :;
190 local obj dms ans; /* temp object for dms type testing */
191 local deg; /* return scalar value */
193 /* firewall - just absolute value non dms objects */
194 if (! istype(a, ans)) {
198 /* compute degrees */
199 deg = a.deg + a.min / 60 + a.sec / 3600;
208 local obj dms ans; /* temp object for dms type testing */
209 local deg; /* degrees */
211 /* firewall - arg must be a dms object */
212 if (! istype(a, ans)) {
213 quit "dms_norm called with non dms object";
216 /* square degrees (norm is the square of absolute value */
226 local obj dms ans; /* temp value */
228 /* firewall - arg must be a dms object */
229 if (! istype(a, ans)) {
230 quit "dms_test called with non dms object";
233 /* return false of non-zero */
235 if (ans.deg == 0 && ans.min == 0 && ans.sec == 0) {
246 local obj dms ans; /* return value */
248 /* firewall - arg must be a dms object */
249 if (! istype(a, ans)) {
250 quit "dms_int called with non dms object";
253 /* normalize the argument */
256 /* truncate to the nearest second */
257 ans.sec = int(ans.sec);
259 /* return value to the nearest second */
266 local obj dms ans; /* return value */
268 /* firewall - arg must be a dms object */
269 if (! istype(a, ans)) {
270 quit "dms_frac called with non dms object";
273 /* normalize the argument */
276 /* remove all but fractional seconds */
279 ans.sec = frac(ans.sec);
281 /* return value to the second fraction */
288 local abs_a, abs_b; /* scalars of the arguments */
290 /* compute scalars of the arguments */
294 /* return the comparison */
295 return cmp(abs_a, abs_b);
301 local abs_a, abs_b; /* scalars of the arguments */
303 /* compute scalars of the arguments */
307 /* return the equality comparison */
308 return (abs_a == abs_b);
314 local obj dms ans; /* return value */
316 /* increment a dms object */
317 if (istype(a, ans)) {
321 /* return normalized result */
326 /* increment a scalar */
333 local obj dms ans; /* return value */
335 /* decrement a dms object */
336 if (istype(a, ans)) {
340 /* return normalized result */
345 /* decrement a scalar */
352 local obj dms ans; /* temp value */
355 if (! istype(a, ans)) {
356 quit "attempt to fix a non dms object";
359 /* force minutes to be intergral */
360 a.min += frac(a.deg) * 60;
363 /* force degrees to be intergral */
364 a.sec += frac(a.min) * 60;
367 /* carry excess seconds into minutes */
368 a.min += a.sec // 60;
371 /* carry excess minutes into degrees */
372 a.deg += a.min // 60;
375 /* round degrees :-) */
378 /* return normalized result */
382 if (config("resource_debug") & 3) {
383 print "obj dms {deg, min, sec} defined";