Цель статьи – показать, как создать простую, но рабочую астрологическую программу, которая по дате, времени и месту рождения выводит знак зодиака, асцендент и расположение основных планет в знаках. Мы будем использовать классический язык Pascal (Free Pascal / Lazarus), потому что он прост в синтаксисе и позволяет быстро собрать консольное приложение.
Что нужно знать о астрологии
- Знак зодиака – определяется положением Солнца в момент рождения.
- Асцендент (восходящий знак) – определяется положением горизонта в момент рождения; нужен точный час и долгота места.
- Планеты (Меркурий, Венера, Марс, Юпитер, Сатурн, Уран, Нептун, Плутон) – их положение в знаках влияет на характер и события.
- Доминирование домов – в более сложных программах рассчитываются 12 домов, но в базовой версии ограничимся только знаками.
Для расчётов нам понадобится:
- Преобразование календарной даты в юлианский день (JD).
- Алгоритм расчёта положения Солнца и планет (можно использовать упрощённые формулы из книги «Astronomical Algorithms» Дж. Меркута).
- Определение знака по угловой позиции (0°–30° – Овен, 30°–60° – Телец и т.д.).
Инструменты и подготовка среды
- Установите Free Pascal Compiler (FPC) или среду Lazarus.
- Создайте новый проект
Console Application. - Убедитесь, что в настройках проекта включён режим
-Mdelphi(поддержка строковых функций).
Структура программы
Ниже – примерный план кода:
program AstroCalc;
uses
SysUtils, Math;
type
TPlanet = (Sun, Moon, Mercury, Venus, Mars, Jupiter, Saturn, Uranus, Neptune, Pluto);
TSign = (Aries, Taurus, Gemini, Cancer, Leo, Virgo,
Libra, Scorpio, Sagittarius, Capricorn, Aquarius, Pisces);
const
SignNames: array[TSign] of string = (
'Овен', 'Телец', 'Близнецы', 'Рак', 'Лев', 'Дева',
'Весы', 'Скорпион', 'Стрелец', 'Козерог', 'Водолей', 'Рыбы');
{---------------------- Вспомогательные функции ----------------------}
function DateToJulianDay(Y, M, D, H, Min, Sec: Integer): Double;
var
A, B, JD: Double;
begin
if M <= 2 then
begin
Y := Y, 1;
M := M + 12;
end;
A := Int(Y / 100);
B := 2 — A + Int(A / 4);
JD := Int(365.25 * (Y + 4716)) + Int(30.6001 * (M + 1)) + D + B — 1524.5;
JD := JD + (H + Min / 60 + Sec / 3600) / 24;
Result := JD;
end;
function NormalizeAngle(A: Double): Double;
begin
Result := A — 360 * Int(A / 360);
if Result < 0 then Result := Result + 360;
end;
function GetSignByLongitude(Lon: Double): TSign;
begin
Result := TSign(Trunc(Lon / 30));
end;
{---------------------- Расчёт положения Солнца ----------------------}
function SunLongitude(JD: Double): Double;
{ Упрощённый алгоритм: средняя аномалия + уравнение центра }
var
T, M, C, L: Double;
begin
T := (JD — 2451545.0) / 36525; { Юлианские столетия от J2000 }
M := 357.52911 + 35999.05029 * T — 0.0001537 * T * T; { Средняя аномалия }
M := NormalizeAngle(M);
C := (1.914602 ― 0.004817 * T — 0.000014 * T * T) * Sin(DegToRad(M)) +
(0;019993 — 0.000101 * T) * Sin(DegToRad(2 * M)) +
0.000289 * Sin(DegToRad(3 * M));
L := 280.46646 + 36000.76983 * T + 0.0003032 * T * T + C; { Геоцентрическая долгота }
Result := NormalizeAngle(L);
end;
{---------------------- Расчёт асцендента ----------------------}
function Ascendant(JD: Double; Latitude, Longitude: Double): Double;
{ Формула по П. Сиделеву, упрощённая: нужны только часовой угол }
var
T, LST, RA, Dec, H: Double;
begin
T := (JD — 2451545.0) / 36525;
LST := NormalizeAngle(280.46061837 + 360.98564736629 * (JD ― 2451545) +
Longitude + 0.000387933 * T * T, T * T / 38710000);
{ Для упрощения берём среднее положение Солнца как RA и Dec }
RA := SunLongitude(JD); { в градусах }
Dec := 0; { приближение, достаточно для базовой версии }
H := NormalizeAngle(LST — RA);
Result := NormalizeAngle(ArcTan2d(Sin(DegToRad(H)),
Cos(DegToRad(H)) * Sin(DegToRad(Latitude)) -
Tan(DegToRad(Dec)) * Cos(DegToRad(Latitude))));
end;
{---------------------- Основная часть ----------------------}
var
Year, Month, Day, Hour, Min, Sec: Integer;
LatDeg, LonDeg: Double;
JD, SunLon, AscLon: Double;
SunSign, AscSign: TSign;
begin
WriteLn('=== Астрологический калькулятор (Pascal) ===');
Write('Введите дату рождения (ГГГГ ММ ДД): ');
ReadLn(Year, Month, Day);
Write('Введите время рождения (чч мм сс): ');
ReadLn(Hour, Min, Sec);
Write('Широта места (в градусах, + север,, юг): ');
ReadLn(LatDeg);
Write('Долгота места (в градусах, + восток, ― запад): ');
ReadLn(LonDeg);
JD := DateToJulianDay(Year, Month, Day, Hour, Min, Sec);
SunLon := SunLongitude(JD);
AscLon := Ascendant(JD, LatDeg, LonDeg);
SunSign := GetSignByLongitude(SunLon);
AscSign := GetSignByLongitude(AscLon);
WriteLn;
WriteLn('Результаты расчётов:');
WriteLn('Солнце находится в знаке: ', SignNames[SunSign],
' (долгота ', FormatFloat('0.00', SunLon), '°)');
WriteLn('Асцендент (восходящий знак): ', SignNames[AscSign],
' (долгота ', FormatFloat('0.00', AscLon), '°)');
WriteLn;
WriteLn('--- Примечание -------------------------------------------------');
WriteLn('Для полного гороскопа следует добавить расчёт остальных планет,');
WriteLn('домов, аспектов и использовать более точные эфемериды.');
WriteLn('-----------------------------------------------------------------');
end.
Пояснение ключевых частей кода
Преобразование даты в юлианский день
Функция DateToJulianDay реализует формулу, предложенную Юлием Цезарем и уточнённую в Astronomical Algorithms. Юлианский день – это единый счётчик дней, позволяющий легко вычислять положения небесных тел.
Нормализация углов
Функция NormalizeAngle гарантирует, что любой угол будет в диапазоне 0°…360°. Это важно, потому что астрологические знаки делятся ровно на 30°.
Расчёт долготы Солнца
Мы используем упрощённый набор коэффициентов (средняя аномалия, уравнение центра). Для большинства любительских задач такой уровень точности (≈0,5°) достаточен.
Асцендент
Точный расчёт асцендента требует звёздных координат Солнца (RA, Dec) и местного звёздного времени (LST). В примере мы берём RA ≈ долготу Солнца, а Dec ≈ 0°, что упрощает формулу, но сохраняет смысл – асцендент будет в пределах нескольких градусов от реального.
Определение знака
Функция GetSignByLongitude делит угол на 30° и возвращает соответствующий элемент перечисления TSign. Массив SignNames хранит русские названия знаков.
Как расширить программу
- Добавить расчёт остальных планет. Для каждой планеты нужны свои коэффициенты (ср. таблицы в «Astronomical Algorithms»).
- Вычисление домов. Реализовать систему Плацидуса, Коха или равных дома.
- Аспекты. Проверять угловые расстояния между планетами (0°, 60°, 90°, 120°, 180°) с допуском ±8°.
- Графический вывод. В Lazarus можно построить круговую диаграмму (круг Зодиака) с помощью компонентов
TCanvas. - База эфемерид. Подключить файл
DE430или использовать онлайн‑API (NASA JPL) для более точных расчётов.
Тестирование и проверка результатов
Для проверки возьмите известные даты рождения знаменитостей и сравните полученные знаки с публичными данными. Пример:
Время: 08:30
Место: Москва (55.75° N, 37.62° E)
Ожидаемый результат:
- Солнце в Водолее
- Асцендент в Овне (приблизительно)
Запустите программу, введите эти параметры и убедитесь, что вывод совпадает.
Полезные ресурсы
- Free Pascal Compiler – официальная страница компилятора.
- Книга Дж. Меркута Astronomical Algorithms – подробные формулы для расчётов.
- Сайт astro.com – онлайн‑калькуляторы для сравнения.
- Школа астрологии «Pro Astro» (см. информацию из интернета) – хорошие вводные курсы по астрологической теории.
Мы создали базовую астрологическую программу на Pascal, которая умеет:
- Преобразовывать дату и время в юлианский день.
- Вычислять долготу Солнца и определять знак зодиака.
- Оценивать асцендент (восходящий знак) по широте и долготе места рождения.
Эта основа легко расширяется: добавьте расчёт остальных планет, домов, аспектов и получите полноценный астрологический движок. Главное – помнить, что астрология – это искусство интерпретации, а программирование лишь предоставляет точные данные;
Удачной разработки!