Уроки, алгоритмы, программы, примеры

Вход на сайт

Материалы по разделам

Построения
на плоскости (2D)
Графика
в пространстве (3D)
Вычислительная
геометрия
Физическое
моделирование
Фрактальная
графика

Новые комментарии

Выдаёт ошибку glut32.dll не найден! При том, что он лежит в System32! Всё решил) Нужно отправить не в System32, а в System.
Спасибо за статью. Я не Ваш студент. Но мне она помогла написать функцию для Канторова множества на Python для черепашки: import turtle def kanter(x, y, d):     if d > 1:         turtle...
Как реализовать в данном примере границы расчёта?

Счетчики и рейтинг

Рейтинг@Mail.ru Яндекс.Метрика
Среда программирования: 
Visual Studio 2010 Express

using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
 
namespace Rotate_Hexagons
{
    public partial class Form1 : Form
    {
        Bitmap myBitmap; // Объявляем битмап
        Graphics g; // Объявляем графику
 
        // Описываем структуру шестиугольника
        public struct T_Hexagon 
        { 
            public Point center;
            public Point[] border;
            public double[] angle;
        };
        public T_Hexagon[,] a = new T_Hexagon[110, 100]; // Объявляем массив структур шестиугольников
        public int[,] order = new int[110, 110]; // Объявляем массив порядка обхода шестиугольников для их поворота
 
        double r = 35.3; // Радиус описанной окружности для шестиугольника (испоьзуется для построения шестиугольников)
        Point center = new Point(15, 15); // Координаты ячейки центрального шестиугольника на плоскости 
 
        int cur_rotatinon_order; // Текущий слой шестиугольников для поворота 
        int cur_cnt; // Текущее кол-во пройденных итераций поворота
        int next_cnt; // Кол-во пройденных интераций поворота для следующего слоя
 
        public Form1()
        {
            InitializeComponent();
        }
 
        private void Form1_Load(object sender, EventArgs e)
        {
 
        }
 
        // Создаем шестиугольник
        void Create_Hexagon(int i, int j) 
        {
            a[i, j].border = new Point[6]; // Инициализируем массив точек границы шестиугольника
            a[i, j].angle = new double[6]; // Массив углов, соответствующих точке
            double angle = Math.PI/3; // Инициализируем начальный угол
            for (int t = 0; t < 6; t++)
            {
                // Рассчитываем координаты шестиугольника
                a[i, j].border[t].X = Convert.ToInt32(r * Math.Cos(t * angle)) + a[i, j].center.X;
                a[i, j].border[t].Y = Convert.ToInt32(r * Math.Sin(t * angle)) + a[i, j].center.Y;
                a[i, j].angle[t] = t * angle; // ... и соответствующий угол для текущей точки
            }
        }
 
        // Рисуем шестиугольник
        void Draw_Hexagon(int i, int j)
        {
            SolidBrush myBrush = new SolidBrush(Color.White);
            g.FillPolygon(myBrush, a[i, j].border);
        }
 
        // Строим все шестиугольники
        void Create_All_Hexagons(Point center)
        {
            // Обходим все шестиугольники
            for (int i = 0; i <= 2 * center.Y; i++)
            {
                for (int j = 0; j <= 2 * center.X; j++)
                {
                    // Устанавливаем сдвиг в один пиксель (для корректного отображения картинки, связано с погрешностью вычислений)
                    int shift = 0;
                    if (i > center.X) shift = 1;
                    if (i < center.Y) shift = -1;
 
                    // Рассчитываем координаты центров всех шестиугольников (ставим их сеткой)
                    a[i, j].center.Y = Convert.ToInt32(a[center.X, center.Y].center.Y + (i - center.X) * 2 * r * Math.Sin(Math.PI / 3)) - shift;
                    a[i, j].center.X = Convert.ToInt32(a[center.X, center.Y].center.X + (j - center.Y) * 2 * r);
 
                    // Смещаем все шестиугольники, которые находяться от центрального шестиугольника на нечетное кол-во позиций, влево, чтобы картинка была шахматного вида
                    if (Math.Abs(i - center.Y) % 2 == 1)
                    {
                        a[i, j].center.X -= Convert.ToInt32(r);
                    }
                    // Рассчитываем координаты точек на границе шестиугольника
                    Create_Hexagon(i, j);
                }
            }
        }
 
