Как нарисовать движущийся лазерный луч? - PullRequest
2 голосов
/ 03 августа 2010

Я хочу нарисовать лазерный луч, который может отскочить от коробки. Обычно лазерный луч имеет переменную длину, и когда он отражается от поверхности, он отражается под углом, с которым сталкивается.

Я сам могу справиться с коллизиями (возможно, еще не пробовал), но я не понимаю, как будет работать фактический рисунок. Я не рисую прямую линию, мне иногда нужно продублировать линию, чтобы две линии были расположены под углом друг к другу, но когда лазерный луч останавливается, игра должна работать так, чтобы конец луча был что он может прекратить рисовать первую линию после того, как весь луч отскочил от поверхности.

Извините за плохое объяснение.

Ответы [ 3 ]

2 голосов
/ 03 августа 2010

Моя математика и триг немного ржавые, но вот моя попытка.

Правильная позиция и длина вашего луча зависит от четырех переменных:

  • v , скорость луча, поскольку, предположительно, это не настоящий лазерный луч и, следовательно, его скорость намного меньше, чем c .Для удобства мы можем сохранить v как расстояние, пройденное в прямом направлении от перспективы луча, за единицу времени.
  • тета , угол падения, которыйэто угол, под которым луч ударил о стену или барьер.
  • l , длина луча.
  • t ,время происшествия (пусть T - текущее время).

По существу, луч, движущийся со скоростью v , падает на стену под углом тета .Как долго будет происходить столкновение?(Сколько времени пройдет от момента, когда столкновение произойдет, до момента, когда луч полностью пройдет через точку падения?)

Во-первых, потому что луч движется под углом относительно набора ортогональных координат, мы должны получить x и y компоненты скорости и длины.

vx = cos ( theta ) * v
vy = sin ( theta ) * v
lx = cos ( theta ) * l
ly = sin ( theta ) * l

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

Теперь время, необходимое для удара луча с левой стороныи оставьте правую сторону следующим образом:

d = lx / vx

Предположим, что инцидент начинаетсявовремя t , а текущее время T .Тогда доля луча, который рисуется слева и справа от точки падения, будет:

r = ( T - t ) / d
слева = l * r
справа = l * (1 - r )

Этот пример был упрощен, чтобы показать только то, как можно рассчитать положение луча, если он ударяет слева направо.Я думаю, что это должен быть довольно простой процесс применения этих принципов к лучу, падающему на вертикальный барьер сверху или снизу.Кроме того, рассмотрим случай, когда головка луча попадает во второй барьер, все еще сталкиваясь с первым.

В этом случае нам нужна другая переменная вместо l , чтобы представить не всю длину луча, а длину сегмента луча, доступного для столкновения (евклидово расстояние междудва места происшествия).

1 голос
/ 06 августа 2010

Звучит так, будто вы на самом деле говорите не о лазерном луче, а о пистолете, стреляющем ярким снарядом, отражающимся от поверхности, и затем вы хотите наблюдать, как он отскакивает от коробки. (Ну, по крайней мере, на эту проблему я отвечаю!) Существуют более сложные, эффективные, общие, точные и т. Д. Методы, но есть простое решение проблемы, особенно когда коробка имеет перпендикулярные стены (то есть обычная коробка ):

Используя направление стрельбы из пистолета, найдите три компонента скорости (vx, vy, vz), и на каждом временном шаге, пока вы рисуете пулю, обновите ее положение x + = dt vx, y + = DT VY, Z + = DT * VZ, и продолжайте делать это, пока не ударится о стену. Когда вы ударяете стену, просто переверните соответствующий компонент вектора скорости , например, если вы ударите стену параллельно плоскости y-z, возьмите vx -vx. И продолжайте в том же духе, пока не достигнете другой стены, а затем снова переверните соответствующий компонент ...

Вот пример в 2D, просто чтобы я мог показать график, но 3D точно такой же с этим простым методом. Я показываю и полный путь черным цветом, и выделяю некоторые его участки красным. Кроме того, пример в Python, но единственные ключевые строки импорта (x + = dt * vx, ...), вероятно, не потребуют много в переводе:

альтернативный текст http://i38.tinypic.com/k4238.png

from pylab import *
from collections import deque

dt = .01
x, y = .5, .5
vx, vy = .233, .61

data = deque(maxlen=100)
all_data = []

for i in range(6000):
    x += dt*vx
    y += dt*vy
    if x<0 or x>1:
        vx = -vx
    if y<0 or y>1:
        vy = -vy
    # store data and plot
    data.append((x, y))
    all_data.append((x, y))
    if i%400==0:
        plot(*zip(*data), color='r', linewidth=4)
plot(*zip(*all_data), color='k')

show()

Как я уже сказал, не так эффективно, но очень просто.

0 голосов
/ 03 августа 2010

Я думаю, вы захотите заглянуть в OpenGL. Вот часто связанный ресурс по OpenGL на iPhone: OpenGL ES с нуля .

Поскольку OpenGL используется на многих платформах, есть все виды ресурсов, которые вы можете использовать. Быстрый поиск в Google по запросу " bouncing laser opengl " дает многообещающие результаты. Если вы добавите «игры» в свой поиск, вы, вероятно, найдете вещи, более похожие на приведенный вами пример (фактически видя, как концы лазерного луча подпрыгивают).

...