mirror of
https://github.com/lcn2/calc.git
synced 2025-08-16 01:03:29 +03:00
365 lines
7.1 KiB
Plaintext
365 lines
7.1 KiB
Plaintext
/*
|
|
* dms - calculate in degrees, minutes, and seconds (based on deg)
|
|
*
|
|
* Copyright (C) 1999,2010,2021 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 */
|
|
|
|
/* initialize 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 */
|
|
|
|
/* initialize 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";
|
|
}
|
|
|
|
/* use builtin d2dms function */
|
|
d2dms(a.deg + a.min/60 + a.sec/3600, a.deg, a.min, a.sec),;
|
|
|
|
/* return normalized result */
|
|
return a;
|
|
}
|
|
|
|
if (config("resource_debug") & 3) {
|
|
print "obj dms {deg, min, sec} defined";
|
|
}
|