        // Прорисовываем все шестиугольники
        void Draw_All_Hexagons(Point center)
        {
            // Инициализируем битмап
            myBitmap = new Bitmap(700, 700);
            g = Graphics.FromImage(myBitmap); // Инициализируем графику
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
 
            SolidBrush myBrush = new SolidBrush(Color.Black);
            g.FillRectangle(myBrush, 0, 0, 700, 700); // Очищаем холст
            for (int i = 0; i <= 2 * center.X; i++)
            {
                for (int j = 0; j <= 2 * center.Y; j++)
                {
                    Draw_Hexagon(i, j); // Рисуем шестиугольник
                }
            }
            pictureBox1.Image = myBitmap; // Записываем содержание bitmap в picturebox
        }
 
        // Устанавливаем порядок обхода шестиугольников для поворота
        void Establish_Order(Point center)
        {
            for (int i = 0; i < 2 * center.X; i++)
            {
                for (int j = 0; j < 2 * center.Y; j++)
                {
                    order[i, j] = -1;
                }
            }
 
            // Устанавливаем порядок в соответствии с номером слоя
            for (int cur_order = 0; cur_order <= 20; cur_order++)
            {
                if (center.X - cur_order >= 0 && center.X + cur_order <= 2 * center.X)
                {
                    if (center.Y - cur_order >= 0 && center.Y + cur_order <= 2 * center.Y)
                    {
                        for (int shift = 0; shift <= cur_order; shift++)
                        {
                            int tmp_shift = shift;
                            if (shift % 2 == 1) tmp_shift++;
                            tmp_shift /= 2;
                            order[center.X - cur_order + tmp_shift, center.Y - shift] = cur_order;
                            order[center.X - cur_order + tmp_shift, center.Y + shift] = cur_order;
 
                            order[center.X + cur_order - shift / 2, center.Y - shift] = cur_order;
                            order[center.X + cur_order - shift / 2, center.Y + shift] = cur_order;
 
                        }
                        int t = cur_order;
                        if (cur_order % 2 == 1) t++;
                        t /= 2;
                        for (int cur_x = center.X - cur_order + t; cur_x <= center.X + cur_order - cur_order / 2; cur_x++)
                        {
                            order[cur_x, center.Y - cur_order] = cur_order;
                            order[cur_x, center.Y + cur_order] = cur_order;
                        }
 
                    }
                }
 
            }
        }
 
        private void pictureBox1_Click(object sender, EventArgs e)
        {
            // Инициалируем координаты центра для центрального на плоскости шестиугольника
            a[center.X, center.Y].center = new Point(350, 350);
            // Строим по координатам центрального шестиугольника все шестиугольники
            Create_All_Hexagons(center);
            Establish_Order(center); // Устанавливаем порядок обхода для поворота
            Draw_All_Hexagons(center); // Рисуем все шестиугольники
            timer1.Start(); // Запускаем таймер (начало поворота от центрального шестиугольника)
        }
 
        // Поворачиваем шестиугольник
        void Rotate_Hexagon(int j, int i)
        {
            for (int t = 0; t < 6; t++)
            {
                // Координаты граничных точек шестиугольника перещитываем относительно центра шестиугольника
                a[i, j].border[t].X -= a[i, j].center.X;
                a[i, j].border[t].Y -= a[i, j].center.Y;
                // Рассчитываем угол для текущей точки
                double cur_angle = a[i, j].angle[t] + Math.PI / 180;
 
                a[i, j].angle[t] = cur_angle;
                // Рассчитываем координаты точек с учетом поворота
                a[i, j].border[t].X = Convert.ToInt32(r * Math.Cos(cur_angle));
                a[i, j].border[t].Y = Convert.ToInt32(r * Math.Sin(cur_angle));
                // Пересчитываем координаты граничных точек относительно абсолютного начала координат
                a[i, j].border[t].X += a[i, j].center.X;
                a[i, j].border[t].Y += a[i, j].center.Y;
            }
        }
 
