<< 9. Приложение С | Оглавление | 11. Приложение E >>
Разделы
10. Приложение D
10.1. Тексты программ на языке C
Листинг D 3.1. Модуль чтения каталога Hipparcos
Файл hipmain.h
// Чтение каталога Hipparcos. Заголовочный файл
// Расположение полной версии каталога Hipparcos
#define HipparcosName
"D:/CATALOGS/HIPARCOS/hip_main.dat"
#define HipNumOfStars 118218
typedef struct
{
long HIP; // Номер звезды по
Hipparcos
// Астрометрическая информация
double RAdeg,DEdeg; //
Экваториальные координаты в градусах
double Plx; // Тригонометрический
параллакс в mas
double pmRA,pmDE; // Собств.
движ. ma*cos(d) и md mas/год
char AstroRef; // Флаг для
кратных систем
// Фотометрическая информация
float VMag; // Звездная вел. по
шкале Джонсона
float B_V ; // Показатель
цвета B-V по шкале Джонсона
struct // ошибки соотв. величин
{ double RAdeg,DEdeg, Plx, pmRA,pmDE;
} sigma;
char Sp[10+1]; // Развернутый
спектральный класс
struct // Битовая структура
отсутствия информации
{ unsigned NoRaDe:1; //
Нет данных о точных координатах
unsigned NoPlx :1; // Нет данных
о параллаксе
unsigned NoPM :1; //
Нетданных о собственных
движениях
unsigned NoVMag:1; // Нет данных
о звездной величине
unsigned NoB_V :1; // Нет
данных о показателе цвета
} Info;
}
THipparcos;
// Прототипы функций
bool OpenHipparcosMain(); //
Открытие файла каталога
void CloseHipparcosMain(); //
Закрытие файла каталога
// Чтение одной строки каталога: результат
помещается в s,
// возвращает false при достижении конца файла.
bool ReadHipparcosMain(THipparcos *s);
Файл hipmain.c
// Чтение каталога Hipparcos
#include <stdio.h>
#include <stdlib>
#include <string.h>
#include "hipmain.h"
#define HipRecSize 451 //
длина строки каталога, включая CR,LF
// Возвращает true, если s состоит только из
пробелов
bool IsBlank(char *s)
{ while (*s)
if (*s++ != ' ')
return false;
return true;
}
FILE *f; // Файловая переменная каталога
// Открытие файла каталога в режиме "только
чтение"
bool OpenHipparcosMain()
{ f=fopen(HipparcosName,"rt");
if (f) return true;
elsereturn false;
}
// Закрытие файла каталога
void CloseHipparcosMain() { fclose(f); };
// Чтение одной записи
bool ReadHipparcosMain(THipparcos *s)
{
// Локальные переменные функции
char hs[HipRecSize]; // Строка
каталога
char st[16]; // Вспомогательный
буфер
if feof(f) return
false; //Если конец файла, то False
fread(hs,HipRecSize,1,f); // Чтение одной строки
s->Info.NoRaDe=0; // Обнуление всех битов флага
s->Info.NoPlx =0; s->Info.NoPM =0;
s->Info.NoVMag=0; s->Info.NoB_V =0;
// Мы не используем форматный ввод оператором
scnaf, с тем,
// чтобы полностью контролировать процесс чтения
полей (в том
// числе и пустых). Функции atoi и atof возвращают
нулевые
// значения в случае ошибки преобразования, поэтому
надо
// проверять поля на пробелы отдельно.
// Интерпретация 12 байт, начиная с 3-го - это
номер HIP.
s->HIP=atoi(strncpy(st,hs+3-1,12));
// Чтение координат: по 12 байт с 52 и с 65
позиции.
strncpy(st,hs+52-1,12); st[12]=0; s->RAdeg=atof(st);
if (IsBlank(st)) s->Info.NoRaDe=1;
strncpy(st,hs+65-1,12); st[12]=0; s->DEdeg=atof(st);
if (IsBlank(st)) s->Info.NoRaDe=1;
// Чтение параллакса - 7 байт с 80-й позиции
strncpy(st,hs+80-1,7); st[7]=0; s->Plx=atof(st);
if (IsBlank(st)) s->Info.NoPlx=1;
// Чтение собственных движений: по 8 байт с 88 и с
97 позиции
strncpy(st,hs+88-1,7); st[7]=0; s->pmRA=atof(st);
if (IsBlank(st)) s->Info.NoPM=1;
strncpy(st,hs+97-1,7); st[7]=0; s->pmDE=atof(st);
if (IsBlank(st)) s->Info.NoPM=1;
s->AstroRef=hs[78-1]; // Флаг кратной звезды
// Чтение зв.величины и показателя цвета B-V по
Джонсону
strncpy(st,hs+42-1,5); st[5]=0; s->VMag=atof(st);
if (IsBlank(st)) s->Info.NoVMag=1;
strncpy(st,hs+246-1,6); st[6]=0; s->B_V=atof(st);
if (IsBlank(st)) s->Info.NoB_V=1;
if (!s->Info.NoRaDe)
{ // Данные об ошибках всегда присутствуют,
// если присутствуют и сами координаты.
strncpy(st,hs+106-1,6); st[6]=0; s->sigma.RAdeg=atof(st);
strncpy(st,hs+113-1,6); st[6]=0; s->sigma.DEdeg=atof(st);
}
if (!s->Info.NoPlx)
{ strncpy(st,hs+120-1,6); st[6]=0; s->sigma.Plx=atof(st);}
if (!s->Info.NoPM)
{ strncpy(st,hs+127-1,6); st[6]=0; s->sigma.pmRA=atof(st);
strncpy(st,hs+134-1,6); st[6]=0; s->sigma.pmDE=atof(st);
}
// Чтение данных о спектральном классе
strncpy(s->Sp,hs+436-1,10); st[10]=0;
return true;
}
Листинг D 3.2. Подсчет звезд без данных о координатах, собственных движениях и параллаксах
#include <stdio.h>
#include "hipmain.h"
main()
{
THipparcos s; // Структура данных о звезде
long NoCoord = 0; // Счетчик
звезд без точных координат
long NoProp = 0; // Счетчик звезд
без собств. движений
long NoPar = 0; // Счетчик звезд
без параллаксов
int k; // битовая маска
OpenHipparcosMain(); // Открытие каталога
while (ReadHipparcosMain(&s)) //
Цикл чтения каталога
{
// Сравнение битов в маске с константами
if (s.Info.NoRaDe) NoCoord++;
if (s.Info.NoPM) NoProp++;
if (s.Info.NoPlx) NoPar++;
}
CloseHipparcosMain(); // Закрытие каталога
// Вывод результатов
printf("Звезд без точных координат
%ld::/n",NoCoord);
printf("Звезд без собственных движений
%ld::/n",NoProp);
printf("Звезд без параллаксов %ld::/n", NoPar);
}
Листинг D 3.3. Вычисление распределения звезд по абсолютной звездной величине
#include <stdio.h>
#include <math.h>
#include "hipmain.h"
main()
{ THipparcos s;
long a[25]; // статистика
int i; // вспомогательная
переменная
double r; // расстояние
double m; // абсолютная звездная
величина
for (i=0; i<=24; i++) a[i]=0; //
обнуление статистики
OpenHipparcosMain();
while (ReadHipparcosMain(&s))
{ if
(s.Info.NoPlx)continue; // нет
данных о паралл.
if (s.Plx<=0.0)
continue; // неположительный
параллакс
if (s.sigma.Plx/s.Plx>0.5)
continue; // точность хуже
50%
r=1000.0/s.Plx; // Вычисление расстояния в пк
m=s.VMag-5.0*log10(r)+5.0;//Вычисление абсолютной
зв. величины
i=floor(m+0.5)+12; // Определение индекса ячейки
массива
if ( (i>=0) && (i<=24)) a[i]++; //
ув.на 1
}
CloseHipparcosMain();
for (i=0; i<=24; i++)
printf("%4d %6d::/n",i-12,a[i]);
}
Листинг D 3.4. Вычисление средней абсолютной звездной величины звезд, список которых находится в файле lumin.txt
main()
{
THipparcos s;
double r; // расстояние
double m; // абсолютная звездная
величина
double mav=0; // средняя
абсолютная звездная величина
long n=0 ; // количество
подходящих звезд
int k; // битовая маска
OpenHipparcosMain();
// Инициализация критерия
printf("%ld звезд в списке.::/n",InitCriteria("lumin.txt"));
while (ReadHipparcosMain(&s))
{
k=s.Info & NoPlx;
if (!k) continue; //
нет данных о параллаксе
if (s.Plx<=0.0)
continue; // неположительный
параллакс
r=1000.0/s.Plx; // Вычисление расстояния в пк
m=s.VMag-5.0*log10(r)+5.0; // Вычисл. абс. звезд.
величины
if (InCelestia(s.HIP)) // Звезда в списке
Celestia?
{
mav+=m; // накопление суммы абс. зв. величин
n++; // суммирование числа звезд
}
} // while
ClearCriteria(); // Очистка критерия
CloseHipparcosMain();
mav/=n; // Вычисление среднего значения
printf("M (av) = %6.2f::/n",mav);
printf("Обработано %ld звезд.::/n",n);
scanf("::/n");
}
Листинг D 3.5. Исходный текст функций InitCriteria, InCelestia, ClearCriteria
Добавления в заголовочный файл hipmain.h
// Инициализация критерия с использованием
выходного файла
// программы Celestia 2000. name - имя файла.
// Возвращает число звезд в списке.
long InitCriteria(char * );
// Функция проверяет, есть ли звезда в списке.
bool InCelestia(long n);
// Очистка критерия.
void ClearCriteria();
Добавления в файл hipmain.c
// Глобальные переменные для работы с критерием
long *List; // Указатель на
начало списка номеров звезд
long NList = 0; // Количество
звезд в списке
// Инициализация критерия с использованием
выходного файла
// программы Celestia 2000. name - имя файла.
// Возвращает число звезд в списке
long InitCriteria(char * name)
{
FILE *t; // файловая переменная
char s[512]; // строка-буфер для
чтения
char q[16]; // дополнительный
буфер
long i; // индекс для цикла for
t=fopen(name,"rt"); // Открываем файл
if (!t) return 0;
for (i=0; i<2; i++)
fgets(s,512,t); // Пропуск двух первых строк
fscanf(t,"%d",&NList); // В третьей строке -
количество звезд
// Выделение памяти под список
List=(long *)
malloc(NList*sizeof(long));
for (i=3; i<=12; i++)
fgets(s,512,t); // Пропуск с остатка 3 по 12
строку
for (i=0; i<NList; i++) // чтение
с 3-го байта 12 байт номера
{ fgets(s,512,t);
strncpy(q,s+2,12); q[12]=0;
List[i]=atoi(q);
}
fclose(t);
return NList;
}
// Функция проверяет, есть ли звезда в списке
bool InCelestia(long
n)
{
long i;
// если критерий не установлен - выход
if (NList==0) returnfalse;
for (i=0; i<NList; i++) // обход
звезд в цикле for
{ // если звезда найдена в списке - выход c
true
if (List[i]==n) return
true;
}
return false; // Сюда попадаем,
только если звезда не найдена
}
// Очистка критерия
void ClearCriteria()
{
free(List);
NList=0;
}
Листинг D 4.1. Процедуры перевода координат
void Aitoff
(double l,
double b, // Сферические
координаты в радианах
double &x, double
&y) // Декартовы координаты
{ double s;
if (l>M_PI) l=l-2*M_PI; //
Приведение l в диапазон -PI до +PI
s=sqrt(1.0+cos(b)*cos(l/2.0)); // Знаменатель
формул 4.1
x=-2.0*cos(b)*sin(l/2.0)/s; y=sin(b)/s;
}
void Screen
(double x,
double y, // Декартовы
координаты
int X0, int Y0, //
Экранныекоординатыначаладекартовойсистемы
double Scale, // Масштаб - точек
экрана на единицу длины
int &u, int &v)
// Экранные координаты
{
u=X0+floor(Scale*x+0.5); v=Y0-floor(Scale*y+0.5);
}
Листинг D 4.2. Процедура, рисующая координатную сетку
double rad(double x) // Перевод
градусов в радианы
{ return x/180.0*M_PI;
}
void AitoffGrid
(int Step, // Шаг сетки
в градусах
int X0, int Y0, //
Экранные координаты центра проекции
double Scale, // Масштаб - точек
на единицу длины
int Gr ) // Флаг - в градусах или
в часах разметка долготы
{
int i,j; // Переменные циклов
for
double l,b; // Галактические
координаты
double x,y; // Декартовы
координаты
int u,v; // Экранные координаты
char s[6]; // Строка для
подписей
int h; // Для разметки осей
// Нанесение сетки меридианов
i=-180; // Первый меридиан -180 градусов
do { // Цикл по меридианам
l=rad(i); // Перевод в радианы
j=-90; // Первая точка меридиана
do { // Цикл построения вдоль
меридиана
// Вычисление точки меридиана
b=rad(j); // Перевод в радианы широты
Aitoff(l,b,x,y); // Перевод в декартовы
координаты
Screen(x,y,X0,Y0,Scale,u,v); // Перевод в экранные
коорд.
// Если точка первая (j=-90), то помещаем
графический курсор
// в точку (u,v) функцией moveto, если точка не
первая, то
// "прочерчиваем" курсором линию из предыдущей
точки
// в точку (u,v) функцией lineto.
if (j==-90) moveto(u,v);
else lineto(u,v);
j+=5; // Шаг 5 градусов обеспечивают гладкий вид
меридиана
} while (j<=90);
i+=Step; // Переход к следующему меридиану
} while (i<=180);
// Нанесение сетки параллелей - аналогично
предыдущему
j=-90;
do { // цикл по параллелям
b=rad(j);
i=-180;
do { // цикл построения вдоль
параллели
l=rad(i);
Aitoff(l,b,x,y); Screen(x,y,X0,Y0,Scale,u,v);
if (i==-180) moveto(u,v);
else lineto(u,v);
i=i+5;
} while (i<=180);
j+=Step;
} while (j<=90);
// Задание свойств шрифта (может зависеть от
граф.библ.)
settextstyle(DEFAULT_FONT,HORIZ_DIR,1);
settextjustify(LEFT_TEXT,BOTTOM_TEXT);
// Подписи меридианов вдоль экватора
i=-180;
do {
// Вычисление координаты точки вывода надписи
l=rad(i);
Aitoff(l,0,x,y); Screen(x,y,X0,Y0,Scale,u,v);
// Если Gr истина, то разметка в градусах, иначе -
в часах
if (Gr) h=i;
else { h=i/15; if (h<0) h+=24;
};
itoa(h,s,10); // Преобразование значения h в
текстовую строку
outtextxy(u+5,v-5,s); // Вывод текстовой строки
i+=Step; // Переход к следующему меридиану
} while (i<=180);
// Изменение выравнивания текста
settextjustify(RIGHT_TEXT,BOTTOM_TEXT);
// Подписи параллелей вдоль нулевого меридиана -
аналогично
j=-90+Step;
do {
if (j!=0) // Экватор не
подписываем
{
b=rad(j);
Aitoff(0,b,x,y); Screen(x,y,X0,Y0,Scale,u,v);
itoa(j,s,10);
outtextxy(u-5,v-5,s);
}
j+=Step;
} while (j<=90-Step);
}
Листинг D 4.3. Перевод экваториальных координат в галактические
// Перевод экваториальных координат в
галактические
void Galaxy(
double a, double d, //
Экваториальные координаты
double &l, double
&b) // Галактические
{
double sa,ca,sd,cd;
doubleconst Leo =
4.936829261; // 282.85948083
doubleconst L0 =
0.57477039907; // 32.931918056
doubleconst si =
0.88998807641; // sin 62.871748611
doubleconst ci =
0.45598379779; // cos 62.871748611
a=a-Leo;
sa=sin(a); ca=cos(a);
sd=sin(d); cd=cos(d);
b=asin(sd*ci-cd*si*sa);
l=atan2(sd*si+cd*ci*sa,cd*ca)+L0;
}
Листинг D 4.4. Построение распределения звезд по небесной сфере
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <graphics.h>
#include <conio.h>
#include "hipmain.h"
voidmain()
{
THipparcos s;
int driver,mode; // Для
инициализации графич. режима
int color; // Цвет точки
double l, b; // Галактические
координаты
double x, y; // Декартовы
координаты
int u, v; // Экранные
координаты
int CX, CY; // Экранные
координаты центра проекции
int SC; // Масштаб перевода
декартовых коорд. в экранные
// Инициализация графического режима (зависит от
библ.)
driver=DETECT; mode=0; initgraph(&driver,&mode,"D:/BC/BGI");
// Задание масштаба и центра
// Проекция Айтофа имеет X в диапазоне от -2 до 2,
и зазор
SC=getmaxx()/4-10;
CX=getmaxx()/2; CY=getmaxy()/2;
AitoffGrid(30,CX,CY,SC,1); // Вывод сетки
координат
OpenHipparcosMain(); // Открытие каталога и
InitCriteria("I-II.txt"); // инициализация
критерия
while (ReadHipparcosMain(&s)) //
Цикл чтения звезд
if (InCelestia(s.HIP)) //
Проверка критерия
{
switch (s.Sp[0]) // Определение
цвета звезды
{
case 'O':
case 'B': color=LIGHTBLUE; break;
case 'A': color=LIGHTCYAN; break;
case 'F':
case 'G': color=YELLOW; break;
case 'K':
case 'M': color=LIGHTRED; break;
default: color=LIGHTGRAY;
} // switch
// Перевод экваториальных координат в радианы,
// а затем в галактические координаты
Galaxy(rad(s.RAdeg),rad(s.DEdeg),l,b);
// Вычисление декартовых координат проекции
Айтофа
Aitoff(l,b,x,y);
Screen(x,y,CX,CY,SC,u,v); // Перевод в экранные
координаты
// Поставить точку (можно заменить на круг, крест и
т.п.)
putpixel(u,v,color);
}; // if и while
ClearCriteria();
CloseHipparcosMain();
getch();
}
Листинг D 4.5. Формирование прямоугольных координат звезд
#define criteria "O-B5.TXT" //
Имя файла критерия
#define list "O-B5.DAT" //
Имя выходного файла
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include "hipmain.h"
main()
{
int n = 0; // Счетчик
THipparcos s;
double r; // Расстояние
double l, b; // Галактические
координаты
double x,y,z; // Декартовы
галактические координаты
FILE *f; // Файл вывода результатов
f=fopen(list,"wt");
OpenHipparcosMain();
printf("%d звезд в критерии.::/n",InitCriteria(criteria));
// PrintList();
while (ReadHipparcosMain(&s))
{
if (s.Info.NoPlx==1)
continue; // нет данных о
параллаксе
if (s.Plx<=0.0)
continue; // "плохое" значение
параллакса
if (s.sigma.Plx/s.Plx>0.5)
continue; // низкая точность
пар.
if (InCelestia(s.HIP))
{
r=1000.0/s.Plx; // Вычисление расстояния в пк
if (r>500.0) continue;
// Отброс далеких звезд
// Перевод в галактические координаты
Galaxy(rad(s.RAdeg),rad(s.DEdeg),l,b);
x=r*cos(b)*cos(l); // Вычисление прямоугольных
y=r*cos(b)*sin(l); // галактических координат
z=r*sin(b);
fprintf(f,"%10.2lf %10.2lf %10.2lf::/n",x,y,z);
// Вывод в файл
n++; // Увеличение счетчика на единицу
};
}; // while
ClearCriteria();
CloseHipparcosMain();
fclose(f);
printf("%d звезд обработано.::/n",n);
}
<< 9. Приложение С | Оглавление | 11. Приложение E >>
Публикации с ключевыми словами:
астрометрия - каталоги - Hipparcos
Публикации со словами: астрометрия - каталоги - Hipparcos | |
См. также:
Все публикации на ту же тему >> |