Задача нарисовать звезду довольно интересная. Но для многих людей, плохо знакомых с геометрией, увы, нерешаемая. Тем не менее, многое непонятное можно делать понятным, узнавая от кого-то что-нибудь по теме.
Код из этой публикации появился благодаря форумчанину Puporev, выложевшему код в одной из тем. Я очень благодерен тому человеку. Правда, код был выложен на Turbo Pascal, а я выкладываю здесь его переоформленный для C++.
Сама по себе звезда в частом понимании имеет 5 вершин, хотя звезды могут иметь разное их количество. Работа с компьютерной графикой часто требует некоторых тригонометрических знаний. Вот в построение звезды тригонометрические сведения как раз будут использованы.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
//C++ 3.1 Листинг #1 MS-DOS Построение звезды
#include <stdlib.h>
#include <iostream.h>
#include <graphics.h> //Для работы с графическими функциями
#include <math.h> //Для работы с тригонометрическими функциями
/*ФУНКЦИЯ ПОСТРОЕНИЯ ЗВЕЗДЫ*/
voidstar(intR,intr,intn)
{
inta=0;
pointtype*p=newpointtype[n*2+1];//Массив для хранения координат вершин звезды
intx=getmaxx()/2;//Расчет центра экрана по х
inty=getmaxy()/2;//Расчет центра экрана по y
//Цикл расчета вершин звезды
for(inti=1;i<n*2+2;i++)
{
if(!(i%2))//При выполнении условия четности следующие формулы
{
p[i].x=x+r/2*cos(a*M_PI/180);
p[i].y=y-r/2*sin(a*M_PI/180);
}
else//При невыполнении условия четности следующие формулы
{
p[i].x=x+R*cos(a*M_PI/180);
p[i].y=y-R*sin(a*M_PI/180);
}
a=a+180/n;
}
//Завершаем построение звезды соединяя её окончание с начальной точкой
p[n*2+1].x=p[1].x;
p[n*2+1].y=p[1].y;
moveto(p[1].x,p[1].y);
//Последовательное соединение точек массива, хранящего вершины звезды
for(i=1;i<n*2+2;i++)
{
lineto(p[i].x,p[i].y);
}
delete[]p;//Освобождаем память
}
voidinput()
{
intR,r;//Внешний и внутренний радиусы
cout<<"Внутренний радиус = ";cin>>r;
cout<<"Внешний радиус = ";cin>>R;
cout<<"Число вершин = ";cin>>n;
star(R,r,n);//Построение звезды по радиусам
}
intmain()
{
system("CLS");
//ПОДГОТОВКА РАБОТЫ С ГРАФИКОЙ
intgdriver=DETECT,gmode,errorcode;
initgraph(&gdriver, &gmode, "");
input();//Ввод параметров звезды с последующим её построением
system("PAUSE");
return0;
}
Что можно сказать по коду& Сам по себе он не совсем маленький, поэтому я намеренно пропустил проверку на ошибки при работе с графикой (чтобы в глаза читателю бросался основной код, а не проверка на ошибки; проверку же на ошибкт делать нужно). Кроме того, я решил, что наиболее удобочитаемо будет как раз сделать так, чтобы ввод данных был вынесен в отдельную функцию, из которой бы уже вызывалась функция построения звезды. Во всем этом коде можно заметить буковку а. Сама по себе эта буква большого значения не имеет и обозначает угол наклона звезды. В принципе, эту букву можно вынести в ввод данных и оттуда требовать ввести угол наклона, по аналогии с требованием вводить радиус.
Принцип вычисления точек для построения состоит в том, что сначала выполняется расчёт координат каждой вершины звезды, получаемые данные записываются в массив. После заполнения массива координатами всё, что остаётся, это поочерёдно соединить координаты линиями. Я поместил центр звезды в центр экрана, но смещать её, конечно, можно в любое место. Слабенький новичок может спросить, зачем здесь динамический массив? Дело в том, что это код для построения звезды с заранее неизвестным числом вершин, поэтому мы не знаем, какая у массива должна быть ёмкость, чтобы хватило на все вычисляемые точки.
Помня, что ни к чему хорошему меня поиски решения этой задачи в основном не приводили, думаю, что эта публикация принесёт много пользы разным людям.
Добавить комментарий