/* * dms - calculate in degrees, minutes, and seconds (based on deg) * * Copyright (C) 1999,2010 David I. Bell and Landon Curt Noll * * Calc is open software; you can redistribute it and/or modify it under * the terms of the version 2.1 of the GNU Lesser General Public License * as published by the Free Software Foundation. * * Calc 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 Lesser General * Public License for more details. * * A copy of version 2.1 of the GNU Lesser General Public License is * distributed with calc under the filename COPYING-LGPL. You should have * received a copy with calc; if not, write to Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * Under source code control: 1990/02/15 01:50:33 * File existed as early as: before 1990 * * Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/ */ obj dms {deg, min, sec}; define dms(deg, min, sec) { local obj dms ans; /* return value */ /* default missing args to 0 */ if (isnull(sec)) { sec = 0; } if (isnull(min)) { min = 0; } /* load object */ ans.deg = deg; ans.min = min; ans.sec = sec; /* return properly formed object */ ans = fixdms(ans); return ans; } define dms_add(a, b) { local obj dms ans; /* return value */ /* initalize value to 1st arg */ if (istype(a, ans)) { /* 1st arg is dms object, load it */ ans.deg = a.deg; ans.min = a.min; ans.sec = a.sec; } else { /* 1st arg is not dms, assume scalar degrees */ ans.deg = a; ans.min = 0; ans.sec = 0; } /* add value of 2nd arg */ if (istype(b, ans)) { /* 2nd arg is dms object, add it */ ans.deg += b.deg; ans.min += b.min; ans.sec += b.sec; } else { /* 2nd arg is not dms, add scalar degrees */ ans.deg += b; } /* return normalized result */ ans = fixdms(ans); return ans; } define dms_neg(a) { local obj dms ans; /* return value */ /* negate argument */ if (istype(a, ans)) { /* 1st arg is dms object, load it */ ans.deg = -a.deg; ans.min = -a.min; ans.sec = -a.sec; } else { /* 2nd arg is not dms, negate scalar degrees */ ans.deg = -a; ans.min = 0; ans.sec = 0; } /* return normalized result */ ans = fixdms(ans); return ans; } define dms_sub(a, b) { local obj dms ans; /* return value */ /* initalize value to 1st arg */ if (istype(a, ans)) { /* 1st arg is dms object, load it */ ans.deg = a.deg; ans.min = a.min; ans.sec = a.sec; } else { /* 1st arg is not dms, assume scalar degrees */ ans.deg = a; ans.min = 0; ans.sec = 0; } /* subtract value of 2nd arg */ if (istype(b, ans)) { /* 2nd arg is dms object, subtract it */ ans.deg -= b.deg; ans.min -= b.min; ans.sec -= b.sec; } else { /* 2nd arg is not dms, subtract scalar degrees */ ans.deg -= b; } /* return normalized result */ ans = fixdms(ans); return ans; } define dms_mul(a, b) { local obj dms ans; /* return value */ /* dms object multiplication */ if (istype(a, ans) && istype(b, ans)) { ans.deg = dms_abs(a) * dms_abs(b); ans.min = 0; ans.sec = 0; /* scalar multiplication */ } else if (istype(a, ans)) { ans.deg = a.deg * b; ans.min = a.min * b; ans.sec = a.sec * b; } else { ans.deg = b.deg * a; ans.min = b.min * a; ans.sec = b.sec * a; } /* return normalized result */ ans = fixdms(ans); return ans; } define dms_print(a) { local obj dms ans; /* temp object for dms type testing */ /* firewall - arg must be a dms object */ if (! istype(a, ans)) { quit "dms_print called with non dms object"; } /* print in dms form */ print a.deg : 'd' : a.min : 'm' : a.sec : 's' :; } define dms_abs(a) { local obj dms ans; /* temp object for dms type testing */ local deg; /* return scalar value */ /* firewall - just absolute value non dms objects */ if (! istype(a, ans)) { return abs(a); } /* compute degrees */ deg = a.deg + a.min / 60 + a.sec / 3600; /* return degrees */ return deg; } define dms_norm(a) { local obj dms ans; /* temp object for dms type testing */ local deg; /* degrees */ /* firewall - arg must be a dms object */ if (! istype(a, ans)) { quit "dms_norm called with non dms object"; } /* square degrees (norm is the square of absolute value */ deg = dms_abs(a); /* return degrees */ return deg*deg; } define dms_test(a) { local obj dms ans; /* temp value */ /* firewall - arg must be a dms object */ if (! istype(a, ans)) { quit "dms_test called with non dms object"; } /* return false of non-zero */ ans = fixdms(a); if (ans.deg == 0 && ans.min == 0 && ans.sec == 0) { /* false */ return 0; } /* true */ return 1; } define dms_int(a) { local obj dms ans; /* return value */ /* firewall - arg must be a dms object */ if (! istype(a, ans)) { quit "dms_int called with non dms object"; } /* normalize the argument */ ans = fixdms(a); /* truncate to the nearest second */ ans.sec = int(ans.sec); /* return value to the nearest second */ return ans; } define dms_frac(a) { local obj dms ans; /* return value */ /* firewall - arg must be a dms object */ if (! istype(a, ans)) { quit "dms_frac called with non dms object"; } /* normalize the argument */ ans = fixdms(a); /* remove all but fractional seconds */ ans.deg = 0; ans.min = 0; ans.sec = frac(ans.sec); /* return value to the second fraction */ return ans; } define dms_rel(a,b) { local abs_a, abs_b; /* scalars of the arguments */ /* compute scalars of the arguments */ abs_a = dms_abs(a); abs_b = dms_abs(b); /* return the comparison */ return cmp(abs_a, abs_b); } define dms_cmp(a,b) { local abs_a, abs_b; /* scalars of the arguments */ /* compute scalars of the arguments */ abs_a = dms_abs(a); abs_b = dms_abs(b); /* return the equality comparison */ return (abs_a == abs_b); } define dms_inc(a) { local obj dms ans; /* return value */ /* increment a dms object */ if (istype(a, ans)) { ans = a; ++ans.sec; /* return normalized result */ ans = fixdms(ans); return ans; } /* increment a scalar */ return a+1; } define dms_dec(a) { local obj dms ans; /* return value */ /* decrement a dms object */ if (istype(a, ans)) { ans = a; --ans.sec; /* return normalized result */ ans = fixdms(ans); return ans; } /* decrement a scalar */ return a-1; } define fixdms(a) { local obj dms ans; /* temp value */ /* firewall */ if (! istype(a, ans)) { quit "attempt to fix a non dms object"; } /* force minutes to be intergral */ a.min += frac(a.deg) * 60; a.deg = int(a.deg); /* force degrees to be intergral */ a.sec += frac(a.min) * 60; a.min = int(a.min); /* carry excess seconds into minutes */ a.min += a.sec // 60; a.sec %= 60; /* carry excess minutes into degrees */ a.deg += a.min // 60; a.min %= 60; /* round degrees :-) */ a.deg %= 360; /* return normalized result */ return a; } if (config("resource_debug") & 3) { print "obj dms {deg, min, sec} defined"; }