Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Проект5.docx
Скачиваний:
10
Добавлен:
11.04.2015
Размер:
571.96 Кб
Скачать

5.9 Открываем клавишей f12 окно кода программы Unit3.Cpp. И в конструкторе формы запишем ниже приведенный текст функции.

// Это дописываем в код программы

TForm1 *Form1;

struct Molecule

{

Int X, y;// : Integer;

Int VX, Vy ;//: Integer;

};

bool IsRunning = false;

_fastcall TForm1::TForm1(TComponent* Owner)

: TForm(Owner)

{

TLeft->Caption = "0";

TRight->Caption= "0";

StartStopBtn->Caption="Пуск";

}

Запустили проект на выполнение, проверили как изменились надписи на метках и кнопке.

5.10 Помимо разных скоростей, неплохо бы задать для горячих и холодных молекул разные радиусы, чтобы их можно было легко различать. Самый простой способ, это разделить содержимое массива на две одинаковые части. Левую половину в массиве Mol холодными, а вторую – горячими.

Открываем двумя щелчками мыши заготовку для кода программы на кнопке Пуск.

void __fastcall TForm3::StartStopBtnClick(TObject *Sender)

{

сonst int RCold = 7; // радиус холодных молекул

const int RHot = 3; //радиус горячих молекул

const int VHot = 10; //скорость горячих молекул

const int VCold = 5; // скорость холодных молекул

const int RHole = 10; // расстояние отверстия в перегородке

const int N = 20; // количество молекул в одной половине аквариума

float angle ; // угол отклонения

int i ;

Molecule Mol [2*N]; // массив молекул удвоенный, то есть всего 40 молекул

int Lb, Rb; // расстояние в пикселях для левой и правой границ

int V , R ; // скорость и радиус молекул

int N1, N2 ; // количество горячих и холодных молекул

if (IsRunning)

{

IsRunning = false;

StartStopBtn->Caption = "Пуск";

return;

}

StartStopBtn->Caption = "Стоп";

TLeft->Caption = "0";

TRight->Caption= "0";

IsRunning = true;

randomize();

Screen->Refresh();

N1 = N * VCold;

N2 = N * VHot;

Тогда цикл определения исходных молекул на псевдокоде будет выглядеть так:

for( i=0; i<2*N;i++)

{

if ( i<N)

{

Выбрать случайную точку в левой части аквариума

Нарисовать молекулу, задав для неё маленькую скорость и большой радиус

}

else

{

Выбрать случайную точку в правой части аквариума

Нарисовать молекулу, задав для неё большую скорость и маленький радиус

}

Выбрать для молекулы случайное направление

Записать данные молекулы в Mol[i]

}

На языке С++ это выглядит так:

for(i = 0;i<2*N; i++)

{

if (i < N)

{ Lb = RCold; Rb = Screen->Width / 2 - RCold;

V = VCold; R= RCold; }

else

{ Lb = Screen->Width / 2 + RHot; Rb = Screen->Width - RHot;

V = VHot; R = RHot; }

Mol[i].X = RandomRange(Lb, Rb);

Mol[i].Y = RandomRange(R, Screen->Height - R);

angle = random(360)* M_PI /180;

Mol[i].Vx = floor(V * sin(angle));

Mol[i].Vy = floor(V * cos(angle));

}

while(IsRunning)

{ // код «Идеальный газ»

……………….// код 5.10.1—5.10.6

// код «Идеальный газ»

Sleep(10);

Application->ProcessMessages();

}

5.10.1 Тот же прием используется дальше – во время операций стирания/рисования молекул. Если текущее значение переменной цикла меньше или равно N, то нам известно, что радиус молекулы большой, иначе маленький.

5.10.2 Вывести значения температур проще всего в двух элементах TLabel. В нашем случае в качестве температуры вполне сгодится сумма скоростей молекул, находящихся в интересующей нас половине. Изначально температура холодного газа равна N*V_холодного_молекулы, а горячего –N*V_горячей_молекулы. Если какая-нибудь молекула перелетает в другую половину аквариума, то температура первой уменьшается на скорость молекулы, температура второй же увеличивается на то же число.

5.10.3 Не забудем, что при выводе числа в метку( строку) необходимо преобразовать его, используя функцию преобразования из ЦелогочислаВСтроку : IntToStr(число).

5.10.4 Теперь проясним ситуацию с перегородкой. Линия прорисовывается методами:

где параметры а-координаты X, b- координаты Y

Pen->Color= clBlack; // устанавливается цвет линии, черный, можно поменять на любой другой.

MoveTo(a,b); // координаты начала линии

LineTo(a,b); // координаты окончания линии

Линии в середине аквариума надо перерисовывать в каждой итерации цикла while(IsRunning), так как пролетающие молекулы стирают её.

5.10.5 Когда молекула подлетает к перегородке, необходимо как-то определить, что с ней произойдет дальше: перелетит ли она в другую половину аквариума или отразится от перегородки назад . Напоминаем, что в процессе работы с молекулой мы сначала её стираем, потом вычисляем новые координаты, рисуем на новом месте, но прежде теперь надо проверить не произошло ли столкновение с перегородкой. Если такое случилось, то его надо обработать, т.е. молекула должна отлететь от перегородки в обратную сторону, аналогично того как это происходило при встрече со стенками всего аквариума.

ЕСЛИ молекула находится в правой части аквариума, но при этом на предыдущей итерации моделирования молекула была в его левой части

ЕСЛИ молекула находится на уровне отверстия в перегородке

То молекула перелетает из левой части аквариума в правую

ИНАЧЕ

Молекула отлетает от перегородки назад в левую часть

ИНАЧЕ

ЕСЛИ молекула находится в левой части аквариума, но при этом на предыдущей итерации моделирования молекула была в его правой части

ЕСЛИ молекула находится на уровне отверстия в перегородке

То молекула перелетает из правой части аквариума в левую

ИНАЧЕ

Молекула отлетает от перегородки назад в правую часть

На языке С++ это выглядит так

if (Mol[i].X > Screen->Width / 2 - R && Mol[i].X - Mol[i].Vx <= Screen->Width / 2 - R)

{

if (Mol[i].Y >= Screen->Height / 2 - RHole && Mol[i].Y <= Screen->Height / 2 + RHole)

{ N1 = N1 - V; // молекула перелетает, температура изменяется

N2 = N2 + V;

}

else

{ Mol[i].X = Screen->Width / 2 - R; // молекула отражается

Mol[i].Vx = -Mol[i].Vx;

}

}

else

if (Mol[i].X < Screen->Width / 2 + R && Mol[i].X - Mol[i].Vx >= Screen->Width / 2 + R)

{

if (Mol[i].Y >= Screen->Height / 2 - RHole && Mol[i].Y <= Screen->Height / 2 + RHole)

{ N2 = N2 - V; N1 = N1 + V; }

else

{ Mol[i].X = Screen->Width / 2 + R; Mol[i].Vx = -Mol[i].Vx; }

}

5.10.6 Следующие строки дописываем в конце цикла while(IsRunning)

Screen->Canvas->Pen->Color= clBlack;

Screen->Canvas->MoveTo(Screen->Width / 2, 0);

Screen->Canvas->LineTo(Screen->Width / 2, Screen->Height / 2 - RHole);

Screen->Canvas->MoveTo(Screen->Width / 2, Screen->Height / 2 + RHole);

Screen->Canvas->LineTo(Screen->Width / 2, Screen->Height);

TLeft->Caption = IntToStr(N1);

TRight->Caption= IntToStr(N2);

5.11 Объедините код тела цикла из программы «Идеальный газ», добавьте в него фрагменты 5.10.1 - 5.10.6

while(IsRunning)

{

}

Откомпилируйте и запустите программу, работа программы соответствует рисунку приведенному ниже.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]