(С) С.Крушинский (Москва), 1993.
От редакции.
Представляя читателям эту интересную авторскую работу, мы должны сказать несколько слов о Спектруме", о нашем взгляде на этот компьютер и вообще на "Синклеровское" движение в целом.
"Спектрум" занимает совершенно особое место в деле компьютеризации нашей страны. Количество его поклонников давно перевалило за миллионы. Это движение, если говорить честно, стало всенародным и уникальным. Уникальность его состоит в том, что огромная часть самого талантливого, способного и одаренного населения одной шестой земного шара, не спрашиваясь ни советов, ни разрешений у высокого начальства, сделала то, что оказалось не под силу никаким госкомитетам и институтам. В рамках скромных 48 килобайт каждый день во всех уголках страны решаются интересные проблемы, делаются настоящие открытия.
Отличительной чертой нашего "синклериста" стала необычайная гордость за свою машину и уважение к ее возможностям. Ни для кого не секрет, что это маленькое чудо может очень многое из того, что и предположить себе не могут фирмы, торгующие суперсовременными 386-ыми и 486-ми IBM-совместимыми машинами. Мы знаем множество примеров, когда способные программисты, намаявшись за рабочий день с IBM-совместимой техникой, приходят домой и отдыхают наедине с любимым "Спектрумом". Они ни на что его не променяют.
Умение реализовать свои идеи, найти новые решения, сделать свой компьютер профессиональным, оставаясь в пределах 48 килобайт, дают такой большой простор для творчества и самоутверждения, какого не во всяком деле найдешь. Мы можем восхищаться гигантскими прокатными станами, ловко расправляющимися с тоннами металла, но всегда будет в почете профессия ювелира, способного так обработать несколько граммов, что они будут радовать глаз и вызывать всеобщее восхищение.
Все это имеет непосредственное отношение к данной статье. Астрономические расчеты достаточно сложны, но это одна из тех областей, в которых Ваш "Спектрум" смело может потягаться с гораздо более мощными потомками. Редакцию "ZX-РЕВЮ" особенно радуют такие материалы, которые выводят эту машинку на новый уровень, позволяют взять от него то, для чего она не предназначалась.
Мы никогда не сталкивались с астрологией и были приятно обрадованы тем фактом, что это, как оказалось, не мертвая наука былых лет, а постоянно развивающееся учение и занимаются им люди серьезные. Они непрерывно растут, повышают свою эрудицию, компьютерную грамотность, расширяют круг общения. Короче говоря, если Вы растете и вместе с вами растут возможности Вашего "Спектрума", то это то, что надо - основная цель "ZX-РЕВЮ" достигнута!
Для тех же из Вас, кто захочет заняться этим делом основательно, эта статья сможет стать первой вешкой на длинном и трудной пути. Мы далеки от мысли, что прочитав и разобрав ее, Вы сразу выйдете на некоторый достаточный уровень. Нет, это будет только началом. Может быть, даже трудным началом. Вам еще предстоит узнать и понять очень и очень многое. Статья достаточно сложна для неподготовленного читателя, поэтому кое-что, самое необходимое, в процессе редактирования мы вынесли в отдельный комментарий в ее заключении.
Автор статьи - Сергей Крушинский. Он не является ни профессиональным астрологом, ни профессиональным программистом. И то и другое - хобби. По профессии он журналист. В то же время, его программы по астрологии у нас распространены не меньше, чем западные аналоги и, если Сергей достиг значительных успехов в своем деле, то благодаря огромной любви к астрологии и, самое главное, к своему SPECCY, как он нежно называет "Спектрум".
Доводилось ли когда-нибудь читателю заглядывать в кабинет современного астролога? Если да, то могу спорить: первое, что бросилось в глаза, было не магическим кристаллом и не чучелом крокодила. На самом почетном месте светился дисплей! Как-то у моего знакомого, считающегося по праву одним из ведущих московских астрологов, сломался его "Коммодор". "Такое чувство, словно выключилось левое полушарие моего мозга", - жаловался он. Ничего удивительного, я сам вспоминаю как кошмар возню с таблицами и циркулем, длившуюся порой до полуночи ради того, чтобы построить один-единственный гороскоп, а под утро, напрягая взгляд, пытаешься его прочитать.
Дело решительным образом изменилось после того, как я купил "Спектрум" и написал первую программу - она стала делать за меня "грубую" работу.
Что такое компьютерная астрология? Это эффективная работа с большим количеством информации, возможность экспериментировать и исследовать. Чего только нет в современных астрологических программах, написанных для машин класса IBM: базы данных, атласы мира, графика, статистическая обработка информации... Даже самому отъявленному скептику небезынтересно взглянуть на аккуратные распечатки, представляющие его персону с новой точки зрения.
Может показаться, что "Спектруму" с его 48-ью килобайтами не под силу тягаться с куда более мощными компьютерами. Ничего подобного. Даже если за дело возьмется начинающий программист, не имеющий понятия ни о чем, кроме стандартного Бейсика -каким я был 2 года назад, когда написал первую программу, - SPECCY хватит на то, чтобы сделать по крайней мере самое важное, а именно: построить гороскоп рождения.
Что такое гороскоп.
Астрология покоится на аксиоме, согласно которой состояние мира в данном месте и в данный момент времени есть нечто уникальное. Когда человек рождается, он настолько восприимчив, что это состояние мира накладывает на него неповторимый отпечаток, впоследствии в большей или меньшей степени определяющий его реакции, а также тип ситуаций, с которыми приходится сталкиваться.
Самая большая роль отводится Солнцу, Луне и планетам Солнечной системы. Их расстановка - основа астрологического "сюжета" - никогда не повторяется во всех подробностях, так же, как не повторяется ни одна шахматная партия.
Сравните три рисунка. На них изображено по сути одно и то же: так называемая "небесная сфера". Вторая картинка имеется в любом астрономическом учебнике. За ее разъяснением можете обратиться и в энциклопедию. А третья - традиционный гороскоп.
Положение любого тела на небесной сфере определяется парой координат: долготой или угловым расстоянием от точки весеннего равноденствия до проекции тела на эклиптику (*/1), и широтой - расстоянием "вверх" или "вниз" от нее, со знаком "+" к Северному полюсу эклиптики и "-" к южному.
Внешний круг - это пояс Зодиака. Он делится на 12 знаков:
Г |
- Овен |
|
- Телец |
л |
- Близнецы |
s |
- Рак |
я |
- Лев |
Щ |
- Дева |
л |
- Весы |
я |
- Скорпион |
|
- Стрелец |
ъ |
- Козерог |
ллл |
- Водолей |
к |
- Рыбы |
Внутреннее кольцо разделено на 12 домов. Их тоже 12. Их отсчет начинается с линии горизонта (Асц-Дсц) и нумеруются против часовой стрелки, как и знаки.
В этом же кольце расположены Солнце ® , Луна " и планеты:
Меркурий $ Венера $
Марс % Юпитер &
Сатурн ' Уран (
Нептун ) Плутон [
Кроме того, Северный или Восходящий Лунный узел *
Зодиак - это пояс созвездий, тянущийся вдоль эклиптики. По нему совершают свой видимый путь Солнце, Луна и планеты. Астрологи делят его на 12 знаков по 30 градусов: Овен, Телец, Близнецы и т.д. Начало Овна - точка весеннего равноденствия. Астрологи говорят: "Марс - 12 градусов Тельца", а не "42 градуса", хотя это то же самое. В наше время знаки не совпадают с одноименными созвездиями.
Другая система координат называется экваториальной. В ней две мерки - прямое восхождение и склонение.
В астрологии есть еще такое понятие, как "дома". Их, как и знаков, двенадцать, только получаются они путем деления не зодиака, а пространства вокруг горизонта. Начало 1-го дома совпадает с точкой горизонта, где восходит солнце. Если знак говорит о том, как проявляет себя находящаяся в нем планета, то дом - о сфере жизни, на которую это действует. Сами же планеты - символы определенных жизненный принципов.
Солнце - источник сил, достоинства, принцип власти: глава государства и "царь в голове" (этот ряд можно продолжать до бесконечности); Луна - инстинкты, привычки, чувства, Марс - борьба, самоутверждение, Венера - гармония, любовь и т.д. Изучив положение планет в знаках, домах и угловые расстояния между планетами, астролог пытается построить характерный сюжет.
... Итак, надо научить "Спектрум" делать следующее:
1) Рассчитывать эклиптические геоцентрические (*/2) координаты Солнца, Луны и планет;
2) Определять границы домов в той же эклиптической системе координат и выводить результат на экран или принтер хотя бы в виде таблицы. Впрочем, места вполне хватит и на приличный рисунок.
Основой для расчетов будут служить дата, время рождения и, кроме того, географическая широта и долгота. Рассмотрим подробнее эти этапы.
Основной расчет.
Вначале определяется положение Солнца на эклиптике. Рассчитываем ZM (среднюю аномалию), ZV (истинную аномалию), ZR (радиус-вектор). Затем довольно простым способом SL, долготу солнца. Широта его всегда равна нулю (*/3). Две величины, полученные на данном этапе, ZR и ZM надо сохранить как SR и SM - они понадобятся в дальнейшем. Чтобы найти положение планеты, необходимо:
1) Рассчитать тем же способом, что и для Солнца, ZM,ZV,ZR;
2) Найти гелиоцентрическую широту (*/4) и долготу планеты (ZB и ZL);
3) Используя полученные ранее величины, перейти к геоцентрическим координатам.
Местонахождение Луны определяется совершенно особым способом, для нее
придется предусмотреть отдельный программный блок. Вместе с Луной будет рассчитываться и долгота лунного узла - точки, в которой Луна пересекает эклиптику, двигаясь с юга на север. Она важна для гороскопа, поскольку говорит о том, насколько гармонично личность вписывается в социум. Все сказанное можно проиллюстрировать схемой (табл. 1):
Таблица 1
Солнце |
Планеты (от J=2 до J=9) |
Луна |
SL, SR, SM
A(1,1)=SL
A(1,2)=0
ZM, ZR, ZV |
ZL, ZB A(J,1), A(J,2) |
A(10,1), A(10,2)
A(11,1)
A(11,2)=0 |
Входом в этот блок процедур послужит переменная, выражающая искомый момент времени - T и таблица, где содержатся характеристики орбит на некоторый известный момент, так называемую начальную эпоху T0. Их нетрудно пересчитать на эпоху T. Выход -массив A(2,11), долгота и широта 10 небесных тел и лунного узла.
Формулы, которые используются для решения почти всех поставленных здесь задач, -это классические формулы небесной механики, основывающиеся на законах, открытых Иоганном Кеплером. Смешно подумать, они умещаются в десяток Бейсик-строк. Есть, правда, нюанс. Тела Солнечной системы влияют друг на друга, что нарушает в некоторой мере "правильность" их движения. В астрономии это называется "возмущениями". Сатурн, например, может оказаться в соседнем градусе. Для достижения точности, на разных этапах расчетов приходится вносить поправки.
Чтобы вычислить положения планет с точностью до угловой секунды, рекомендую
такой алгоритм:
а) отключить телефон, запереть дверь;
б) выпить крепкого кофе;
в) набирать тригонометрические выражения, страницу за страницей; вернуться к шагу
б).
Выход из этого цикла надо предусмотреть по одному из следующих условий:
- если не хватило памяти компьютера;
- если у программиста нервное истощение;
- если последний убедился, что его старания бесполезны, т.к. все равно для 8-разрядного компьютера сверхвысокая точность недостижима (или достижима, но сверхвысокой ценой)!
К счастью, в астрологии, в отличие от навигации, не требуется такая точность. Плюс-минус 10 минут вполне достаточно. Поэтому надо будет всего лишь внести маленькую поправку в гелиоцентрическую долготу Сатурна, Юпитера, а по желанию и Нептуна и Урана. Эта точность будет почти неизменной не только для нашего столетия, но и, скажем, для 16-го века.
Календарь.
Период T говорит о том, сколько столетий прошло от начальной эпохи. Примем за начальную эпоху 31 декабря 1889 г., 12 часов 00 минут по Гринвичу. Рассчитаем, сколько суток и долей суток прошло с этого момента. Переведем их в столетия, поделив на 36525. Если наша дата приходится на один из прошлых веков, число будет отрицательным.
Определение интервала в сутках - дело довольно хлопотное, если браться за него "в лоб". Поэтому астрономы применяют так называемую систему юлианских дат. За точку отсчета взят средний Гринвичский полдень 1 января 4713 г. до н.э. В следующий полдень наступила юлианская дата 1, потом -2 и т.д. Таким образом, начальной эпохе соответствует ю.д. 2415020, а 1 февраля 1965 г. 11 ч. 46 мин. - 2438792.99. Для определения ю.д. существует формула:
JD=TRUNC(3 65.2 5*Y)+
TRUNC(30.60 01*(M+1)+
D+A+172 0994.5
Если месяц - январь или февраль, то Y=(год-1), М=(месяц+12). Иначе Y=году, M=месяцу.
D=4M^o+(4ac по Гринвичу+мин/6 0)/2 4
А=0, если дата дана по старому стилю. Иначе A=2-X+TRUNC(X/4), где X=TRUNC(Y/100)
Дальше просто: вычитаем из ю.д. 2415020 - получается число суток от начальной эпохи. Между прочим, в подавляющем большинстве программ, занимающихся определением дня недели и биоритмов, используется система юлианских дат. Так, если известна ю.д. в 0 часов по Гринвичу, то номер дня недели:
N = (JD+1.5) MOD 7.
0 - воскресение, 6 - суббота.
Примечание: Здесь мы применили две функции - TRUNC( ) и MOD, которых нет в стандартном Бейсике, хотя они имеются среди кодов калькулятора "Спектрума", поэтому надо дать некоторые пояснения.
Функция TRUNC выделяет целую часть дробного числа. Дотошный читатель может предположить, что то же самое делает и стандартная функция INT, но это не совсем так. Они совпадают только для положительных чисел, для отрицательных же они различаются.
Дело в том, что INT всегда округляет число "вниз", a TRUNC - всегда округляет к "нулю".
Так, если число равно 3.14, то INT (3.14) = 3 и TRUNC (3.14) тоже равно 3. С другой стороны, если число равно -3.14, то INT(-3.14) = -4, a TRUNC (-3.14) равно -3.
Задать в стандартном БЕЙСИКе функцию TRUNC можно так:
DEF FN T(X)=SGN(X)*INT(ABS X)
Теперь функция MOD(X,Y) - это остаток от деления X/Y:
DEF FN M(X,Y)=X-Y*INT(X/Y).
Итак, помимо блока с основными расчетами, в программу надо включить календарные вычисления. На входе дата и время по Гринвичу, на выходе - T (период) и JD (юлианская дата, она может еще пригодиться).
Ввод исходных данных.
Если не претендовать на очень уж товарный вид программы, то подойдет стандартное INPUT. Обозначим данные, которые должны быть получены в результате так: YE, МО, DA, HO, MI, LA, LO - год; месяц; день; часы; минуты; градусы широты (положительное число, если она северная, отрицательное, если южная); градусы долготы ("+" к западу, "-" к востоку, это может не соответствовать некоторым стандартам, но так удобнее).
Способ организации ввода, т.е. вводить ли поясное время, а потом пересчитывать его в Гринвичское или сразу последнее; записывать долготу в виде градусов/минут или в виде десятичной дроби, как вводить для нее знак - дело вкуса. Главное - разобраться во всем заранее, в противном случае появятся ошибки, которые трудно будет выловить. И, разумеется, надо своевременно сообщить пользователю о выбранном формате.
В англо-американских программах принято записывать не "23:15", а "11:15", затем "РМ" - "после полудня". Потом - номер часового пояса ("TIME ZONE"). 16 июня 1930 г. почти на всей территории бывшего СССР стрелки были переведены на 1 ч. вперед, что получило название "декретное время". А с 1980-го действует летнее. Поэтому к номеру часового пояса надо еще прибавлять 1 или 2 часа.
Координаты Москвы в большинстве "фирменных" программ записываются так: 037Е35; 55N45 ("N" означает север, "E" - восток).
Я вполне солидарен с программистами, которые считают хорошим тоном проверять, не ошибся ли пользователь. Широта не может выходить за пределы -90, +90 градусов. В феврале 1993 г. 28, а не 29 дней... Что еще хорошо бы учесть? В самом начале я писал о домах гороскопа. Сегодня чаще всего применяют 2 системы: Планидуса и Коха, и в том и в другом случае при расчете идет в ход тригонометрия. Так вот, если задана заполярная широта и одна из этих систем, происходит остановка с сообщением "INVALID ARGUMENT".
Определить, сколько дней в любом месяце любого года можно по формуле:
X=28+ABS(INT(MO/8)-(MO/2-INT(MO/ 2))*2)+2*SGN(ABS(MO-2))+ (1-SGN((Y/4-INT(YE/4))*4))*(1-SGN(ABS(MO -2)))
В тех же фирменных программах, как правило, имеется банк данных, в котором хранятся во-первых имена и даты рождения клиентов, а во вторых, координаты городов. Дисковая операционная система TR-DOS позволяет сделать то же самое на "Спектруме".
Астрологические дома.
Если полный оборот вокруг своей оси Земля совершает примерно за 24 часа, то каждые 4 минуты, или около того, над горизонтом восходит новый градус эклиптики. В астрологии этот участок называется Асцендентом и считается одним из самых важных факторов гороскопа, пожалуй даже более важным, чем солнечный знак (о котором идет речь на последних страницах газет). Примерно так же меняется кульминирующий градус или середина неба (она занимает самое высокое положение в небе по сравнению с остальной частью эклиптики). Противоположные им точки называются "десдендент" и "Основание неба", а все вместе - "углами гороскопа", вот вкратце их значения:
Асцендент - темперамент, внешность, самооценка, самые характерные черты личности и судьбы... вообще, по одному нему можно сказать очень многое о человеке. Вся астрология, если угодно - не что иное, как учение о больших и малых циклах. Асдендент - это начало (в этой точке планета восходят, "рождаются"), а по началу любого цикла можно спрогнозировать его дальнейшее развитие. Еще его можно сравнить с оглавлением книги, где коротко указано, чего от нее ждать.
Середина Неба - социальная реализация личности, карьера, общественное положение (здесь небесные тела кульминируют; Солнце пересекает это место в полдень, образно говоря, достигает расцвета), С.Н. в решительном, инициативном знаке Овна -человек готов идти на риск и борьбу, добиваясь профессионального успеха; в знаке Рыб -наоборот, пассивен, плывет по течению, зато шансы нередко сами приходят к нему в руки...
Десцендент - говорит о других людях (в противовес "Я" - Асценденту), с которыми приходится считаться. Прежде всего, это партнеры: коллеги, супруг.
Основание Неба - "источник": родительский дом, детство, родина, "семейное гнездо".
Асцендент - начало 1-го дома. О.Н. - 4-го, Десцендент - 7-го, C.K - 10-го. Границы остальных домов рассчитываются в разных системах по-разному. На протяжении 2 тысячелетий нашей эры одни системы уступали место другим. Сегодня широко известны несколько. Любопытно, что одна из них принадлежит перу Иоганна Молиториса де Кунигсберга (1436-1476), признанного математика, внесшего вклад в сферическую тригонометрию. Его имя, как и псевдоним - Региомонтанус - говорит о том, что родом он из нынешнего Калининграда.
Другая система приписывается т. Кампанелле... Я приведу систему Вальтера Коха (1895-1977). Считается, что она особенно хорошо работает в сфере бытовых прогнозов.
Расположение домов неодинаково не только в разное время, но и на разных широтах. Представьте себе апельсин, разрезанный наискосок.
От угла, под которым прошел нож, будет зависеть внешний вид содержимого. Помимо широты и времени суток для решения задачи надо знать еще период T и наклон эклиптики в эпоху (угол эпсилон, см. рис. 2) Обозначим его ЕС.
ЕС=23.4522 92-1.3 012 5Е-02*Т-1.63 88889Е-0 6*Т*T+5.03 05556Е-07, градусов.
Сперва определяется прямое восхождение Небесного меридиана RAMC, затем прямое восхождение пересчитывается в долготу (т.е. переходим от одной системы координат к другой) - получается С.Н. Находим асцендент. Наконец, зная "углы", одну за другой рассчитываем границы домов 11-го, 12-го, 2-го и 3-го. Остальные дома расположены в противоположных градусах. На выходе - массив H(1...12), дома.
"Дебют".
А.Г.Алексеев в одной из статей для "ZX-РЕВЮ" удачно назвал этим словом фрагменты, которые повторяются в разных программах - с них удобно начинать. В мой "дебют" входит несколько процедур:
1. "INTERVAL".
В астрономических вычислениях часто приходится иметь дело с большими углами. Например, угол ZM, рассчитанный по стандартной формуле, может оказаться равным 29345.672 градуса или 512.17858 радианам. Это то же самое, что 185.672 градуса или 3.2405876 радиан. Мало того, что последние два числа нагляднее. Бывают случаи, когда вычисляя тригонометрические функции больших углов, калькулятор "Спектрума" ошибается.
Попробуйте, например, PRINT SIN(512.17858).
Получится -.098815626.
Затем: PRINT SIN(3.2405876).
Результат: - .098833433! Между прочим, IBM показывает: -0,0988334620170090.
Десяток таких ошибок, и результат окажется столь далеким от точного, что духи-управители планет разгневаются на астролога, который им воспользуется... дабы избежать их немилости, предлагаю процедуру, которая приводит число A в интервал 0 - AMAX:
95 REM: вход А-число, AMAX-верхний предел
96 REM: X-результат, Y-локальная переменная 100 LET Y=INT(ABS(A)/AMAX)*AMAX
110 LET X=A-Y*(A>=AMAX)+(AMAX+Y)*(A<0): REM: Слава Джорджу Булю! 120 RETURN
2. "POLYNOME"
Как Вы заметили, ряд формул содержит умножение последовательности чисел на степени времени (Т). Процедуру для этого на Бейсике удобно оформить в виде функции пользователя:
129 REM POLYNOME
130 DEF FN P(A,B,C,T)=A+T*(B+C*T)
3. "ARCTANGENS(A/B) "
При использовании функции ATN возникает неопределенность: неизвестно, в каком квадранте лежит вычисленный угол. Его можно установить по знакам A и Y:
139 REM на входе A,B (радианы), на выходе X
140 IF NOT B THEN LET B=1E-6: REM на случай, если B=0 150 LET Y=ATN(A/B)
160 LET A=Y+(Y<0)*PI+(A<0)*PI
170 LET B=PI+PI: GOSUB 100: REM к процедуре INTERVAL, которая вернет результат X 180 RETURN
Кроме этих подпрограмм, я включаю в "дебют" объявление констант.
10 RESTORE 9000 20 READ ZE, ON, L6, К
30 LET S=PI/K: REM величина, приближающаяся к 1 радиану. Чтобы переводить градусы в радианы
и наоборот, удобнее всего умножать, и делить число на S, а не на (PI/180) 40 LET K2=K+K: REM 360 50 LET P2=PI+PI
9000 DATA 0,1,60,180: REM константа
Этот ход значительно сокращает программу. Все же, из соображений читаемости, я не буду использовать константы в примерах.
Неплохо было бы написать процедуры "дебюта" в кодах калькулятора и разместить их, например, в REM-строках. Параметры удобно передавать туда через функции пользователя. (См. "Элементарная графика", гл.3. или "Программирование в машинных кодах и на языке АССЕМБЛЕРа", ч. 2. гл. 4.6). Вопрос в том, как возвращать в Бейсик результат, он ведь находится на стеке калькулятора в интегральном представлении. Я знаю несколько способов. Увы, ни один из них не назовешь вполне изящным. Самый примитивный - завести особую переменную, допустим Q, затем написать на Ассемблере процедуру, которая будет искать в области Бейсик-переменных нашу Q и переносить в отведенные ей 5 ячеек памяти 5 байт с калькуляторного стека. Процедура, которую я привожу - это слегка измененная программа FIND из N-3,4 "ZX-РЕВЮ" за 1993 год ("Применение ассемблера для создания быстроработающих программ").
Вызов процедуры, которая ищет адрес переменной и помещает его в HL. После кода имени переменной идут 5 байтов, туда и надо переместить 5 байтов со стека калькулятора.
Чтобы выполнить команду LDIR, этот адрес должен быть в DE. Теперь надо найти начало стека калькулятора. Помещаем в HL
;содержимое системной переменной STKEND. Число находится в ячейках от ;(STKEND)-5 до (STKEND)-1.
DEC HL DEC HL DEC HL DEC HL
DEC HL ;Теперь в HL - адрес первого байта искомого числа.
LD ВС,5 ;Его длина - 5 байт.
LDIR ;Передаем его переменной.
RET
Поиск переменной.
Адрес системной переменной VARS.
Код буквы "Q"
Сравнение и выход, если переменная найдена. Ее адрес
Если 5-й бит в имени равен 0, то это либо массив,
либо символьная строка.
Следующие строки следует пропустить.
LD HL,(5С4В) LD A,51H CP(HL)
RET BIT
JR
INC
LD
INC
LD
ADD
INC
JR
Z
5,(HL)
NZ,X2 HL
E,(HL) HL
D,(HL) HL,DE HL X1
X2
Аналогичным способом проверяем, не является ли переменная многосимвольной, параметром цикла, наконец, если ни тем, ни другим - соответствует ли ее имя "Q".
NZ,X3 HL
A,(HL)
7,(HL)
Z,-6
DE,6
HL,DE
X1
7,(HL)
Z,-10
DE,13
HL,DE
X1
JR
INC
LD
BIT
JR
LD
ADD
JR
BIT
JR
LD
ADD
JR
Конструкция получится такая:
1. В БЕЙСИКе: Объявить переменную Q
LET Q=0
Объявить функцию пользователя:
DEF FN A(A,B,...)=USR адрес Вызывать ее:
LET X=FN A(...)
X здесь не имеет ровно никакого значения: он показывает лишь содержимое регистровой пары ВС. Важно то, что ответ содержится в Q.
Читателям, не имеющим опыта работы с калькулятором "Спектрума", предлагаю воспользоваться отлаженной процедурой INTERVAL. Перед тем, как вызывать ее, надо поместить параметры на калькуляторный стек. Первый параметр на стеке (сверху) - AMAX, следующий - число A (листинг 1).
При вычислении Y неплохо было бы воспользоваться командой mod/div, которой располагает калькулятор, но, к сожалению, она не во всех случаях работает корректно.
Комментарий. Содержимое стека. ;Поскольку будет использоваться операция ;">=", надо подготовить регистр B, поместив туда ее код (10) ;Включение калькулятора. ;Сохраняем AMAX в ячейке M0 ;и удаляем его со стека. ;Сохраняем A в ячейке M1 ;ABS(A)
;Вызов AMAX на стек
;ABS(A)/AMAX
;TRUNC(ABS(A)/AMAX)
;AMAX, TRUNC(ABS(A)/AMAX)
;AMAX*TRUNC(ABS(A)/AMAX)=Y
;Y - в ячейку M2
;A,Y
;A,A,Y
; AMAX, A, A, Y
;A >= AMAX ? Результат: 0 или 1
;Y, [0 ИЛИ 1], A, Y.
;Y*(A>=AMAX), A, Y.
;Y*(A>=AMAX)-A, Y
;Выход из калькулятора.
;Теперь надо подготовить регистр B к
;операции "<".
;AMAX на стек ;Y на стек ;AMAX+Y ;A на стек ;0 на стек ;A < 0 ? ;(AMAX+Y)*(A<0)
;A-Y*(A>=AMAX)+(AMAX+Y)*(A<0) - что и ;требовалось...
;Лучше не оставлять на стеке "мусора". ;В данной случае за результатом идет лиш-;нее число, оно удаляется. ;После чего - выход из процедуры. ;Результат на стеке.
Апология Бейсика.
Вот и зашла речь о наболевшем вопросе: на каком языке программировать? Теперь, когда структура программы более-менее ясна, самое время порассуждать на эту тему.
Не стоит торопиться с ответом: "конечно же, в кодах". И вот почему. При всех бесспорных преимуществах - скорости, экономии памяти, возможности создавать нестандартные эффекты - даже отлаженная машинно-кодовая программа останется как бы замороженной. Изменить какие-либо детали еще можно, но структуру... легче писать заново, чем резать по живому. Если же автор серьезно интересуется астрологией, его взгляды на предмет не стоят на месте. То и дело возникает желание попробовать новую методику или изменить привычную. То и дело говоришь себе: "Вот этого я раньше не учитывал, а надо бы".
Хочу подчеркнуть, структура, которую я описал, подходит для скромной программы, не претендующей на то, чтобы удовлетворить неслабые потребности профессионального астролога. А методов, помимо гороскопа рождения - хоть пруд пруди...
Совершенствуешься и в умении решать вычислительные задачи. Я, например, совсем недавно узнал, как проще всего рассчитывать орбиту Плутона (это запутанный вопрос в астрономии, поскольку Плутон был открыт сравнительно недавно). И до сих пор не нашел простого способа выполнять на восьмиразрядном "Спектруме" математические операции с двойной точностью, как, например, в GW-BASICe: задал "DEFDBL A-T" - и все переменные от A до T становятся числами с удвоенной разрядностью. Но рано или поздно, ведь, узнаю, быть может не без помощи "ZX-РЕВЮ". Кстати, не занимался ли кто-нибудь из читателей этим вопросом? Не думаю, чтобы это было архисложной задачей. В компьютере MSX, построенном на том же процессоре Z-80, все числа по умолчанию 16-разрядные! Это очень пригодилось бы в календарных расчетах (9-я цифра в юлианской дате не обязательна, но ее присутствие повысило бы точность).
код |
Мнемоника |
6 |
|
10 |
LD B,0A |
239 |
RST 28H |
192 |
store M0 |
2 |
delete |
193 |
store M1 |
43 |
abs |
224 |
recall M0 |
5 |
divide |
50 |
truncate |
224 |
recall M0 |
4 |
multiply |
194 |
store M2 |
225 |
recall M1 |
49 |
duplicate |
224 |
recall M0 |
10 |
>= |
226 |
recall M2 |
4 |
multiply |
3 |
subtract |
56 |
end calc |
6 |
|
13 |
LD B,0B |
239 |
RST 28H |
224 |
recall M0 |
226 |
recall M2 |
15 |
add |
225 |
recall M1 |
160 |
const zero |
13 |
< |
4 |
multiply |
15 |
add |
1 |
exchange |
2 |
delete |
56 |
end calc |
201 |
RET |
... Еще один "минус" кодовой программы: мониторы-отладчики, по крайней мере, те, что мне известны, не "берут" кодов калькулятора. Попробуйте сами и увидите такую фантасмагорию! Дабы уменьшить мучения, мне пришлось делать специальный отладчик; он позволял писать мнемониками и макро-командами, переводил числа в упакованную форму -вобщем, выполнил всякую рутину, но при всем этом был лишен удобств пакета GENS/MONS. Другое дело, игра - там калькулятор используется не так часто, задачи иные, а потому и подход не тот.
Недостатки стандартного БЕЙСИКа общеизвестны. Ладно, пускай, вычисления. Хуже то, что ради экономии памяти приходится идти на уловки, делающие порой программу нечитаемой. Отсутствуют некоторые команды, очень полезные для создания хорошей структуры, типа ON...GOTO, зато спектрумовский БЕЙСИК один из самых демократичных. Как-то я попробовал на пижонском компьютере MSX написать нечто вроде: GOSUB(VAL"1000" AND X=SGN PI)+(VAL"2000" AND X=BIN).
Беднягу, кажется, стошнило...
Есть ли другие варианты? Первое, что приходит в голову - ПАСКАЛЬ, однако, повозившись недельку-другую с версией фирмы Hisoft, приходишь к выводу, что авторы ее заботились в первую очередь о том, как облегчить себе жизнь. Вещественные числа там имеют всего 6 значащих цифр (*/5). Чтобы получить результат такой же точный, как на БЕЙСИКе, приходится проделывать разные арифметические трюки. Из-за этого и по другим причинам катастрофически не хватает памяти. Нет полной ясности относительно того, как Паскаль взаимодействует с системой - распространенные руководства говорят об этом крайне скупо. Так что далеко не все машинно-кодовые фрагменты, которые пытаешься вставить в программу, используя оператор INLINE - особенно, если в них есть обращения к ПЗУ, дают ожидаемые результаты.
Программу написать можно, в этом я убедился. Работать она будет исключительно быстро, читать ее текст и отлаживать - одно удовольствие - ПАСКАЛЬ есть ПАСКАЛЬ. Но считать она будет максимум в рамках двух столетий, делать сможет очень немногое... и никаких красот. Может быть, есть смысл сделать на Паскале графический табель-календарь, показывающий, как планеты движутся в течение, скажем, заданного месяца -благо, разрешение экрана не настолько высоко, чтобы на графике были видны минуты, зато важно, чтобы расчеты выполнялись быстро.
С другой стороны, ничуть не худшего эффекта можно добиться с помощью TOBOS-FP, пожалуй, единственного из Бейсик-компиляторов, который оправдывает надежды. С ним пришлось немало повозиться. Часть того, что о нем написано - не только в "таблоидных" инструкциях, но и в такой серьезной книге, как "Диалекты Бейсика для ZX-SPECTRUM" -оказалось неточным. А кое о чем важном там вообще не сказано, например, о том, что объектный код является релоцируемым. Несмотря на то, что непосредственно после компиляции он располагается с адреса 24000, его можно загружать и запускать с другого адреса - скажем, с 26000, расположив ниже собственные кодовые подпрограммы. Лишь бы он не затирал рабочие процедуры и стек компилятора.
Напомню, что для компиляции больших программ в TOBOSе предусмотрен режим "компиляции с уничтожением исходного текста". Оказалось, этот режим не работает с дисковой системой, которая сдвигает БЕЙСИК вверх. Так что приходится инициализировать стандартную SINCLAIR-систему страшной командой RANDOMIZE USR 0, загружать с ленты компилятор и исходный текст, компилировать, записывать полученный объектный код на ленту, потом загружать его с ленты в новый адрес и только после этого переписывать на диск (*/6). Удовольствия мало. Тем не менее, мне удалось откомпилировать таким образом довольно объемную программу, включавшую помимо расчетов еще и графику, сервис, разные виды таблиц - большую часть того, что необходимо профессиональному астрологу -и знакогенератор, печатающий 60 символов в строке. Больше всего поразила скорость. Хотите верьте, хотите нет, она была почти такой же, как у программы "PRIMA", написанной Б.Богдановым для IBM на Турбо-Паскале!
Однако, увы, за все приходится платить. Недостаток TOBOSa - пониженная точность расчетов (он работает с 7-значными числами); памяти, несмотря на все, он съедает много: хочешь добавить в программу какой-нибудь милый пустячок - не тут-то было...
Вариант, который мне кажется почти идеальным для некоммерческой астрологической программы - это БЕТА-БЕЙСИК. О его преимуществах было достаточно написано в "ZX-РЕВЮ". Он как будто нарочно создан для подобных программ. Позже пойдет речь об уравнении Кеплера. Оно очень красиво вписывается в структуру DO...UNTIL. Оператор ON...GOSUB в паре мест просто необходим. Функции SINE, COSE, знакогенератор 4/7 пикселов, возможность гибко манипулировать сеткой графических координат, окна - все это помогает наглядно иллюстрировать результаты.
Параметры орбит.
Я уже писал, что для расчета координат небесных тел нужно знать во-первых, период T, а во-вторых, параметры их орбит в начальную эпоху T0. Для каждой из планет таких параметров 6: средняя аномалия, эксцентриситет, большая полуось, долгота перигелия, долгота восходящего узла и наклон орбиты. Обозначим их переменными ZM, ZE, ZA, ZW, ZQ, ZI.
Допустим, дата у нас 24 июня 1976 г. Время - 0 ч. по Гринвичу. Тогда юлианская дата:
JD= 2443683. 5,
а
T=(2443683.5-2415020)/36525 = 0.78476386.
Найдем среднюю аномалию ZM для Меркурия. В таблице даны три числа:
102,27938,
149472,52,
7Е-6.
Обозначим их X1, X2, X3.
ZM = X1+X2*T+X3*T*T
(или FN P(X1,X2,X3, T))=117402.91 градусов = 42.91004 градусов = 0,74892085 радиан. Точно так же находим остальные значения.
Все величины, кроме ZA (астрономические единицы) и ZE нужно перевести в радианы!
Поскольку каждая орбита представляет собой эллипс, данные параметры описывают именно эту геометрическую фигуру, а также ее положение относительно орбиты Земли.
Положения Солнца и планет.
Средняя аномалия ZM показывает, где бы находилась планета, если бы она двигалась равномерно по кругу. Зная ее и эксцентриситет эллипса, можно найти эксцентрическую аномалию EA и истинную аномалию ZV, т.е. перевести планету на эллипс. Для определения ЕА служит уравнение Кеплера:
EA=ZE*SIN(EA)=ZM.
Очевидно, решить его не так-то просто, Но компьютеру все нипочем! Вот как это делается.
197 REM HELIO1
198 REM
199 REM Уравнение Кеплера. На входе ZE,ZM. На выходе ЕА
200 LET EA=ZM: REM начальное значение ЕА
202 LET EPSYLON=1E-6: REM задаем точность
205 REM начало цикла
210 LET DELTA=EA-ZE*SIN(EA)-ZM: REM невязка.
220 LET EA=EA-DELTA/(1-ZE*COS(EA)): REM очередное значение ЕА
230 IF ABS(DELTA)>EPSYLON THEN GOTO 210: REM к началу цикла, если не достигнута требуемая точность
А вот как то же самое выглядит в кодах калькулятора (к моменту вызова этой процедуры на вершине калькуляторного стека должно находиться ZM, за ним - ZE. Сама процедура может быть расположена в любом месте оперативной памяти). См. листинг-2.
Листинг-2
Дес. код |
Мнемоника Комментарий |
239 |
RST28H |
Вкл. калькулятора |
195 |
store M3 |
Начальное значение ЕА, т.е. ZM - |
|
|
в 3-ю ячейку памяти |
195 |
store M4 |
ZM в 4-ю ячейку. |
1 |
exchange |
Меняем местами ZM и ZE |
197 |
store M5 |
ZE в 5-ю ячейку |
2 |
delete |
Удаляем верхнее число со стека. |
|
|
Это начало цикла. |
49 |
duplicate |
Копирование вершины стека. |
229 |
recall M5 |
Вызываем ZE |
1 |
exchange |
Теперь стек выглядит так: ЕА, ZE, ЕА |
31 |
sin |
sin(EA), ZE, EA |
4 |
multiply |
ZE*sin(EA), EA |
3 |
subtract |
EA-ZE*sin(EA) |
226 |
recall M4 |
вызываем ZM |
3 |
Subtract |
EA-ZE*sin(EA)-ZM, т.е. невязка DELTA. |
49 |
duplicate |
DELTA, DELTA |
161 |
const one |
1, DELTA, DELTA |
227 |
recall M3 |
ЕА на стек |
32 |
cos |
COS(EA) |
229 |
recall M5 |
ZE на стек |
4 |
multiply |
cos(EA)*ZE |
3 |
subtract |
1-cos(EA)*ZE, DELTA, DELTA |
5 |
divide |
DELTA/(1-cos(EA)*ZE),DELTA |
227 |
recall M3 |
EA на стек |
1 |
exchange |
|
3 |
subtract |
ЕА минус последний результат. Получено |
|
|
очередное значение ЕА |
195 |
store M3 |
сохраняем его в 3-й ячейке |
1 |
exchange |
меняем местами ЕА и DELTA |
42 |
abs |
abs(DELTA) |
52 |
|
Это ввод |
221 |
|
числа |
6 |
|
1Е-5 в упакованной форме |
55 |
|
(допустимая |
189 |
|
величина |
5 |
|
невязки) |
3 |
subtract |
abs(DELTA)-^-6 |
55 0
0 |
gt zero |
>0? |
225 |
jump true-31 Если да, то переход к началу цикла |
56 |
end calc. |
Выключение калькулятора. |
201 |
RET |
Результат на вершине стека. |
Теперь можно найти истинную аномалию ZV:
235 REM истинная аномалия. На входе ЕА, ZE, ZA (большая полуось).
240 LET A=ZA*SIN(EA)*SQR(1-ZE*ZE)
250 LET B=ZA*COS(EA)-ZE)
260 GOSUB 140: REM к процедуре ARCTANGENS
270 LET ZV=X
Затем радиус-вектор, ZR:
275 REM радиус-вектор. На входе ZA, ЕА, ZE 290 LET ZR=ZA*(1-ZE*COS(EA))
Таким образом, величины ZR, ZV найдены, что и было намечено в первоначальной схеме. На этом можно было бы и закончить подпрограмму HELIO1, однако, здесь же удобнее вычислить еще одну промежуточную величину, используя очередной параметр орбиты. Обозначим ее ZU.
290 LET A=ZV+ZW: LET AMAX=PI+PI
300 GOSUB 100: REM к процедуре INTERVAL
310 LET ZU=X
320 RETURN: REM конец подпрограммы HELIO1
Долготу солнца (SL) найти теперь просто. В случае с ним ZU -это долгота Земли. Так что SL=ZU+PI. Полученную величину надо "прогнать" через процедуру INTERVAL. С планетами сложнее. Вот как выглядит расчет для них.
321 REM HELIO2
322 REM гелиоцентрические координаты планет.
323 REM на входе ZQ,ZI,ZU, на выходе ZL, ZB - гелиоц. широта и долгота
324 REM
325 REM *** ZI.
330 LET A=COS(ZI)*sin(ZU):LET B=COS(ZU) 340 GOSUB 140: REM к процедуре ARCTANGENS 350 LET A=X+ZQ: LET AMAX=PI+PI 360 GOSUB 100: REM к процедуре INTERVAL 370 LET ZL=X
380 LET ZB=ASN(SIN(ZU)*SIN(ZI)) 390 RETURN
395 REM GEOCENTRIC
396 REM переход от гелио- к геоцентрическим долготе и широте (LO,LA)
397 REM на входе: ZR, ZL, ZB, а также SR, SL - радиус-вектор и долгота Солнца.
398 REM Z, А, M, С, N, D - ЛОкальные переменные
399 REM
400 LET A=ZL-SL:LET M=ZR*COS(ZB):LET C=ZR*SIN(ZB) 410 LET N=M*SIN(A): LET D=M*COS(A)+SR
415 REM *** LO
420 LET A=N: LET B=D: GOSUB 140:REM ARCTANGENS 425 LET A=X+SL: LET B=PI+PI:GOSUB 100: REM INTERVAL 430 LET LO=X
435 REM *** расстояние от Земли 440 LET Z=SQR(M*N+D*D+C*C) 445 REM *** LA 450 LET LA=ASN(ZR/Z*SIN(ZB)) 460 RETURN
Осталось перевести LO и LA из радиан в градусы и передать массиву A( ).
Луна.
Вместе с Солнцем и Асцендентом, Луна - важнейший показатель в любом гороскопе, а в женском часто самый главный. Достаточно вспомнить, с чем она связывалась в представлениях разных народов, чтобы понять ее значение в астрологии. В древних религиях ее почитаем, как богиню зачатий и материнства. Если Солнце - активное, мужское начало, то Луна - уравновешивающая его пассивная, женская сторона природы, инстинкт самосохранения, чувства... Известно, что лунные циклы оказывают влияние на многие процессы в животном и растительном мире, на здоровье человека. Древние славяне лечились, выполняли земледельческие работы и даже солили капусту сообразно с определенными фазами Луны.
Луна движется через Зодиак быстро, проходя полный круг за месяц, а один знак -примерно за двое суток. Точно вычислить ее положение в заданный момент времени непросто - слишком много факторов приходится учитывать. На каждом шагу надо вносить поправки. Целиком все занимает пару книжных страниц. Тем, кто желает вычислить положение Луны с точностью до минуты, рекомендую обратиться к книге Ж.Месса "Астрономические формулы для калькуляторов". Здесь же приведу упрощенный расчет, занимающий немного меньше места и дающий точность плюс-минус 10 минут дуги. Это не так страшно, как может показаться на первый взгляд - ведь видимый диск Луны "растянут" на целых 30 минут, полученная же долгота указывает положение центра диска.
495 REM MOON
496 REM на входе T,JD,SL,SN. На выходе X,Y,ZQ - долгота, широта Луны и долгота Лунного узла
498 REM C,D - вспомогательные локальные переменные
499 REM параметры орбиты
500 LET D=JD-2415020: REM число дней, прошедших от начальной эпохи 505 DIM P(5): REM для поправок
510 LET ZL=270.434164+D*13.176397:REM средняя долгота 520 LET ZW=334.32956+D*0.11140408: REM долгота перигея 530 LET ZM=ZL-ZW: REM средняя аномалия 540 LET ZQ=259.18328-D*0.052953923 REM долгота узла 543 LET ZI=5.145396: REM наклон орбиты
545 REM приведение параметров в интервал 0...360 и перевод в радианы. 550 LET AMAX=350
500 LET A=ZM: GOSUB 100:LET ZM=X*(PI/180)
570 LET A=ZL: GOSUB 100:LET ZL=X*(PI/180)
580 LET A=ZQ: GOSUB 100:LET ZQ=X*(PI/180)
590 LET ZI=ZI*(PI/180)
595 REM расчет основных поправок
600 LET C=ZL-SL
610 LET P(1)=1.2739*SIN(C+C-M)
620 LET P(2)=0.1858*SIN(SM)
630 LET P(3)=0.37*SIN(SM)
640 LET ZM=ZM+(P(1)-P(2)-P(3))*(PI/180)
650 LET P(4)=6.2686*SIN(ZM)
660 LET P(5)=0.214*SIN(ZM+ZM)
670 LET ZL=ZL+P(1)+P(4)-P(8)+P(5))*(PI/180)
680 LET ZL=ZL+0.6583*SIN(2*ZL-SL))*(PI/180)
690 LET ZQ=ZQ-0.16*SIN(SM)*(PI/180)
700 LET C=ZL-ZQ
705 REM *** долгота
710 LET A=SIN(C)*COS(ZI): LET B=COS(C) 720 GOSUB 140: REM ARCTANGENS
725 LET A=X+ZQ: LET AMAX=PI+PI: GOSUB 100: REM INTERVAL 730 REM *** широта
740 LET Y=ASN(SIN(C)*SIN(C)*SIN(ZI))
750 LET X=X/(PI/180): LET Y=Y/(PI/180): LET ZQ=ZQ/(PI/180) 760 RETURN
Разумеется, вместо (PI/180) лучше использовать константу S, которая равна 1.7453292E-2, т.е. приблизительно 1 радиану. А массив P(5) объявить в начале программы.
Поправки на возмущения планетных орбит.
Больше всего отклоняются от правильного в геометрическом смысле движения Сатурн и Юпитер. К их средним долготам (ZL) надо прибавить: Для Юпитера:
((0.3314-0.0103*P(1))*SIN(P(4))-
0.0644*P(1)*COS(P(4)))*(PI/180) Для Сатурна:
((0.1609*P(1)-0. 0105)*COS(P(4))+
(0.0182*P(1)+0.8142)*SIN(P(4))-
0.1488*SIN(P(5))-0.0408*SIN(P(5)+
P(5))+0.0856*SIN(P(5))*COS(P(3))+
0.0813*CQS(P(5))*SIN(P(3)))*(PI/180).
где:
P(1)=T/5+0.1
P(2)=(237.47555+3034.9061*T)*(PI/180) P(3)=(265.91650+1222.1139*T)*(PI/180) P(4)=5*P(3)-2*P(2) P(5)=P(3)-P(2)
Как всегда, полученные величины лучше привести в интервал 0...PI*2.
Расчет астрологических домов по системе В.Коха.
885 REM
886 REM KOCH HOUSES 087 REM
885 REM на входе: GMT-время по Гринвичу в часах и десятых долях часа, LO - долгота в
градусах, "-" к востоку. LA-широта в градусах, "-" к югу, ЕС- наклон эклиптики в градусах, T. Выход: массив H(1...12) - эклиптическая доля гота границ домов.
892 REM
893 REM Прямое восхождение меридиана
894 REM
900 LET RAMC=FN P(6.6460656,2400.0513,2.581E-5,T):REM POLYNOME 910 LET A=(RAMC+GMT)*15-LO 920 LET LA1=LA*(PI/180)
930 IF LA>(90-EC) THEN LET A=RAMC+180: LET LA1=-LA1
940 LET A=RAMC: LET AMAX=360:GOSUB 100: LET RAMC=X: REM INTERVAL
945 LET RAMC=RAMC*(PI/180): LET EC1=EC*(PI/180):REM перевод в радианы
950 REM середина неба
960 LET A=SIN(RAMC):LET B=COS(RAMC)*COS(EC1): GOSUB 140: REM ARCTANGENS
965 LET MC=X
970 REM Асдендент
960 LET A=COS(RAMC):LET B=-(SIN(EC)*TAN(LA1)*COS(EC)*SIN(RAMC):GOSUB 140 985 LET AS=X
990 LET L=1: LET X=AS:GOSUB 1140 993 LET L=10: LET X=MC:GOSUB 1140 995 REM Вершины домов
1000 LET X0=SIN(EC1)*TAN(LA1)/COS(EC1)*SIN(RAMC) 1010 RESTORE 1020
1020 DATA 0.52350879,1.0471976,2.0943952,2.617994
1030 LET X4=-3
1040 FOR J=1 TO 4
1050 READ X: LET X4=X4+1
1060 IF X4=0 THEN LET X4=1
1070 GOSUB 1100
1080 NEXT J
1090 RETURN
1095 REM вычисления
1100 LET X3=RAMC+X+ATN(X0/SQR(1-X0*X0))*X4/3
1110 LET A=SIN(X3):LET B=COS(X3)*COS(EC1)-TAN(LA1)*SIN(EC1)
1120 LET L=L+1: IF L>12 THEN LET L=L-11
1130 GOSUB 140: REM ARCTANGENS
1140 LET H(L)=X/(PI/180):LET A=X+PI: LET AMAX=PI+PI:GOSUB 100: REM INTERVAL 1150 LET H(L+6-12*(L>7))=X/(PI/180): REM противоположный дом 1160 RETURN
Управляющая программа.
Поскольку для ряда простых расчетов я давал лишь формулы, то нет смысла подробно описывать главный блок, показывая номера строк для переходов, важнее сам алгоритм. Выглядит он так:
1) Ввести исходные данные. Проверить, не допустил ли пользователь ошибку. Если да, то начать сначала. Распечатать эти данные на экране и спросить у него самого, все ли в порядке. Если нет, начать сначала. Перевести все в формат, который будет использовать программа.
2) Рассчитать юлианскую дату, соответствующую заданной дате и времени, вычислить период Т.
3) Рассчитать по T и данным из таблицы исходные параметры орбиты Солнца: ZM, ZE,
ZA, ZW. Найти положение Солнца (см. HELIO1). Сохранить среднюю долготу, радиус-вектор и среднюю аномалию Солнца в особых переменных.
4) Найти положение Луны и Северного Лунного узла - M(1,1), M(2,1), M(11,1), M(12,1)
5) Вычислить значения P(1..5), которые понадобятся при расчете поправок на долготы Сатурна и Юпитера
6) Для планет:
Цикл для J от 2 до 9
Определить ZM, ZE, ZA, ZW, ZQ, ZI.
Найти гелиоцентрические координаты. Если J=5 или 6 (Юпитер, Плутон), вычислить поправки и прибавить их к ZL.
Перейти к геоцентрическим координатам.
Перевести результат в градусы и присвоить массиву M( ).
7) Найти наклон эклиптики ЕС.
8) Рассчитать границы домов H( ).
9) Вывести результат на дисплей или принтер.
10) Вернуться к началу.
Я намеренно не касался пункта (9) только потому, что тема эта слишком обширна. Сюда входят вопросы дизайна и графики, форматирования чисел... возможно даже несколько нестандартного прерывания, если Вы желаете, чтобы в углу экрана имелись часы - для всего этого потребовалась бы отдельная статья. Хотелось бы только обратить внимание читателей на следующее: все результаты, хранящиеся в массивах H( ) и M( ) -вещественные числа, долготы лежат в диапазоне 0...360 градусов. Выводить на экран лучше градусы и минуты. Если же придерживаться астрологической традиции, то надо указывать знак Зодиака. Так, например, 338.25002 преобразуется в стринг "08:04 Рыб". Один из возможных способов вывода представлен на рис.3 (получен из зарубежной программы фирмы Protheus software).
В заключение прошу извинить меня за слишком поверхностное изложение астрономии. Всем, кому такой уровень покажется недостаточным, горячо рекомендую книги: Ж.Меес - "Астрономические формулы для калькуляторов", М., Мир, 1988; П. Дэффет-Смит - "Практическая астрономия с калькулятором", М., Мир, 1982. Что же касается тонкостей астрологии, то среди моря доступной сегодня литературы я бы выделил учебники Сефариала, Джорджа Ллевеллина, Ф. Сакоян, Хет Монстера и философские работы Редиара.
* * *
КОММЕНТАРИИ "ИНФОРКОМа".
/1. "Эклиптика" - правильнее говорить - "плоскость эклиптики".
Это плоскость, которая совпадает с плоскостью орбиты земли. Поскольку Земля вращается вокруг Солнца, то естественно, что Солнце всегда лежит в этой плоскости.
/2. Геоцентрические координаты - это координаты в системе, в которой начало отсчета привязано к центру Земли. Эклиптические геоцентрические координата -координаты в системе, в которой начало координат совпадает с центром Земли, а главная плоскость XY совпадает с плоскостью эклиптики.
/3. Поскольку Солнце естественно всегда лежит в плоскости эклиптики, то его широта в эклиптической геоцентрической системе координат всегда равна нулю.
/4. Гелиоцентрическая система координат - в отличие от геоцентрической связана не с Землей, а с Солнцем. Центр этой системы находится в центре Солнца, а главная плоскость XY - совпадает с плоскостью эклиптики.
/5. Это действительно так, но надо признать, что это не столько облегчает жизнь создателям ПАСКАЛя, сколько пользователям. Ведь благодаря этому в ПАСКАЛе НР4Т удается использовать только четыре восьмиразрядных регистра для хранения действительных чисел (вместо пяти). Это значительно упрощает интерфейс программ на
ПАСКАЛе с собственными процедурами пользователя в машинном коде. Из м/к легко находятся и эксплуатируются переменные ПАСКАЛЯ.
/6. По-видимому, используя информацию, приведенную в статье Алексеева А.Г. "Секреты TRDOS" (см. ZX-РЕВЮ N1,2 за 1993 г.) этот недостаток компилятора можно было бы и устранить. Не исключено, что кто-то это уже и сделал.
|
Справочные таблицы для расчетов элементов орбит планет. |
|
|
|
SUN |
|
|
|
SATURN |
|
|
ZM |
358.47583 |
35999.05 |
-.00015 |
|
ZM |
175.46622 |
1221.5515 |
-.000502 |
ZE |
.01675104 |
-.0000418 |
-1.26E-7 |
|
ZE |
.05589232 |
-.0003455 |
-7.28E-7 |
ZA |
1.0000002 |
0 |
0 |
|
ZA |
9.554747 |
0 |
0 |
ZV |
101.22083 |
1.71918 |
.00045 |
|
ZV |
338.3078 |
1.0852207 |
.00097854 |
|
|
|
|
ZQ |
112.79041 |
0.8731951 |
-.00015218 |
|
MERCURY |
|
|
ZI |
2.492519 |
-.0039189 |
-.00001549 |
ZM |
102.27938 |
149472.52 |
7E-6 |
|
|
|
|
ZE |
0.20561421 |
.00002046 |
-3E-8 |
|
URANUS |
|
|
ZA |
0.3870986 |
0 |
0 |
|
ZM |
72.64878 |
428.37911 |
.000079 |
ZV |
28.753753 |
0.3702806 |
.0001208 |
|
ZE |
.0463444 |
-.00002658 |
7.7E-8 |
ZQ |
47.145944 |
1.1852083 |
.0001739 |
|
ZA |
19.21814 |
0 |
0 |
ZI |
7.002881 |
.0018608 |
-.0000183 |
|
ZW |
99.071581 |
0.985765 |
-.0010745 |
|
|
|
|
ZQ |
73.477111 |
0.4986678 |
.0013117 |
|
VENUS |
|
|
ZI |
0.772464 |
.0006253 |
.0000395 |
ZH |
212.60322 |
58517.804 |
.001286 |
|
|
|
|
ZE |
.00682069 |
-.00004774 |
9.1E-8 |
|
NEPTUNE |
|
|
ZA |
0.7233316 |
0 |
0 |
|
ZM |
37.73063 |
218.46134 |
-.00007 |
ZU |
54.384186 |
0.5081861 |
-.0013664 |
|
ZE |
.00899704 |
6.338-6 |
-2E-9 |
ZQ |
75.779647 |
0.89985 |
.00041 |
|
ZA |
30.10957 |
0 |
0 |
ZI |
3.393631 |
.0010058 |
-1E-6 |
|
ZW |
276.04597 |
0.3256394 |
.00014095 |
|
|
|
|
ZQ |
130.68139 |
1.098935 |
.00024987 |
|
MARS |
|
|
ZI |
1.779242 |
-.0095436 |
-9.1E-6 |
ZM |
319.51913 |
19139.855 |
.000181 |
|
|
|
|
ZE |
.0933129 |
.000092064 |
-7.75-8 |
|
PLUTO |
|
|
ZA |
1.5236883 |
0 |
0 |
|
ZM |
229.94722 |
144.91306 |
0 |
ZW |
285.43176 |
1.0697667 |
.0001313 |
|
ZE |
.24864 |
0 |
0 |
ZQ |
48.786442 |
0.7709917 |
-1.4E-6 |
|
ZA |
39.51774 |
0 |
0 |
ZI |
1.850333 |
-.000675 |
.0000126 |
|
ZW |
113.52139 |
0 |
0 |
|
|
|
|
ZQ |
108.95444 |
1.39601 |
.00031 |
|
JUPITER |
|
|
ZI |
17.14678 |
0 |
0 |
ZM |
225.32833 |
3034.692 |
-.000722 |
|
|
|
|
Z8 |
.04833475 |
.00016418 |
-4.876E-7 |
|
|
|
|
ZA |
5.2025613 |
0 |
0 |
|
|
|
|
ZV |
273.27756 |
0.5994317 |
.00070405 |
|
|
|
|
ZQ |
99.443414 |
1.01053 |
.00035222 |
|
|
|
|
ZI |
1.308736 |
-.0056961 |
3.9E-6 |
|
|
|
|