        private void timer1_Tick(object sender, EventArgs e)
        {
            cur_rotatinon_order = 0; // Инициализируем номер текущего слоя
            cur_cnt = 0; // Инициализируем текущее кол-во выполненных итераций поворота (для текущего слоя)
            next_cnt = 0; // Инициализируем кол-во выполненных итераций поворота для следующего слоя
 
            timer2.Start(); // Запускаем таймер поворота
        }
        private void timer2_Tick(object sender, EventArgs e)
        {
            cur_cnt++; // Увеличиваем кол-во итераций поворота
            if (cur_cnt > 15) next_cnt++; // Если кол-во итераций поворота больше половины необходимого, то начинаем вращать следующий слой
 
            // Поворачиваем шестиугольники текущего слоя
            for (int i = 0; i <= 2 * center.X; i++)
            {
                for (int j = 0; j <= 2 * center.Y; j++)
                {
                    if (order[i, j] == cur_rotatinon_order) Rotate_Hexagon(i, j); 
                }
            }
 
            // Поворачиваем шестиугольники следующего слоя
            for (int i = 0; i <= 2 * center.X; i++)
            {
                for (int j = 0; j <= 2 * center.Y; j++)
                {
                    if (next_cnt != 0 && order[i, j] == cur_rotatinon_order+1) Rotate_Hexagon(i, j);
                }
            }
 
            // Рисуем все шестиугольники
            Draw_All_Hexagons(center);
 
            // Если полностью перевернули шестиугольники текущего слоя, то переходим к следующему
            if (cur_cnt == 30)
            {
                cur_rotatinon_order++;
                cur_cnt = 15;
                next_cnt = 0;
            }
 
            // Если мы обошли все слои, то останавливаем вращение
            if (cur_rotatinon_order == 20)
            {
                timer2.Stop();
                return;
            }
        }
 
 
    }
}

Прикрепленный файлРазмер
Rotate_Hexagons.rar33.08 кб

Комментарии

Dj_crush аватар
Опубликовано Dj_crush в 16. Июль 2015 - 6:25.

еще немного оптимизировал код:

#include <SFML/Graphics.hpp>
#include <Windows.h>
 
const float M_PI = 3.1415926f / 180;
using namespace sf;
void DrawRadius(RenderWindow& window, int r, int Angle);
void DrawObject(RenderWindow& window, int x, int y, int Angle);
 
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPreviousInst, LPSTR lpCommandLine, int nCommandShow)
{
	int Angle = 0,Angle_New = 0, Angle_Old = 0,Angle_Future = 30, current_layer=0;
	ContextSettings settings;
	settings.antialiasingLevel = 8;
	RenderWindow window(VideoMode(640, 480), "Two patterns", Style::Default, settings);
 
	while (window.isOpen())
	{
 
		window.clear(Color(0, 0, 0, 255));
 
		Event event;
		while (window.pollEvent(event))
		{
			if (event.type == Event::Closed)
				window.close();
		}
		for (int layer = 0; layer < 8; layer++)
		{
			if (layer == current_layer) DrawRadius(window, layer, Angle);
			if (layer < current_layer) DrawRadius(window, layer, Angle_New);
			if (layer > current_layer) DrawRadius(window, layer, Angle_Old);
		}
 
		Angle++;
		if (Angle > Angle_Future)
		{
 
			Angle_New = Angle - 1;
			Angle = Angle - 30;
			current_layer++;
			if (current_layer == 8)
			{
				current_layer = 0;
				Angle_Future = Angle_Future + 30;
				Angle_Old = Angle_New; 
				Angle = Angle_New;
			}
		}
		window.display();
 
		Sleep(5);
	}
}
// функция рисует шестиугольники текущего слоя
void DrawRadius(RenderWindow& window,int layer, int Angle)
{
	int x = 320 - layer * 35, y = 240 - layer * 60, number_of_hexagons, direction_of_motion = 0, counter_hexagons_in_row = 0;
	number_of_hexagons = (layer > 0) ? 7 * layer : 1;
	for (int counter_of_hexagons = 0; counter_of_hexagons < number_of_hexagons; counter_of_hexagons++)
	{
		if (x>-35 && x<675 && y>-1 && y<485) DrawObject(window, x, y, Angle); // для того чтобы не тратить время на прорисовку невидимых шестиугольников
 
		switch (direction_of_motion)
		{
		case 1: x = x + 70; break;
		case 2: x = x + 35; y = y + 60; break;
		case 3: x = x - 35; y = y + 60; break;
		case 4: x = x - 70; break;
		case 5: x = x - 35; y = y - 60; break;
		case 6: x = x + 35; y = y - 60; break;
		case 7: y = y - 60; break;
		}
		counter_hexagons_in_row++;
		if (counter_hexagons_in_row == layer)
		{
			counter_hexagons_in_row = 0;
			direction_of_motion++;
			if (direction_of_motion == 8) direction_of_motion = 1;
		}
	}
}
 
