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

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

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

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

У меня проблема вот с этим: gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);. Вылезает ошибка: CS1061 "object" не содержит определения "GL_COLOR_BUFFER_BIT", и не удалось найти доступный метод расширения "GL_COLOR_BUFFER_BIT",...
Большое спасибо. Единственный код который прошел без каких либо ошибок. Ура!!!
Скажите пожалуйста, подскажите алгоритм по которому по заданным точкам можно определить тип многогранника, скажем это куб или прямоугольный параллелепипед. Нашел теорию по этим фигурам: https://www.mat... https://www.mat... Акцентировать внимание...
Всем у кого не работает. файл wizard.script Ещё одно упоминание Glut32 в строке "if (!VerifyLibFile(dir_nomacro_lib, _T("glut32"), _T("GLUT's"))) return false;" меняем на "if (!VerifyLibFile(dir_nomacro_lib, _T("freeglut"), _T("GLUT's"))) return...
Не получается, емаё

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

Рейтинг@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);
 
}