Оновіть сторінку, щоб побачити новий випадковий багатокутник!

Багатокутник і Багатокутник

Наш останній приклад у цьому розділі перевіряє зіткнення двох багатокутників. Як ви вже здогадуєтеся зробити перевірку на зіткнення двох багатокутників доволі просто, достатньо перевірити, чи стикається будь-яка зі сторін одного багатокутника з будь-якою зі сторін іншого! Як і раніше, ми також перевіряємо, чи один багатокутник повністю знаходиться всередині іншого.

Повний приклад коду:

// масиви для вершин багатокутників
const pentagon = new Array(5);
const randomPoly = [];

function setup() {
  createCanvas(window.innerWidth, window.innerHeight);
  noStroke();

  // створення вершин пʼятикутника
  const angle = TWO_PI / pentagon.length;
  for (let i = 0; i < pentagon.length; i++) {
    const a = angle * i;
    const x = width / 2 + cos(a) * 100;
    const y = height / 2 + sin(a) * 100;
    pentagon[i] = createVector(x, y);
  }

  // створення випадкових вершин для рухомого багатокутника
  let a = 0;
  let i = 0;
  while (a < 360) {
    const x = cos(radians(a)) * random(30, 50);
    const y = sin(radians(a)) * random(30, 50);
    randomPoly.push(createVector(x, y));
    a += random(15, 40);
    i += 1;
  }
}

function draw() {
  background(255);

  // оновлення положення для рухомого багатокутника
  const mouse = createVector(mouseX, mouseY);
  const diff = p5.Vector.sub(mouse, randomPoly[0]);
  for (const v of randomPoly) {
    v.add(diff);
  }

  // результат перевірки на зіткнення
  const isHit = isPolyWithPolyCollides(pentagon, randomPoly);
  // при зіткненні змінюємо колір
  if (isHit) {
    fill(255, 150, 0);
  } else {
    fill(0, 150, 255);
  }

  // малювання пʼятикутника
  noStroke();
  beginShape();
  for (const v of pentagon) {
    vertex(v.x, v.y);
  }
  endShape();

  // малювання рухомого багатокутника
  fill(0, 150);
  beginShape();
  for (const v of randomPoly) {
    vertex(v.x, v.y);
  }
  endShape();
}

// перевірка на перетин між багатокутником та багатокутником
function isPolyWithPolyCollides(p1, p2) {
  // прохід через кожну з вершин у парі з наступною вершиною списку
  let next = 0;
  for (let current = 0; current < p1.length; current++) {
    // отримання наступної вершини зі списку
    next = current + 1;
    // коли дійшли до останньої вершини, беремо першу під індексом 0
    if (next === p1.length) next = 0;

    // отримуємо p5.Vector у нашій поточній позиції
    // це зробить наш оператор if трохи чистішим
    const vc = p1[current];// c для "current" (поточний)
    const vn = p1[next];   // n для "next" (наступний)

    // тепер ми можемо використати ці дві точки (лінію) для порівняння
    // з вершинами іншого багатокутника за допомогою isPolyWithLineCollides()
    let isCollision = isPolyWithLineCollides(p2, vc.x, vc.y, vn.x, vn.y);
    if (isCollision) return true;

    // опціонально: перевірка, чи другий багатокутник знаходиться ВСЕРЕДИНІ першого
    isCollision = isPolyWithPointCollides(p1, p2[0].x, p2[0].y);
    if (isCollision) return true;
  }

  return false;
}

// перевірка на перетин між багатокутником та лінією
function isPolyWithLineCollides(vertices, x1, y1, x2, y2) {
  // прохід через кожну з вершин у парі з наступною вершиною списку
  let next = 0;
  for (let current=0; current= 0 && uA <= 1 && uB >= 0 && uB <= 1) {
    return true;
  }

  return false;
}

// перевірка на перетин між багатокутником та точкою
// використовується лише для перевірки, чи другий багатокутник знаходиться ВСЕРЕДИНІ першого
function isPolyWithPointCollides(vertices, px, py) {
  let isCollision = false;

  // прохід через кожну з вершин у парі з наступною вершиною списку
  let next = 0;
  for (let current = 0; current < vertices.length; current++) {

    // отримання наступної вершини зі списку
    // коли дійшли до останньої вершини, беремо першу під індексом 0
    next = current + 1;
    if (next === vertices.length) next = 0;

    // отримуємо p5.Vector у нашій поточній позиції
    // це зробить наш оператор if трохи чистішим
    const vc = vertices[current];  // c для "current" (поточний)
    const vn = vertices[next];     // n для "next" (наступний)

    // compare position, flip 'isCollision' variable back and forth
    if (((vc.y > py && vn.y < py) || (vc.y < py && vn.y > py)) &&
      (px < (vn.x - vc.x) * (py - vc.y) / (vn.y - vc.y) + vc.x)) {
      isCollision = !isCollision;
    }
  }

  return isCollision;
}

Далі: Завдання 4