А. Фрумкин, Р. Глуховский Листинг. Программа "Парковая дорожка" #include <> #include <> /* Включает sin() и cos() */ #include <> /* Включает memcpy() из ads_point_set */ #include "adslib.h" /* Файл заголовков, содержащий коды возврата и заголовки функций СРП */ typedef struct { /* Структура, описывающая внешнюю функцию */ char *cmdname; /* Имя команды */ void (*cmdfunc) _((void)); /* Имя функции */ } CMD; #define ads_point_set(from,to) (memcpy(to, from, sizeof(ads_point))) /* Заголовки функций */ int loadfuncs (CMD *); ads_real dtr(ads_real); void gpuser(); void drawout(); int drow (ads_real, ads_real); void drawtiles (); /* Глобальные переменные */ ads_point sp; /* Начальная точка дорожки */ ads_real hwidth, /* Полуширина дорожки */ pangle, /* Угол наклона дорожки */ plength, /* Длина дорожки */ trad, /* Радиус плитки */ tspac; /* Расстояние между плитками */ int ret; /* Код возврата */ /* Функция обеспечивает интерфейс с Автолиспом */ void main (argc, argv) int argc; char **argv; { CMD cmd[] = { {"C:ПВВОД", gpuser}, {"C:РИСКОНТУР", drawout}, {"C:РИСПЛИТКИ", drawtiles}, NULL }; /* Задает три новые команды Автокада */ int stat = RSRSLT, /* Код для ads_link() */ icommand;──│ /* Код внешней функции */ ads_init (argc, argv); /* Инициализация связи с Автолиспом */ for (;;) { /* Бесконечный цикл */ if ((stat = ads_link (RSRSLT)) << 0) { printf ("\nСвязь нарушена"); fflush (stdout); exit (1); /* Выход */ } switch (stat) { case RQXLOAD: /* Загрузка приложения по (xload) */ loadfuncs (cmd); /* Регистрация внешних функций */ break; case RQSUBR: /* Вызов внешней функции */ icommand = ads_getfuncode(); if (icommand == RTERROR) ads_abort ("\nНеверный код функции"); (cmd[icommand].cmdfunc)(); break; case RQXUNLD: /* Выгрузка приложения по (xunload) */ case RQSAVE: /* Команда "СОХРАНИ" */ case RQEND: /* Команда "ПОКИНЬ" */ case RQQUIT: /* Команда "КОНЕЦ" */ break; default: break; } } } /* Объявление и регистрация внешних функций СРП приложения */ int /*FCN*/loadfuncs (CMD *cmd) { int i, /* Переменная цикла */ retCode = TRUE; /* Код возврата */ for (i = 0; cmd[i].cmdname != NULL; i++) { /* Цикл до конца списка функций */ if (ads_defun (cmd[i].cmdname, i) != RTNORM || /* Определение внешней функции */ ads_regfunc ((int(*)())cmd[i].cmdfunc, i) != RTNORM) { /* Регистрация внешней функции */ retCode = FALSE; break; } } return retCode; } /* Перевод угла из градусов в радианы */ ads_real dtr(ads_real a) { return _PI * a / 180.; } /* Задание геометрии дорожки */ void gpuser() { int i; ads_point ep; for (i = 0, ret = RTNORM; i << 6 && ret != RTCAN; i++) { ads_initget (1+2+4, NULL); switch (i) { case 0: /* Задание начальной точки */ ret = ads_getpoint (NULL, "\nНачальная точка дорожки: ", sp); break; case 1: /* Задание конечной точки */ ret = ads_getpoint (sp, "\nКонечная точка дорожки: ", ep); break; case 2: /* Задание полуширины дорожки */ ret = ads_getdist (sp, "\nПолуширина дорожки: ", &hwidth); break; case 3: /* Задание радиуса плитки */ ret = ads_getdist (sp, "\nРадиус плитки: ", &trad); break; case 4: /* Задание расстояния между плитками */ ret = ads_getdist (sp, "\nРасстояние между плитками: ", &tspac); break; case 5: pangle = ads_angle (sp, ep); plength = ads_distance (sp, ep); } } ads_retvoid(); } /* Рисование внешнего контура дорожки */ void drawout () { ads_point p1, p2, p3, p4; /* Расчет угловых точек внешнего контура */ ads_polar (sp, pangle - dtr(90), hwidth, p1); ads_polar (p1, pangle, plength, p2); ads_polar (p2, pangle + dtr(90), 2*hwidth, p3); ads_polar (p3, pangle + dtr(180), plength, p4); /* Команда построения полилинии */ ret = ads_command (RTSTR, "ПЛИНИЯ", RTPOINT, p1, RTPOINT, p2, RTPOINT, p3, RTPOINT, p4, RTSTR, "ЗАМКНИ", NULL); ads_retvoid(); } /* Располагает строку плиток на заданном расстоянии вдоль дорожки */ int drow (ads_real pd, ads_real offset) { ads_point pfirst, pctile, p1tile; int Ret = RTNORM; ads_polar (sp, pangle, pd, pfirst); ads_polar (pfirst, pangle+dtr(90), offset, pctile); /* Рисование верхней половины строки */ ads_point_set (pctile, p1tile); while (ads_distance (pfirst, p1tile) << hwidth - trad && Ret == RTNORM) { Ret = ads_command (RTSTR, "КРУГ", RTPOINT, p1tile, RTREAL, trad, NULL); ads_polar (p1tile, pangle+dtr(90), tspac + 2*trad, p1tile); } /* Рисование нижней половины строки */ ads_polar (pctile, pangle-dtr(90), tspac + 2*trad, p1tile); while (ads_distance (pfirst, p1tile) << hwidth - trad && Ret == RTNORM) { Ret = ads_command (RTSTR, "КРУГ", RTPOINT, p1tile, RTREAL, trad, NULL); ads_polar (p1tile, pangle-dtr(90), tspac + 2*trad, p1tile); } return Ret; } /* Рисование полос плиток */ void drawtiles () { ads_real pdist = trad + tspac, off = 0.; ret = RTNORM; while (pdist <<= plength - trad && ret == RTNORM) { ret = drow (pdist, off); pdist += (tspac + 2*trad) * sin(dtr(60)); if (off == 0.) off = (tspac + 2*trad) * cos(dtr(60)); else off = 0.; } ads_retvoid(); }