Задача 2. Остывание "чашки кофе" - по книге
Гулда и
Тобочника
"Компьютерное моделирование в физике".
* Гулд Х., Я.Тобочник. Компьютерное моделирование в физике. Том 1 . с. 25
Вид экрана:

Программа:
/**
* Моделирование остывания кофе (только график)
* dT/dt = -k*(T - T_room)
* Гулд Х., Я.Тобочник. Компьютерное моделирование в физике. Том 1 . с. 25
*/
import controlP5.*;
ControlP5 cp5;
float T_coffee = 90.0; // Начальная температура (°C)
float T_room = 22.0; // Температура комнаты (°C)
float k = 0.01; // Коэффициент охлаждения
float time = 0; // Время (минуты)
ArrayList<PVector> dataPoints = new ArrayList<PVector>();
void setup() {
size(1000, 600);
smooth();
// Настройка интерфейса
cp5 = new ControlP5(this);
textSize(26);
cp5.addSlider("T_coffee")
.setPosition(630, 130)
.setSize(200, 20)
.setRange(0, 100)
.setValue(90)
.setLabel(" Initial T (°C)");
cp5.addSlider("T_room")
.setPosition(630, 170)
.setSize(200, 20)
.setRange(0, 30)
.setValue(22)
.setLabel(" Room T (°C)");
cp5.addSlider("k")
.setPosition(630, 210)
.setSize(200, 20)
.setRange(0.001, 0.05)
.setValue(0.01)
.setLabel(" Thermal conductivity (k)");
cp5.addButton("reset")
.setPosition(630, 250)
.setSize(100, 30)
.setLabel("reset");
}
void draw() {
background(255);
// Расчет температуры (метод Эйлера)
float dT = -k * (T_coffee - T_room);
T_coffee += dT;
if (time < 100) {
time += 0.1;
}
// Сохранение данных
dataPoints.add(new PVector(time, T_coffee));
// Отрисовка графика
drawGraph();
// Вывод данных
fill(0);
textSize(26);
text("Остывание кофе по закону Ньютона", 600, 80);
textSize(16);
text("Температура кофе: " + nf(T_coffee, 0, 1) + " °C", 450, 230);
text("Время остывания: " + nf(time, 0, 1) + " мин", 450, 260);
textSize(15);
text("dT/dt = -k*(T - T_room)", 400, 120);
textSize(12);
text("комната, °C:" , 830, 119);
text("кофе, °C:" , 830, 160);
text("теплопроводность, k:", 830, 199);
}
void drawGraph() {
// Оси графика
stroke(0);
line(100, 100, 100, height-100); // Ось Y (температура)
line(100, height-100, width-100, height-100); // Ось X (время)
// Разметка оси X (время)
textAlign(CENTER, TOP);
for (int i=0; i<=10; i++) {
float x = map(i, 0, 10, 100, width-100);
line(x, height-100, x, height-95);
text(i*10, x, height-80); // Метки 0,10,20...100 минут
}
text("Время (минуты)", width/2, height-60);
// Разметка оси Y (температура 0-100°C)
textAlign(RIGHT, CENTER);
for (int i=0; i<=10; i++) {
float temp = i * 10; // 0,10,20...100°C
float y = map(temp, 0, 100, height-100, 100);
line(95, y, 100, y);
text(nf(temp,0,0), 90, y);
// Выделение комнатной температуры красным
if (abs(temp - T_room) < 0.1) {
fill(255, 0, 0);
text(nf(temp,0,0), 90, y);
fill(0);
}
}
pushMatrix();
translate(30, height/2);
rotate(-HALF_PI);
text("Температура (°C)", 0, 0);
popMatrix();
// Кривая охлаждения
stroke(200, 100, 0);
strokeWeight(2);
noFill();
beginShape();
for (PVector p : dataPoints) {
float x = map(p.x, 0, 100, 100, width-100);
float y = map(p.y, 0, 100, height-100, 100);
vertex(x, y);
}
endShape();
// Текущая точка
float currentX = map(time, 0, 100, 100, width-100);
float currentY = map(T_coffee, 0, 100, height-100, 100);
fill(200, 100, 0);
noStroke();
ellipse(currentX, currentY, 8, 8);
// Горизонтальная линия комнатной температуры
stroke(255, 0, 0, 100);
float roomY = map(T_room, 0, 100, height-100, 100);
line(100, roomY, width-100, roomY);
}
void reset() {
time = 0;
dataPoints.clear();
T_coffee = cp5.getController("T_coffee").getValue();
T_room = cp5.getController("T_room").getValue();
k = cp5.getController("k").getValue();
}
