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

Processing:Примеры/Неперпендикулярное отражение 1

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


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

Контакты:

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


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


Описание[1]

Этот скетч-пример основан на уравнении R = 2N(N*L)-L, где R – это вектор отражения, N – это нормаль, а L – это вектор столкновения.

Пример

  1. // позиция левого края «земли»:
  2. PVector base1;
  3. // позиция правого края «земли»:
  4. PVector base2;
  5. // длина «земли»:
  6. float baseLength;
  7.  
  8. // массив с точками (координатами) вдоль линии «земли»:
  9. PVector[] coords;
  10.  
  11. // переменные для двигающегося шара:
  12. PVector position;
  13. PVector velocity;
  14. float r = 6;
  15. float speed = 3.5;
  16.  
  17. void setup() {
  18.   size(640, 360);
  19.  
  20.   fill(128);
  21.   base1 = new PVector(0, height-150);
  22.   base2 = new PVector(width, height);
  23.   createGround();
  24.  
  25.   // начальная позиция шара – вверху посередине экрана:
  26.   position = new PVector(width/2, 0);
  27.  
  28.   // рассчитываем начальную случайную скорость:
  29.   velocity = PVector.random2D();
  30.   velocity.mult(speed);
  31. }
  32.  
  33. void draw() {
  34.   // рисуем фон:
  35.   fill(0, 12);
  36.   noStroke();
  37.   rect(0, 0, width, height);
  38.  
  39.   // рисуем «землю»:
  40.   fill(200);
  41.   quad(base1.x, base1.y, base2.x, base2.y, base2.x, height, 0, height);
  42.  
  43.   // рассчитываем нормаль:
  44.   PVector baseDelta = PVector.sub(base2, base1);
  45.   baseDelta.normalize();
  46.   PVector normal = new PVector(-baseDelta.y, baseDelta.x);
  47.  
  48.   // рисуем шар:
  49.   noStroke();
  50.   fill(255);
  51.   ellipse(position.x, position.y, r*2, r*2);
  52.  
  53.   // двигаем шар:
  54.   position.add(velocity);
  55.  
  56.   // делаем вектор столкновения единичным:
  57.   PVector incidence = PVector.mult(velocity, -1);
  58.   incidence.normalize();
  59.  
  60.   // определяем и обрабатываем столкновение:
  61.   for (int i=0; i<coords.length; i++) {
  62.     // проверяем расстояние между шаром и координатами «земли»:
  63.     if (PVector.dist(position, coords[i]) < r) {
  64.  
  65.       // рассчитываем скалярное произведение
  66.       // вектора столкновения и нормали:
  67.       float dot = incidence.dot(normal);
  68.  
  69.       // рассчитываем вектор отражения,
  70.       // присваиваем вектор отражения направлению движения шара:
  71.       velocity.set(2*normal.x*dot - incidence.x, 2*normal.y*dot - incidence.y, 0);
  72.       velocity.mult(speed);
  73.  
  74.       // рисуем линию нормали в точке столкновения:
  75.       stroke(255, 128, 0);
  76.       line(position.x, position.y, position.x-normal.x*100, position.y-normal.y*100);
  77.     }
  78.   }
  79.  
  80.   // задаем границы экрана...
  81.   // правая сторона:
  82.   if (position.x > width-r) {
  83.     position.x = width-r;
  84.     velocity.x *= -1;
  85.   }
  86.   // левая сторона:
  87.   if (position.x < r) {
  88.     position.x = r;
  89.     velocity.x *= -1;
  90.   }
  91.   // верхняя сторона:
  92.   if (position.y < r) {
  93.     position.y = r;
  94.     velocity.y *= -1;
  95.     // рандомизируем «землю»:
  96.     base1.y = random(height-100, height);
  97.     base2.y = random(height-100, height);
  98.     createGround();
  99.   }
  100. }
  101.  
  102.  
  103. // рассчитываем переменные для «земли»:
  104. void createGround() {
  105.   // рассчитываем длину «земли»:
  106.   baseLength = PVector.dist(base1, base2);
  107.  
  108.   // заполняем массив с координатами для «земли»:
  109.   coords = new PVector[ceil(baseLength)];
  110.   for (int i=0; i<coords.length; i++) {
  111.     coords[i] = new PVector();
  112.     coords[i].x = base1.x + ((base2.x-base1.x)/baseLength)*i;
  113.     coords[i].y = base1.y + ((base2.y-base1.y)/baseLength)*i;
  114.   }
  115. }

См.также

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

  1. processing.org - Non-orthogonal Reflection by Ira Greenberg