// функция рисует шестиугольник, повернутый на угол Angle
void DrawObject(RenderWindow& window,int x, int y, int Angle)
{
	float x1 = -sin(M_PI * Angle)*35;
	float y1 = cos(M_PI * Angle)*35;
	float x2 = -sin(M_PI * (Angle + 60))*35;
	float y2 = cos(M_PI * (Angle + 60))*35;
	float x3 = -sin(M_PI * (Angle + 120))*35;
	float y3 = cos(M_PI * (Angle + 120))*35;
	float x4 = -sin(M_PI * (Angle + 180))*35;
	float y4 = cos(M_PI * (Angle + 180))*35;
	float x5 = -sin(M_PI * (Angle + 240))*35;
	float y5 = cos(M_PI * (Angle + 240))*35;
	float x6 = -sin(M_PI * (Angle + 300))*35;
	float y6 = cos(M_PI * (Angle + 300))*35;
	ConvexShape convex;
	convex.setPointCount(6);
	convex.setPoint(0, Vector2f(x1 + x, y1 + y));
	convex.setPoint(1, Vector2f(x2 + x, y2 + y));
	convex.setPoint(2, Vector2f(x3 + x, y3 + y));
	convex.setPoint(3, Vector2f(x4 + x, y4 + y));
	convex.setPoint(4, Vector2f(x5 + x, y5 + y));
	convex.setPoint(5, Vector2f(x6 + x, y6 + y));
	window.draw(convex);
 
}

Dj_crush аватар
Опубликовано Dj_crush в 15. Июль 2015 - 20:49.

Здравствуйте, а так программу можно писать?
VC2013 +SFML 2.2

#include <SFML/Graphics.hpp>
#include <Windows.h>
 
const float M_PI = 3.1415926 / 180;
using namespace sf;
// create global structure poly
 
