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

Вход на сайт

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

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

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

Не получается, емаё
огромное спасибо за подробное объяснение про 3д графику на питоне, в интернете очень мало подобной информации
dobryj den, popytalas otkryt prikreplionnyj fail ctoby posmotret kak rabotaet, no mne ego ne pokazyvaet vydajet osibku. Pochemu?
Очень интересно! ии сайт крутой жалко что умирает(
У Вас число превысит максимальное число int. Можно использовать в Вашем случае uint, но лучше все переписать на double.

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

Рейтинг@Mail.ru Яндекс.Метрика
Язык программирования: 
C#
Среда программирования: 
Microsoft Visual Studio 2013

using System;
using System.Drawing;
using System.Windows.Forms;
 
namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public int len; //длина стороны квадрата
        public int distance;// расстояние между квадратами
        public int quantity;//количество квадратов
        public int counter = 0;//счётчик сдвига
        public int dxy = 1;//величина сдвига
        public int color = 0, color2 = 0;//переменные, которые меняют цвет движущейся грани
        public int dcolor;//величина изменения цвета за смещение
        public int next_order = -1, cur_order = -1;//переменные хранят номер слоя движущихся квадратов
        public int[,] order;//массив очерёдности
        //массивы точек, определяющих соответствующие грани квадратов
        public PointF[,] left;
        public PointF[,] right;
        public PointF[,] top;
        public PointF[,] bottom;
        Color coltemp, coltemp2;//цвета движущихся квадратов
        Pen helppen, mainpen, temppen, temppen2;//окрашивание квадратов: helppen - не сдвинутые, temppen,temppen2 - двигающиеся, mainpen - сдвинутые
        Bitmap btmp;
        public Graphics g;
        public Form1()
        {
            InitializeComponent();
        }
        private void Loading(object sender, EventArgs e)//функция инициализации основных значений
        {
            len = 22;
            distance = len * 7 / 2;
            if (distance % 2 == 1)
                distance++;
            dcolor = 3;
            //предварительно определяем начальный и конечный цвет (после полного прохода они обновляются, установлены экспериментально)
            coltemp2 = Color.FromArgb(255, 80, 255, 50);
            helppen = new Pen(Color.FromArgb(255, 80 + 2 * 57, 198, 50), 3);
            mainpen = new Pen(coltemp2, 3);
            //определяем количество квадратов относительно размеров экрана
            quantity = pbox.Width / (len + distance / 2);
            // четное количество для корректного отображения
            if (quantity % 2 == 1)
                quantity++;
            //инициализируем и заполняем массивы координат
            left = new PointF[quantity, 2 * quantity];
            right = new PointF[quantity, 2 * quantity];
            top = new PointF[quantity, 2 * quantity];
            bottom = new PointF[quantity, 2 * quantity];
            int cm = -(quantity / 2 - 1) * (distance) - len / 2;// постоянный сдвиг (так как координаты смещены к центру picture Box)
            int sh = 0; // шахматный сдвиг
            for (int i = 0; i < quantity; i++)
                for (int j = 0; j < 2 * quantity; j++)
                {
                    if (j % 2 == 1)
                        sh += distance / 2;
                    else
                        sh -= distance / 2;
                    left[i, j].X = top[i, j].X = sh + cm + i * (distance);
                    left[i, j].Y = top[i, j].Y = cm + j * (distance / 2) - distance / 2;
                    right[i, j].X = bottom[i, j].X = sh + cm + i * (distance) + len;
                    right[i, j].Y = bottom[i, j].Y = cm + j * (distance / 2) + len - distance / 2;
                    top[i, j].X--;
                    bottom[i, j].X++;
                }
            Define_order();// определяем порядок движения квадратов
            timer1.Enabled = true;// включаем таймер
        }
        private void Define_order()
        {
            order = new int[quantity, 2 * quantity];//инициализируем массив
            int middle = quantity - 1;// находим "среднюю" строку
            for (int i = 0; i < quantity; i++)
                order[i, middle] = (int)Math.Abs(i - middle / 2);//заполняем эту строку от центра (0) к краям 
           //заполняем остальные элементы массива по четвертям
            for (int i = 0; i < quantity; i++)
            {
                int temp = order[i, middle];// значение в соответствующей "средней" строке
                if (i < quantity / 2)// левая половина
                {
                    for (int j = middle + 1; j < 2 * quantity - 1; j = j + 2)//нижняя половина
                    {
                        temp++;
                        order[i, j] = order[i, j + 1] = temp;
                    }
                     temp = order[i, middle];
                    for (int j = middle - 1; j >= 0; j -= 2)//верхняя
                    {
                        temp++;
                        order[i, j] = temp;
                        if (j > 0)
                            order[i, j - 1] = temp;
                    }
                }
                else //правая половина
                {
                    for (int j = middle; j < 2 * quantity - 1; j = j + 2)//нижняя 
                    {
                        order[i, j] = order[i, j + 1] = temp;
                        temp++;
                    }
                     temp = order[i, middle];
                     for (int j = middle; j > 0; j -= 2)//верхняя
                    {
                        order[i, j] = order[i, j - 1] = temp;
                        temp++;
                    }
                }
            }
        }
        private void Draw_square(int i, int j, Pen pen, int dif = 0)//рисуем отедльный квадрат, если dif=1, то происходит сдвиг
        {
            if (dif == 1)
            {
                g.DrawLine(pen, left[i, j].X, left[i, j].Y, left[i, j].X, left[i, j].Y + len+1);
                g.DrawLine(pen, right[i, j].X, right[i, j].Y, right[i, j].X, right[i, j].Y - len);
                g.DrawLine(pen, top[i, j].X, top[i, j].Y, top[i, j].X + len, top[i, j].Y);
                g.DrawLine(pen, bottom[i, j].X, bottom[i, j].Y, bottom[i, j].X - len, bottom[i, j].Y);
                //запоминаем новые координаты точек
                left[i, j].X -= dxy;
                right[i, j].X += dxy;
                top[i, j].Y -= dxy;
                bottom[i, j].Y += dxy;
            }
            else
            {
                g.DrawLine(pen, left[i, j].X, left[i, j].Y, left[i, j].X, left[i, j].Y + len);
                g.DrawLine(pen, right[i, j].X, right[i, j].Y, right[i, j].X, right[i, j].Y - len);
                g.DrawLine(pen, top[i, j].X, top[i, j].Y, top[i, j].X + len+2, top[i, j].Y);
                g.DrawLine(pen, bottom[i, j].X, bottom[i, j].Y, bottom[i, j].X - len-2, bottom[i, j].Y);
            }
        }
        private void Draw()
        {
            btmp = new Bitmap(pbox.Width, pbox.Height);
            g = Graphics.FromImage(btmp);
            g.TranslateTransform((float)pbox.Width / 2, (float)pbox.Height / 2);//сдвигаем начало координат в центр
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
            for (int i = 0; i < quantity; i++)//обход всех точек для прорисовки
            {
                for (int j = 0; j < 2 * quantity; j++)
                {
                    if (order[i, j] < cur_order)// если точка в предыдущем слое(уже сдвинута)
                        Draw_square(i, j, helppen);
                    else if (order[i, j] == cur_order)// если точка в текущем слое
                        Draw_square(i, j, temppen, 1);// рисуем с меняющимся цветом и сдвигом
                    if (next_order <= cur_order)// если не начато движение следующего
                    {
                        if (order[i, j] > cur_order)
                            Draw_square(i, j, mainpen);// рисуем следующие слои старым цветом
                    }
                    else //если началось движение следующего слоя (next_order)
                    {
                        if (order[i, j] == next_order)
                            Draw_square(i, j, temppen2, 1);// сдвигаем и меняем цвет для движущегося квадрата
                        else if (order[i, j] > next_order)
                            Draw_square(i, j, mainpen);// остальные без изменений
                    }
                }
            }
            pbox.BackgroundImage = btmp;
        }
        private void timer1_Tick(object sender, EventArgs e)//таймер изменяет счётчик и позволяет квадратам двигаться 
        {
            if (counter > (len / 2 + 1) / 2)//если счётчик больше
            {
                next_order = cur_order + 1;// начинаем двигать следующий слой
                if (counter > len / 2)// если счётчик больше
                {
                    counter = 0;// обнуляем
                    cur_order++;// текущий слой меняется
                }
            }
            if (counter == (len / 2 + 1) / 2)
                color2 = 0;//обнуляем цвет для нового движения
            else if (counter == 0)
                color = color2;// меняется слой (был next_order, стал cur_order), цвет продолжает изменятся с этого значения
            color += dcolor;
            color2 += dcolor;
            if (dxy > 0)//если движемся от зелёного к желтому
            {
                coltemp = Color.FromArgb(255, 80 + 2 * color, 255 - color, 50);
                coltemp2 = Color.FromArgb(255, 80 + 2 * color2, 255 - color2, 50);
            }
            else//от желтого к зелёному
            {
                coltemp = Color.FromArgb(255, 190 - 2 * color, 195 + color, 50);
                coltemp2 = Color.FromArgb(255, 190 - 2 * color2, 195 + color2, 50);
            }
            if (cur_order > quantity - 1)//реверс, замена цветов mainpen и helppen
            {
                dxy = -dxy;
                // сбрасываем счётчик слоёв
                cur_order = -1;
                next_order = -1;
                // меняем цвета
                temppen = mainpen;
                mainpen = helppen;
                helppen = temppen;
            }
            temppen = new Pen(coltemp, 3);
            temppen2 = new Pen(coltemp2, 3);
            counter++;
            Draw();//функция отрисовки
        }
        private void Click_pbox(object sender, EventArgs e)
        {
            if (timer1.Enabled == true)
            {
                timer1.Stop();
            }
            else
                timer1.Start();
        }// позволяет нажать паузу
    }
}

Прикрепленный файлРазмер
Martyniuk_-_digital_squares.rar97.27 кб