Processing:Примеры/Неперпендикулярное отражение 1
Материал из Онлайн справочника
Перейти к навигацииПерейти к поиску
Содержание | Среда разработки Processing | Справочник языка Processing | Библиотеки | Примеры | Режимы программирования |
Перевод: Максим Кузьмин
Проверка/Оформление/Редактирование: Мякишев Е.А.
Описание[1]
Этот скетч-пример основан на уравнении R = 2N(N*L)-L, где R – это вектор отражения, N – это нормаль, а L – это вектор столкновения.
Пример
// позиция левого края «земли»:
PVector base1;
// позиция правого края «земли»:
PVector base2;
// длина «земли»:
float baseLength;
// массив с точками (координатами) вдоль линии «земли»:
PVector[] coords;
// переменные для двигающегося шара:
PVector position;
PVector velocity;
float r = 6;
float speed = 3.5;
void setup() {
size(640, 360);
fill(128);
base1 = new PVector(0, height-150);
base2 = new PVector(width, height);
createGround();
// начальная позиция шара – вверху посередине экрана:
position = new PVector(width/2, 0);
// рассчитываем начальную случайную скорость:
velocity = PVector.random2D();
velocity.mult(speed);
}
void draw() {
// рисуем фон:
fill(0, 12);
noStroke();
rect(0, 0, width, height);
// рисуем «землю»:
fill(200);
quad(base1.x, base1.y, base2.x, base2.y, base2.x, height, 0, height);
// рассчитываем нормаль:
PVector baseDelta = PVector.sub(base2, base1);
baseDelta.normalize();
PVector normal = new PVector(-baseDelta.y, baseDelta.x);
// рисуем шар:
noStroke();
fill(255);
ellipse(position.x, position.y, r*2, r*2);
// двигаем шар:
position.add(velocity);
// делаем вектор столкновения единичным:
PVector incidence = PVector.mult(velocity, -1);
incidence.normalize();
// определяем и обрабатываем столкновение:
for (int i=0; i<coords.length; i++) {
// проверяем расстояние между шаром и координатами «земли»:
if (PVector.dist(position, coords[i]) < r) {
// рассчитываем скалярное произведение
// вектора столкновения и нормали:
float dot = incidence.dot(normal);
// рассчитываем вектор отражения,
// присваиваем вектор отражения направлению движения шара:
velocity.set(2*normal.x*dot - incidence.x, 2*normal.y*dot - incidence.y, 0);
velocity.mult(speed);
// рисуем линию нормали в точке столкновения:
stroke(255, 128, 0);
line(position.x, position.y, position.x-normal.x*100, position.y-normal.y*100);
}
}
// задаем границы экрана...
// правая сторона:
if (position.x > width-r) {
position.x = width-r;
velocity.x *= -1;
}
// левая сторона:
if (position.x < r) {
position.x = r;
velocity.x *= -1;
}
// верхняя сторона:
if (position.y < r) {
position.y = r;
velocity.y *= -1;
// рандомизируем «землю»:
base1.y = random(height-100, height);
base2.y = random(height-100, height);
createGround();
}
}
// рассчитываем переменные для «земли»:
void createGround() {
// рассчитываем длину «земли»:
baseLength = PVector.dist(base1, base2);
// заполняем массив с координатами для «земли»:
coords = new PVector[ceil(baseLength)];
for (int i=0; i<coords.length; i++) {
coords[i] = new PVector();
coords[i].x = base1.x + ((base2.x-base1.x)/baseLength)*i;
coords[i].y = base1.y + ((base2.y-base1.y)/baseLength)*i;
}
}
См.также
Внешние ссылки
Примеры на Processing | |
---|---|
Основы |
|
Продвинутые графические эффекты |
|
Примеры из сторонних библиотек |