Processing:Примеры/Силы (гравитация и сопротивление жидкости) с векторами
Материал из Онлайн справочника
Перейти к навигацииПерейти к поиску
Содержание | Среда разработки Processing | Справочник языка Processing | Библиотеки | Примеры | Режимы программирования |
Перевод: Максим Кузьмин
Проверка/Оформление/Редактирование: Мякишев Е.А.
Описание[1]
Демонстрация воздействия на тела (класс Mover) двух разных сил. На тела постоянно воздействует сила притяжения (гравитация), но после попадания в «воду» на них также начинает воздействовать сопротивление жидкости.
Об основах работы с PVector читайте тут, а также на странице «Примеры» в разделе «Векторы».
Пример
// пять падающих тел:
Mover[] movers = new Mover[10];
// жидкость:
Liquid liquid;
void setup() {
size(640, 360);
reset();
// создаем «воду»:
liquid = new Liquid(0, height/2, width, height/2, 0.1);
}
void draw() {
background(0);
// рисуем «воду»:
liquid.display();
for (Mover mover : movers) {
// находится ли тело в жидкости?
if (liquid.contains(mover)) {
// рассчитываем силу сопротивления:
PVector drag = liquid.drag(mover);
// применяем силу сопротивления к падающему телу:
mover.applyForce(drag);
}
// рассчитываем гравитацию на основе массы объекта:
PVector gravity = new PVector(0, 0.1*mover.mass);
// применяем гравитацию:
mover.applyForce(gravity);
// обновляем экран:
mover.update();
mover.display();
mover.checkEdges();
}
fill(255);
text("click mouse to reset", 10, 30);
// "кликните мышкой, чтобы сбросить результаты"
}
void mousePressed() {
reset();
}
// перезапускаем все объекты Mover,
// задавая всем им случайный размер:
void reset() {
for (int i = 0; i < movers.length; i++) {
movers[i] = new Mover(random(0.5, 3), 40+i*70, 0);
}
}
/**
* Силы (гравитация и сопротивление жидкости) с векторами
* Автор – Дэниэл Шиффман.
*
* Демонстрация воздействия на тела (класс Mover) разных сил.
* Тела постоянно подвергаются силе притяжения.
* Попадая в «воду», тела начинают испытывать сопротивление жидкости.
*/
class Mover {
// позиция, скорость и ускорение:
PVector position;
PVector velocity;
PVector acceleration;
// значение массы привязано к размеру тела:
float mass;
Mover(float m, float x, float y) {
mass = m;
position = new PVector(x, y);
velocity = new PVector(0, 0);
acceleration = new PVector(0, 0);
}
// второй закон Ньютона: F = M * A, т.е. сила, действующая на тело,
// равна произведению массы тела на сообщаемое этой силой ускорение
// (или A = F / M):
void applyForce(PVector force) {
// делим силу на массу:
PVector f = PVector.div(force, mass);
// задаем ускорению значение, рассчитанное выше:
acceleration.add(f);
}
void update() {
// скорость меняется в зависимости от ускорения:
velocity.add(acceleration);
// позиция меняется с помощью скорости:
position.add(velocity);
// с каждым кадром ускорение нужно удалять:
acceleration.mult(0);
}
// рисуем объект Mover:
void display() {
stroke(255);
strokeWeight(2);
fill(255, 200);
ellipse(position.x, position.y, mass*16, mass*16);
}
// рассчитываем столкновение тела с дном:
void checkEdges() {
if (position.y > height) {
velocity.y *= -0.9; // небольшое затухание
// при столкновении с дном
position.y = height;
}
}
}
/**
* Силы (гравитация и сопротивление жидкости) с векторами
* Автор – Дэниэл Шиффман.
*
* Демонстрация воздействия на тела (класс Mover) разных сил.
* Тела постоянно подвергаются силе притяжения.
* Попадая в «воду», тела начинают испытывать сопротивление жидкости.
*/
// класс Liquid:
class Liquid {
// «вода» - это прямоугольник:
float x, y, w, h;
// коэффициент сопротивления:
float c;
Liquid(float x_, float y_, float w_, float h_, float c_) {
x = x_;
y = y_;
w = w_;
h = h_;
c = c_;
}
// объект Mover находится в воде?
boolean contains(Mover m) {
PVector l = m.position;
if (l.x > x && l.x < x + w && l.y > y && l.y < y + h) {
return true;
} else {
return false;
}
}
// рассчитываем сопротивление жидкости:
PVector drag(Mover m) {
// рассчитываем сопротивление,
// умножая коэффициент сопротивления на квадрат скорости:
float speed = m.velocity.mag();
float dragMagnitude = c * speed * speed;
// задаем направление вектору сопротивления жидкости,
// инвертируя направление движения (скорость) падающего тела:
PVector drag = m.velocity.copy();
drag.mult(-1);
// присваиваем направлению движения (drag)
// значение сопротивления жидкости (dragMagnitude):
drag.setMag(dragMagnitude);
return drag;
}
void display() {
noStroke();
fill(127);
rect(x, y, w, h);
}
}
См.также
Внешние ссылки
Примеры на Processing | |
---|---|
Основы |
|
Продвинутые графические эффекты |
|
Примеры из сторонних библиотек |