Cat hungry.png
Здравствуйте! Собираем деньги на перевод материалов по электронике(https://www.allaboutcircuits.com/education/). Реквизиты указаны здесь.

Processing:Примеры/Силы (гравитация и сопротивление жидкости) с векторами

Материал из Онлайн справочника
Перейти к: навигация, поиск


Перевод: Максим Кузьмин (Cubewriter)
Перевел 2686 статей для сайта.

Контакты:

Проверка/Оформление/Редактирование: Мякишев Е.А.


Ambox content.png Черновик


Описание[1]

Демонстрация воздействия на тела (класс Mover) двух разных сил. На тела постоянно воздействует сила притяжения (гравитация), но после попадания в «воду» на них также начинает воздействовать сопротивление жидкости.

Об основах работы с PVector читайте тут, а также на странице «Примеры» в разделе «Векторы».

Пример

  1. // пять падающих тел:
  2. Mover[] movers = new Mover[10];
  3.  
  4. // жидкость:
  5. Liquid liquid;
  6.  
  7. void setup() {
  8.   size(640, 360);
  9.   reset();
  10.   // создаем «воду»:
  11.   liquid = new Liquid(0, height/2, width, height/2, 0.1);
  12. }
  13.  
  14. void draw() {
  15.   background(0);
  16.  
  17.   // рисуем «воду»:
  18.   liquid.display();
  19.  
  20.   for (Mover mover : movers) {
  21.  
  22.     // находится ли тело в жидкости?
  23.     if (liquid.contains(mover)) {
  24.       // рассчитываем силу сопротивления:
  25.       PVector drag = liquid.drag(mover);
  26.       // применяем силу сопротивления к падающему телу:
  27.       mover.applyForce(drag);
  28.     }
  29.  
  30.     // рассчитываем гравитацию на основе массы объекта:
  31.     PVector gravity = new PVector(0, 0.1*mover.mass);
  32.     // применяем гравитацию:
  33.     mover.applyForce(gravity);
  34.  
  35.     // обновляем экран:
  36.     mover.update();
  37.     mover.display();
  38.     mover.checkEdges();
  39.   }
  40.  
  41.   fill(255);
  42.   text("click mouse to reset", 10, 30);
  43.    //  "кликните мышкой, чтобы сбросить результаты"
  44. }
  45.  
  46. void mousePressed() {
  47.   reset();
  48. }
  49.  
  50. // перезапускаем все объекты Mover,
  51. // задавая всем им случайный размер:
  52. void reset() {
  53.   for (int i = 0; i < movers.length; i++) {
  54.     movers[i] = new Mover(random(0.5, 3), 40+i*70, 0);
  55.   }
  56. }
  57.  
  58.  
  59. /**
  60.  * Силы (гравитация и сопротивление жидкости) с векторами
  61.  * Автор – Дэниэл Шиффман.  
  62.  *
  63.  * Демонстрация воздействия на тела (класс Mover) разных сил.
  64.  * Тела постоянно подвергаются силе притяжения.
  65.  * Попадая в «воду», тела начинают испытывать сопротивление жидкости.
  66.  */
  67.  
  68.  
  69. class Mover {
  70.  
  71.   // позиция, скорость и ускорение:
  72.   PVector position;
  73.   PVector velocity;
  74.   PVector acceleration;
  75.  
  76.   // значение массы привязано к размеру тела:
  77.   float mass;
  78.  
  79.   Mover(float m, float x, float y) {
  80.     mass = m;
  81.     position = new PVector(x, y);
  82.     velocity = new PVector(0, 0);
  83.     acceleration = new PVector(0, 0);
  84.   }
  85.  
  86.   // второй закон Ньютона: F = M * A, т.е. сила, действующая на тело,
  87.   // равна произведению массы тела на сообщаемое этой силой ускорение
  88.   // (или A = F / M):
  89.   void applyForce(PVector force) {
  90.     // делим силу на массу:
  91.     PVector f = PVector.div(force, mass);
  92.     // задаем ускорению значение, рассчитанное выше:
  93.     acceleration.add(f);
  94.   }
  95.  
  96.   void update() {
  97.  
  98.     // скорость меняется в зависимости от ускорения:
  99.     velocity.add(acceleration);
  100.     // позиция меняется с помощью скорости:
  101.     position.add(velocity);
  102.     // с каждым кадром ускорение нужно удалять:
  103.     acceleration.mult(0);
  104.   }
  105.  
  106.   // рисуем объект Mover:
  107.   void display() {
  108.     stroke(255);
  109.     strokeWeight(2);
  110.     fill(255, 200);
  111.     ellipse(position.x, position.y, mass*16, mass*16);
  112.   }
  113.  
  114.   // рассчитываем столкновение тела с дном:
  115.   void checkEdges() {
  116.     if (position.y > height) {
  117.       velocity.y *= -0.9;  // небольшое затухание
  118.                            // при столкновении с дном
  119.       position.y = height;
  120.     }
  121.   }
  122. }
  123.  
  124.  
  125. /**
  126.  * Силы (гравитация и сопротивление жидкости) с векторами
  127.  * Автор – Дэниэл Шиффман.
  128.  *
  129.  * Демонстрация воздействия на тела (класс Mover) разных сил.
  130.  * Тела постоянно подвергаются силе притяжения.
  131.  * Попадая в «воду», тела начинают испытывать сопротивление жидкости.
  132.  */
  133.  
  134. // класс Liquid:
  135. class Liquid {
  136.  
  137.  
  138.   // «вода» - это прямоугольник:
  139.   float x, y, w, h;
  140.   // коэффициент сопротивления:
  141.   float c;
  142.  
  143.   Liquid(float x_, float y_, float w_, float h_, float c_) {
  144.     x = x_;
  145.     y = y_;
  146.     w = w_;
  147.     h = h_;
  148.     c = c_;
  149.   }
  150.  
  151.   // объект Mover находится в воде?
  152.   boolean contains(Mover m) {
  153.     PVector l = m.position;
  154.     if (l.x > x && l.x < x + w && l.y > y && l.y < y + h) {
  155.       return true;
  156.     } else {
  157.       return false;
  158.     }
  159.   }
  160.  
  161.   // рассчитываем сопротивление жидкости:
  162.   PVector drag(Mover m) {
  163.     // рассчитываем сопротивление,
  164.     // умножая коэффициент сопротивления на квадрат скорости:
  165.     float speed = m.velocity.mag();
  166.     float dragMagnitude = c * speed * speed;
  167.  
  168.     // задаем направление вектору сопротивления жидкости,
  169.     // инвертируя направление движения (скорость) падающего тела:
  170.     PVector drag = m.velocity.copy();
  171.     drag.mult(-1);
  172.  
  173.     // присваиваем направлению движения (drag)
  174.     // значение сопротивления жидкости (dragMagnitude):
  175.     drag.setMag(dragMagnitude);
  176.     return drag;
  177.   }
  178.  
  179.   void display() {
  180.     noStroke();
  181.     fill(127);
  182.     rect(x, y, w, h);
  183.   }
  184. }

См.также

Внешние ссылки

  1. processing.org - Forces (Gravity and Fluid Resistence) with Vectors by Daniel Shiffman.