Двумерная диффузия

Автор: Пользователь скрыл имя, 24 Ноября 2012 в 20:21, курсовая работа

Описание работы

Клеточный автомат – дискретная динамическая система, представляющая собой совокупность одинаковых клеток, одинаково соединенных между собой. Пространство, время и состояние этой системы дискретны. Все клетки образуют так называемую решетку клеточного автомата. Эти решетки могут быть разных типов и отличаться как по размерности, так и по форме клеток.

Содержание

Введение 6
1. Постановка и анализ задачи 7
1.1. Постановка задачи 7
1.2. Анализ задачи 7
2. Процесс проектирования 8
2.1. Диаграмма вариантов использования 8
2.2. Диаграмма деятельности 9
3. Описание реализации 10
4. Тестирование программы 11
Заключение 14
Список литературы 15

Работа содержит 1 файл

Двумерная диффузия.docx

— 227.66 Кб (Скачать)

 

Листинг программы

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;

 

namespace diffusion

{

    public partial class MainForm : Form

    {

 

        private int[,] field = new int[200, 200];   // Поле для диффузии

                                                    // 0 - пусто, 1 - частица

        double percent = 0;                         // Вероятность переещения частицы

        int nSteps = 0;                             // Количество шагов диффузии

        int curStep = 0;                            // Текущий шаг

        Random randomizer = new Random();           // Генератор случайных чисел

 

        // Инициализация  поля

        private void initField()

        {

            for (int i = 0; i < 200; i++)

                for (int j = 0; j < 200; j++)

                    if ((i >= 50) && (i < 150) && (j >= 50) && (j < 150))   // Создаём посередине

                        field[i, j] = 1;                                    // Черный квадрат

                    else

                        field[i, j] = 0;

        }

 

        // Отрисовка поля

        void updateImage()

        {

            int startX = workArea.Width/4; // Позиция, начиная с которой

            int startY = workArea.Height / 5;  // Будет отобажаться поле

            Bitmap image = new Bitmap(workArea.Width, workArea.Height); // Создаём пустое изображение

 

            using (Graphics gr = Graphics.FromImage(image)) // Создаём объект для рисования

            {

                               

                Rectangle rect = new Rectangle(startX, startY, field.GetLength(0), field.GetLength(1));

                gr.FillRectangle(new SolidBrush(Color.White), rect);    // Заливем все белым цветом

               

            }

 

            // Проходим каждый элемент поля

            for (int i = 0; i < field.GetLength(0); i++)

                for (int j = 0; j < field.GetLength(1); j++)

                    if (field[i, j] == 1)   // И если в элементе не пусто

                        image.SetPixel(i + startX, j + startY, Color.Black);    // Ставим черную точку

 

            workArea.Image = image; // Переносим изображение на рабочую область

            workArea.Refresh();     // И обновляе картинку

        }

 

        // Шаг  диффузии

        void doStep()

        {

            // Создаём ещё одно новое временное  поле

            int[,] newField = new int[field.GetLength(0), field.GetLength(1)];

 

            // Копируем старое поле в новое

            for (int i = 0; i < field.GetLength(0); i++)

                for (int j = 0; j < field.GetLength(1); j++)

                    newField[i, j] = field[i, j];

 

            // Для каждого элемента поля

            for (int i = 0; i < field.GetLength(0); i++)

                for (int j = 0; j < field.GetLength(1); j++)

                    if (field[i, j] == 1)   // Если в этом елементе есть частица

                        if (randomizer.NextDouble() < percent)  // с вероятностью percent

                        {

                            // Перемещаем частицу

                            List<Point> plist = new List<Point>();  // Создаем список возможных ходов

                            // И проверяем все возможные ходы

                            if (i > 0)  // и граничные условия

                                if (newField[i - 1, j] == 0)    // Если можно переместить точку сюда

                                    plist.Add(new Point(i - 1, j)); // Добавляем ход в список

                            if (j > 0)

                                if (newField[i, j - 1] == 0)

                                    plist.Add(new Point(i, j - 1));

                            if (i < field.GetUpperBound(0))

                                if (newField[i + 1, j] == 0)

                                    plist.Add(new Point(i + 1, j));

                            if (j < field.GetUpperBound(1))

                                if (newField[i, j + 1] == 0)

                                    plist.Add(new Point(i, j + 1));

                            if (plist.Count == 0)

                                continue;

                            Point p = plist[randomizer.Next(plist.Count)];  // Выбираем случайный ход

                            newField[i, j] = 0; // И меняем местами

                            newField[p.X, p.Y] = 1; // точки

                        }

 

            field = newField;   // Новое поле переносим в старое

            updateImage();      // И обновляем изображение

        }

 

        public MainForm()

        {

            InitializeComponent();

            initField();    // Инициализируем поле

            updateImage();  // Обновляем картинку

        }

 

        // Нажатие кнопки "Начать"

        private void beginButton_Click(object sender, EventArgs e)

        {

            if (timer1.Enabled) // Если тамйер включен

            {

                timer1.Enabled = false; // выключаем таймер

                beginButton.Text = "Начать";    // Меняем текст кнопки

                this.Text = "Диффузия"; // И формы

            }

            else // В противном случае

            {

                // Получаем значение вероятности  диффузии

                if (!double.TryParse(diffPercent.Text, out percent) || (percent < 0) || (percent > 100))

                {

                    // Если зачение некорректно

                    diffPercent.Focus();

                    diffPercent.SelectAll();    // Выделяем его

                    return; // И выходим

                }

                percent /= 700;

 

                // Получаем количество шагов

                if (!int.TryParse(stepsNumber.Text, out nSteps))

                {

                    stepsNumber.Focus();

                    stepsNumber.SelectAll();

                    return;

                }

 

                curStep = 0;    // Текщий шаг пока что нулевой

 

                initField();    // Иницилизируем поле

 

                timer1.Enabled = true;  // Включаем таймер

                beginButton.Text = "Стоп";  // Меняем текст кнопки

            }

        }

 

        private void diffPercent_Leave(object sender, EventArgs e)

        {

            double temp;

 

            // Проверяем значение на корректность

            if (!double.TryParse(diffPercent.Text, out temp))

            {

                diffPercent.Focus();

                diffPercent.SelectAll();

            }

        }

 

        private void stepsNumber_Leave(object sender, EventArgs e)

        {

            int temp;

 

            // Проверяем значение на корректность

            if (!int.TryParse(stepsNumber.Text, out temp))

            {

                stepsNumber.Focus();

                stepsNumber.SelectAll();

            }

        }

 

        // Тик таймера

        private void timer1_Tick(object sender, EventArgs e)

        {

            doStep();   // Производим шаг диффузии

            if (++curStep == nSteps)    // Если выполнено необходимое количество шагов

            {

                timer1.Enabled = false; // Выключаем таймер

                beginButton.Text = "Начать";    // Меняем текст кнопки

                this.Text = "Диффузия";         // И формы

                return;

            }

            // Меняем текст формы

            this.Text = "Диффузия (Шаг " + Convert.ToString(curStep) + " из " + Convert.ToString(nSteps) + ")";

        }

    }

}


Информация о работе Двумерная диффузия