struct _hexagon
{
	float x1;
	float y1;
	float x2;
	float y2;
	float x3;
	float y3;
	float x4;
	float y4;
	float x5;
	float y5;
	float x6;
	float y6;
} hexagon;
void DrawRadius(RenderWindow& window, int r, int Angle);
void DrawObject(RenderWindow& window, int x, int y, int Angle);
 
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPreviousInst, LPSTR lpCommandLine, int nCommandShow)
{
	int Angle = 0,Angle_New = 0, Angle_Old = 0,Angle_Future = 30, current_layer=0;
	ContextSettings settings;
	settings.antialiasingLevel = 8;
	RenderWindow window(VideoMode(640, 480), "Two patterns", Style::Default, settings);
 
	while (window.isOpen())
	{
 
		window.clear(Color(0, 0, 0, 255));
 
		Event event;
		while (window.pollEvent(event))
		{
			if (event.type == Event::Closed)
				window.close();
		}
 
 
		for (int layer = 0; layer < 8; layer++)
		{
			if (layer == current_layer) DrawRadius(window, layer, Angle);
			if (layer < current_layer) DrawRadius(window, layer, Angle_New);
			if (layer > current_layer) DrawRadius(window, layer, Angle_Old);
 
		}
 
		Angle++;
		if (Angle > Angle_Future)
		{
 
			Angle_New = Angle - 1;
			Angle = Angle - 30;
			current_layer++;
			if (current_layer == 8)
			{
				current_layer = 0;
				Angle_Future = Angle_Future + 30;
				Angle_Old = Angle_New; 
				Angle = Angle_New;
			}
		}
		window.display();
 
		Sleep(5);
	}
}
// функция рисует шестиугольники текущего слоя
void DrawRadius(RenderWindow& window,int layer, int Angle)
{
 
 
	int x = 320 - layer * 35, y = 240 - layer * 60, number_of_hexagons, direction_of_motion = 0, counter_hexagons_in_row = 0;
	number_of_hexagons = (layer > 0) ? 7 * layer : 1;
	for (int counter_of_hexagons = 0; counter_of_hexagons < number_of_hexagons; counter_of_hexagons++)
	{
		if (x>-35 && x<675 && y>-1 && y<485) DrawObject(window, x, y, Angle); // для того чтобы не тратить время на прорисовку невидимых шестиугольников
 
		switch (direction_of_motion)
		{
		case 1: x = x + 70; break;
		case 2: x = x + 35; y = y + 60; break;
		case 3: x = x - 35; y = y + 60; break;
		case 4: x = x - 70; break;
		case 5: x = x - 35; y = y - 60; break;
		case 6: x = x + 35; y = y - 60; break;
		case 7: y = y - 60; break;
		}
 
 
		counter_hexagons_in_row++;
		if (counter_hexagons_in_row == layer)
		{
			counter_hexagons_in_row = 0;
			direction_of_motion++;
			if (direction_of_motion == 8) direction_of_motion = 1;
		}
 
 
	}
}
 
// функция рисует шестиугольник, повернутый на угол Angle
void DrawObject(RenderWindow& window,int x, int y, int Angle)
{
 
	int rad = 35;
	hexagon.x1 = -sin(M_PI * Angle)*rad;
	hexagon.y1 = cos(M_PI * Angle)*rad;
	hexagon.x2 = -sin(M_PI * (Angle + 60))*rad;
	hexagon.y2 = cos(M_PI * (Angle + 60))*rad;
	hexagon.x3 = -sin(M_PI * (Angle + 120))*rad;
	hexagon.y3 = cos(M_PI * (Angle + 120))*rad;
	hexagon.x4 = -sin(M_PI * (Angle + 180))*rad;
	hexagon.y4 = cos(M_PI * (Angle + 180))*rad;
	hexagon.x5 = -sin(M_PI * (Angle + 240))*rad;
	hexagon.y5 = cos(M_PI * (Angle + 240))*rad;
	hexagon.x6 = -sin(M_PI * (Angle + 300))*rad;
	hexagon.y6 = cos(M_PI * (Angle + 300))*rad;
	ConvexShape convex;
	convex.setPointCount(6);
	convex.setPoint(0, sf::Vector2f(hexagon.x1 + x, hexagon.y1 + y));
	convex.setPoint(1, sf::Vector2f(hexagon.x2 + x, hexagon.y2 + y));
	convex.setPoint(2, sf::Vector2f(hexagon.x3 + x, hexagon.y3 + y));
	convex.setPoint(3, sf::Vector2f(hexagon.x4 + x, hexagon.y4 + y));
	convex.setPoint(4, sf::Vector2f(hexagon.x5 + x, hexagon.y5 + y));
	convex.setPoint(5, sf::Vector2f(hexagon.x6 + x, hexagon.y6 + y));
	window.draw(convex);
 
}