Исходник программы - интерактивное построение звёздчатого многоугольника на Си(C++)


Добавил:DMT
Дата создания:29 апреля 2008, 17:48
Дата обновления:29 апреля 2008, 17:48
Просмотров:11537 последний сегодня, 21:47
Комментариев: 0
Исходник программы - интерактивное построение звёздчатого многоугольника на Си(C++)
Код на C++
  1. #include <graphics.h>
  2. #include <conio.h>
  3. #include <math.h>
  4. #include <stdio.h>
  5. #include <iostreame.h>
  6. #include <mmouse.h>
  7. #include <string.h>
  8. #include <ctype.h>
  9. #include <stdlib.h>
  10. #include <dos.h>
  11. struct coor
  12. {int x,y;}
  13. *m;
  14.  
  15. void initmouse(void)
  16. {
  17. asm xor ax,ax
  18. asm xor bx,bx
  19. asm int 0x33
  20. }
  21.  
  22. void show_cur(int i)
  23. {
  24. union REGS r;
  25. r.h.ah=0;
  26. r.h.al=i;
  27. int86(0x33,&r,&r);
  28. }
  29.  
  30. int mouse_mode(void)
  31. {
  32. asm mov ax,3
  33. asm int 0x33
  34. return _BL;
  35. }
  36.  
  37. void get_xy(void)
  38. {
  39. asm mov ax,3
  40. asm int 0x33
  41. m->x=_CX;
  42. m->y=_DX;
  43. }
  44.  
  45.  
  46.  
  47. #define PI 3.14159
  48.  
  49. struct Point // класс точки
  50. {
  51. double x,y; // координаты точки
  52. int code(Point q); // код четверти, в которой лежит точка q
  53. double operator*(Point q);// векторное произведение
  54. Point operator-(Point q); // разность векторов
  55. };
  56.  
  57. Point ctop(void)//преобразование координаты мыши в координаты точки
  58. {
  59. Point p;
  60. p.x=m->x-250;
  61. p.y=m->y-250;
  62. return p;
  63. }
  64.  
  65. int Point::code(Point q) // код четверти, в которой лежит точка q
  66. { // начало координат находится в точке (x,y)
  67. if (q.x-x>=0 && q.y-y>=0) return 0;
  68. if (q.x-x< 0 && q.y-y>=0) return 1;
  69. if (q.x-x>=0 && q.y-y< 0) return 3;
  70. if (q.x-x< 0 && q.y-y< 0) return 2;
  71. }
  72.  
  73. double Point::operator*(Point q)
  74. {
  75. return x*q.y-y*q.x; // векторное произведение
  76. }
  77. Point Point::operator-(Point q) // разность векторов
  78. {
  79. Point t; t.x=x-q.x; t.y=y-q.y; return t;
  80. }
  81.  
  82. int operator <(Point p, Point q)
  83. {
  84. Point t; // сравнение углов радиус-векторов p и q
  85. t.x=0; t.y=0; // коды четвертей вычисляются относительно (0,0)
  86. if(t.code(p)<t.code(q)) return 1;
  87. if(t.code(p)>t.code(q)) return 0;
  88. return (p*q>0); // вращение от p к q направлено против часовой стрелки
  89. }
  90. class Domain // абстрактный класс области
  91. {
  92. protected:
  93. int color; // цвет области
  94. int n; // количество сторон
  95. public:
  96. virtual int isin(Point p)=0; // функция принадлежности
  97. Domain(int c=15): color(c){} // конструктор
  98. void show();// функция вывода области
  99. void change(int k, int l);//функция преобразования
  100. };
  101.  
  102. void Domain::show()
  103. {
  104. int ix, iy; Point q;Point g;Point f;
  105. for (iy=0; iy<=getmaxy(); iy++)
  106. for (ix=0; ix<=getmaxx(); ix++)
  107. {
  108. q.x = ix-250;
  109. q.y = iy-250;
  110. if (isin(q)) putpixel(ix,iy, color);
  111. }
  112. }
  113.  
  114. void Domain::change(int k, int l)
  115. {
  116. int ix, iy; Point q;
  117.  
  118. for (iy=0; iy<=getmaxy(); iy++)
  119. for (ix=0; ix<=getmaxx(); ix++)
  120. {
  121. q.x = (ix-250)-k;
  122. q.y = (iy-250)+l;
  123. if (isin(q)) putpixel(ix,iy, color);
  124. }
  125. }
  126.  
  127. //класс многоугольника
  128. class Polygon: virtual public Domain
  129. {
  130. protected:
  131. Point *p;
  132. public:
  133. Polygon(){n=0;}
  134. Polygon(double *x, double *y, int num, int cl);
  135. int isin(Point t);
  136. };
  137. Polygon::Polygon(double *x, double *y, int num, int cl):Domain(cl)
  138. {
  139. int i; n = num; p= new Point [num];
  140. for (i=0; i<n; i++)
  141. {
  142. p[i].x=x[i]; p[i].y=y[i];
  143.  
  144. }
  145. }
  146.  
  147. int Polygon::isin(Point t) // тест на принадлежность методом углов
  148. {
  149. int i, ind=0;
  150. Point q = p[n-1];
  151. for (i=0; i<n; i++)
  152. {
  153. if (t.code(q)==t.code(p[i]));
  154. else if ((t.code(p[i])-t.code(q)-1)%4==0) ind++;
  155. else if ((t.code(p[i])-t.code(q)+1)%4==0) ind--;
  156. else if ((p[i]-q)*(t-q)>0) ind+=2;
  157. else ind-=2;
  158. q = p[i];
  159. }
  160. ind = ind/4;
  161. if (ind==0) return 0; else return 1;
  162. }
  163.  
  164. //класс звездчатого полигона
  165. class SPolygon: public Polygon
  166. {
  167. protected:
  168. Point pC;
  169. public:
  170. SPolygon(){} // конструктор по умолчанию
  171. SPolygon(double *x, double *y, int m, int cl);
  172. };
  173. SPolygon::SPolygon(double *x, double *y, int m, int cl):Domain(cl)
  174. {
  175. int i,j;
  176. Point t;
  177. p= new Point [m]; n=m;
  178. pC.x=0; pC.y=0;
  179. for(i=0;i<m;i++)
  180. {
  181. pC.x+=x[i]; pC.y+=y[i];
  182. }
  183. pC.x= pC.x/m; pC.y= pC.y/m;
  184. setcolor(YELLOW);
  185. for(i=0;i<m;i++)
  186. {
  187. p[i].x=x[i]; p[i].y=y[i];
  188. circle(p[i].x+250,p[i].y+250,2);
  189. }
  190. //Сортируем точки по возрастанию угла вокруг центра тяжести методом вставок
  191. for(i=1; i<m; i++)
  192. {
  193. t = p[i];
  194. for (j=i-1; (j>=0) && ((t-pC)<(p[j]-pC)); j--)
  195. p[j+1] = p[j];
  196. p[j+1]=t;
  197. }
  198. for (i=0;i<m-1;i++)
  199. {
  200. line(p[i].x+250, p[i].y+250,p[i+1].x+250, p[i+1].y+250);
  201. line(p[m-1].x+250, p[m-1].y+250,p[0].x+250, p[0].y+250 );
  202. }
  203.  
  204. }
  205.  
  206. Point tt;
  207. int main()
  208. {
  209. double rad=150, x[10], y[10];//радиус окружности и вершины пятиугольник
  210. int i,n;
  211. clrscr();
  212. cout<<"Введите количество углов (от 3 до 15) ";
  213. cin>>n;
  214. if(n<3||n>15) exit(1);
  215. for(i=0;i<5;i++)
  216. {
  217. // вершины большого пятиугольник
  218. x[i] = rad*cos(2*PI*i/5);
  219. y[i] = rad*sin(2*PI*i/5);
  220. // вершины маленького пятиугольник
  221. x[i+5] = rad*cos(2*PI*i/5+PI/5)/2;
  222. y[i+5] = rad*sin(2*PI*i/5+PI/5)/2;
  223. }
  224. randomize();
  225. for(i=0;i<10;i++)
  226. {x[i]+=(random(100));}
  227.  
  228. int gm, gd=DETECT;
  229. initgraph(&gd, &gm, "..\\bgi"); // инициализация графики
  230.  
  231. SPolygon dom(x,y,n,LIGHTRED); // построение звездчатого по-лигон
  232. dom.show(); // вывод звездчатого полигон
  233. initmouse();
  234. show_cur(1);
  235. int key;
  236. int k=0,l=0;
  237.  
  238. while(1)
  239. {
  240. get_xy();
  241. if(kbhit()!=0)//если нажата клавиша - Выход
  242. {
  243. key=getch();
  244. if(key==13||key==27)
  245. {
  246. show_cur(2);
  247. cleardevice();
  248. closegraph();
  249. exit(1);
  250. show_cur(1);
  251. }
  252. }
  253. if(mouse_mode()==2) //если нажата левая кнопка - ввод вектора
  254. {
  255. show_cur(2);
  256. gotoxy(1,1);
  257. cout<<"Vector (X,Y)\n";
  258. cout<<"X=";
  259. cin>>k;
  260. cout<<"Y=";
  261. cin>>l;
  262. cleardevice();
  263. SPolygon dom(x,y,n,LIGHTRED); // построение звездчатого по-лигона
  264. dom.change(k,l);
  265. show_cur(1);
  266. }
  267. get_xy();//получаем координаты
  268. if(mouse_mode()==1)//если нажата правая - проверка на попадание точки
  269. {
  270. get_xy();//получаем координаты
  271. Point q;
  272. tt=ctop();
  273. show_cur(2);
  274. q.x = tt.x-k;
  275. q.y = tt.y+l;
  276. gotoxy(1,1);
  277. if(!dom.isin(q)) {cout<<"Point out Polygon";gotoxy(1,1);}
  278. else {cout<<"Point in Polygon ";gotoxy(1,1);}
  279. show_cur(1);
  280. }
  281. }
  282. getch(); closegraph();
  283. return 0;
  284. }
При использовании обязательна ссылка на http://DMTSoft.ru
up