Продолжая тему построение графических объектов используя мультимедийную библиотеку SFML, рассмотрим интересный класс VertexArray (массив вершин).
Точки
#include <SFML/Graphics.hpp>
using namespace sf;
int main()
{
srand(time(NULL));
RenderWindow window(VideoMode( 1500, 900 ), L"Titul", Style::Default);
//Массив точек
VertexArray mypoint(Points, 10000);
for (int i = 0; i < 10000; i++)
mypoint[i].position=Vector2f(rand()%1500, rand() % 900);
while (window.isOpen())
{
Event event;
while (window.pollEvent(event))
{
if (event.type == Event::Closed) window.close();
}
window.clear(Color::Blue);
window.draw(mypoint); // Точка
window.display();
}
return 0;
}
VertexArray mypoint(Points, 10000) в параметрах объекта mypoint указываем тип объекта Points - точка и этих точек должно быть 10000. Через цикл for обращаемся к каждой точке и устанавливаем случайные координаты для неё mypoint[i].position=Vector2f(rand()%1500, rand() % 900), не забываем в начале запустить генератор случайных чисел srand(time(NULL)).
Линии
// Массив линий
VertexArray myLines(Lines, 40);
for (int i = 0,y=0; i < 40; i+=2,y+=10)
{ myLines[i].position = Vector2f(100, 100+y);
myLines[i+1].position = Vector2f(500, 100+y);
}
Объект myLines содержит в параметрах тип Lines - линия и количество точек 40, так как для построения линии необходимо две точки, указав 40 точек, получаем 20 линий. Как и ранее для каждой точки с помощью цикла for устанавливаем координаты места положения в графическом окне. Незабываем в конце цикла while (window.isOpen()) рисовать данный объект window.draw(myLines).
Ломаная линия
// Ломаная линия
VertexArray myLinesStrip(LineStrip, 20);
for (int i = 0, y = 0; i < 20; i += 2, y += 50) {
myLinesStrip[i].position = Vector2f(600, 100 + y);
myLinesStrip[i + 1].position = Vector2f(1200, 100 + y);
}
Для отображения треугольников в параметрах объекта myTriangle указываем тип фигуры треугольник (Triangle) и обозначив 9 точек, рисуем три треугольника. Для корректного отображения фигур, необходимо следовать установленному порядку обозначения координат вершин треугольников.
Порядок определения координат вершин треугольников обозначен на рисунке №1.
Используя функцию Color разукрашиваем точки треугольников (myTriangles[8].color = Color(255, 255, 0)) в формате RGB.
В массиве треугольников соединённых с центральной точкой первая вершина является центром, затем каждая новая вершина определяет новый треугольник, используя центр и предыдущую вершину.
В массиве четырёхугольников, 4 вершины каждого четырёхугольника должны быть определены последовательно, либо по часовой стрелки, либо против часовой стрелки.
Прототип симулятора солнечной системы
Используя знания предыдущей и этой темы создадим симулятор солнечной системы.
В основе программного кода будем использовать формулу нахождения координат точки на окружности.
x = x0 + round(rad*cos(a*PI/180));
y = y0 + round(rad * sin(a * PI / 180))*vector;
где, x и y - координаты вращающегося объекта, x0 и y0 - координаты центра вращения, round() - функция округления до ближайшего целого, rad - расстояние от центра вращения до объекта вращения, cos() и sin() - тригонометрические функции, a - изменяемый угол при вращении от 0 до 360 градусов, PI - число 3.14, vector - направление вращения равен 1 или -1.
Процесс вычисления координат вращающегося объекта поместим в отдельный класс Planets.
Который будет состоять из двух конструкторов:
Planets(int startx, int starty, int r, int v);
Planets(int r, int v);
где, переменные int startx, int starty - координаты центра вращения, int r - расстояние от центра вращения до объекта вращения, int v - направление вращения.
Методы int getx(), int gety() - будут возвращать координаты вращающегося объекта. Метод void move(double s) - будет изменять угол вращения с шагом указанным в переменной double s. Метод void setposition(int startx, int starty) служит для изменения центра вращения.
Ниже привожу код с подробным описание каждого блока.
#include <SFML/Graphics.hpp>
#include <math.h>
using namespace sf;
using namespace std;
// Класс для вычисления кооординат вращающегося объекта
class Planets
{
public:
Planets(int startx, int starty, int r, int v);
Planets(int r, int v);
int getx();
int gety();
void move(double s);
void setposition(int startx, int starty);
private:
int x0=0,y0=0,rad=0,x=0,y=0,vector=1;
double a = 0;
const double PI = acos(-1.0);
};
Planets::Planets(int startx, int starty, int r, int v)
{
if (v > 1) v = 1;
if (v < -1 || v == 0) v = -1;
vector = v;
x0 = startx;
y0 = starty;
rad = r;
}
Planets::Planets(int r, int v)
{
if (v > 1) v = 1;
if (v < -1 || v == 0) v = -1;
vector = v;
rad = r;
}
int Planets::getx()
{
return x;
}
int Planets::gety()
{
return y;
}
void Planets::move(double s)
{
a += s;
if (a > 360) a = 0;
x = x0 + round(rad*cos(a*PI/180));
y = y0 + round(rad * sin(a * PI / 180))*vector;
}
void Planets::setposition(int startx, int starty)
{
x0 = startx;
y0 = starty;
}
int main()
{
// Запускаем генератор случайных чисел
srand(time(NULL));
// Создаём графическое окно
RenderWindow window(VideoMode(1500, 900), L"Солнечная система", Style::Default);
// Вертикальная синхронизация кадров анимации
window.setVerticalSyncEnabled(true);
// Объявление планет солнце, меркурий, венера, земля, марс, луна
CircleShape sun(100.f), merk(1), vener(6), earth(10), mars(4), moon(4);
// Задаём параметры для солнца
sun.setPosition(750, 450);
sun.setOrigin(100,100);
Texture texsun;
texsun.loadFromFile("sun.png");
sun.setTexture(&texsun);
//Задаём параметры для звезд
VertexArray stars(Points, 50);
for (int i = 0; i < 49; i++) {stars[i].color = Color(255, 255, 255);
stars[i].position = Vector2f(rand() % 1500, rand() % 900);}
//Задаём параметры для земли
Texture texearth;
texearth.loadFromFile("erd.png");
earth.setTexture(&texearth);
earth.setOrigin(5,5);
//Задаём параметры для венеры
vener.setFillColor(Color(208, 159, 46));
vener.setOrigin(3, 3);
//Задаём параметры для марса
mars.setFillColor(Color(223, 54, 16));
mars.setOrigin(2, 2);
//Задаём параметры для меркурия
merk.setFillColor(Color(208, 159, 46));
//Задаём параметры для луны
Texture texmoon;
texmoon.loadFromFile("luna.png");
moon.setTexture(&texmoon);
moon.setOrigin(2, 2);
// Создаём объекты определения координат планет
Planets merkxy(750,450,150,-1),venerxy(750,450,200,-1), marsxy(750,450,300,-1), earthxy(750,450,250,-1);
Planets moonxy(30,-1);
while (window.isOpen())
{
Event event;
while (window.pollEvent(event)) if (event.type == Event::Closed)window.close();
// Каждую итерацию изменяем угол положения планеты на 1
merkxy.move(1);
//Устанавливаем текущие координаты объекта
merk.setPosition(merkxy.getx(), merkxy.gety());
// Каждую итерацию изменяем угол положения планеты на 0.5
venerxy.move(0.5);
//Устанавливаем текущие координаты объекта
vener.setPosition(venerxy.getx(), venerxy.gety());
// Каждую итерацию изменяем угол положения планеты на 1.5
marsxy.move(1.5);
//Устанавливаем текущие координаты объекта
mars.setPosition(marsxy.getx(), marsxy.gety());
// Каждую итерацию изменяем угол положения планеты на 0.8
earthxy.move(0.8);
//Устанавливаем текущие координаты объекта
earth.setPosition(earthxy.getx(), earthxy.gety());
// Определяем центр вращения, так как земля меняет своё положение
moonxy.setposition(earth.getPosition().x, earth.getPosition().y);
// Каждую итерацию изменяем угол положения планеты на 3
moonxy.move(3);
//Устанавливаем текущие координаты объекта
moon.setPosition(moonxy.getx(), moonxy.gety());
// Вращаем солнце
sun.rotate(-1);
window.clear();
window.draw(stars);
window.draw(sun);
window.draw(merk);
window.draw(vener);
window.draw(earth);
window.draw(mars);
window.draw(moon);
window.display();
}
return 0;
}
Более подробную инструкцию по 2D примитивам мультимедийной библиотеки SFML вы можете увидеть посмотрев видео "2D примитивы SFML C++".