views:

313

answers:

3

I'm looking to draw a laser beam which can possibly bounce around a box. Basically the laser beam is of variable length and when it bounces off a surface it will reflect at the angle that it collides.

I can handle the collision stuff myself (probably, haven't tried it yet though), but I'm confused about how the actual drawing would work here. It's not like I'm drawing a straight line, I need to sometimes duplicate the line so there are two lines at angles to each other, but when the laser beam stops, the game needs to work out where the end of the beam is so that it can stop drawing the first line after the entire beam has bounced off the surface.

Sorry for the poor explanation.

A: 

I think you'll want to look into OpenGL. Here's an often-linked resource on OpenGL on the iPhone: OpenGL ES from the Ground Up.

Since OpenGL is used on many platforms, there are all sorts of resources out there that you can use. A quick google search for "bouncing laser opengl" produces some promising results. If you throw "gaming" into your search, you'll probably find things more like the example you gave (actually seeing the ends of a laser beam bouncing around).

Joshua Nozzi
+2  A: 

My math and trig are a little rusty but here's my attempt.

The correct position and length of your beam depends on four variables,

  • v, the velocity of the beam, since presumably this is not a true laser beam and thus it's velocity is much slower than c. For convenience, we can store v as distance covered in the forward direction from the beam's perspective, per unit of time.
  • theta, the angle of incidence, that is, the angle at which the beam has struck a wall or barrier.
  • l, the length of the beam.
  • t, the time of the incident (let T be the current time).

Basically, a beam traveling at velocity v strikes a wall at angle theta. How long will the collision occur? (How long will it be from the time that the collision occurs until the time that the beam has completely traveled past the incidence point?)

First, because the beam is traveling at an angle relative to an orthogonal coordinate set, we should get the x and y components of velocity and length.

v.x = cos(theta) * v
v.y = sin(theta) * v
l.x = cos(theta) * l
l.y = sin(theta) * l

If the walls off which the beam can reflect are themselves at angles, you will have to project onto them by using the wall's angle as a frame of reference (use the difference between the two angles).

Now the time it takes for the beam to strike from the left side and leave out the right side is given by:

d = l.x/*v.x*

Suppose that the incident begins at time t, and the current time is T. Then, the proportion of the beam which is drawn on the left and right sides of the incidence point is,

r = (T - t)/d
left = l * r
right = l * (1 - r)

This example has been simplified to show only how one might compute the beam position if it strike from the left to the right. I think it should be a fairly simple process to apply these principles to a beam striking a vertical barrier from the top or the bottom. Also, consider the case that the head of the beam strikes a second barrier while still in collision with the first.

In that case, we need another variable in place of l to represent not the entire length of the beam, but the length of the segment of the beam available for collision (Euclidean distance between the two incident locations).

Jesse Dhillon
A: 

It sounds like you're not really talking about a laser beam but instead about a gun shooting a bright projectile that reflects off the surface, and you then want to watch it bounce around the box. (Well, at least that's the problem I'm answering!) There are more complicated, efficient, general, accurate, etc, methods, but there's an easy solution to the problem, especially when the box has perpendicular walls (i.e. a normal box):

Using the direction that the gun is fired, find the three velocity components, (vx, vy, vz), and at each timestep while you're drawing the bullet, update it's position x+=dt*vx, y+=dt*vy, z+=dt*vz, and keep doing this until you hit a wall. When you hit a wall, just reverse the appropriate component of the velocity vector, e.g. if you hit the wall parallel to the y-z plane, take vx to -vx. And just keep going the same way until you hit another wall, and then reverse the appropriate component again...

Here's an example in 2D, just so I can show a plot, but 3D is exactly the same with this simple method. I show both the full path in black, and highlight some sections of it in red. Also, the example's in python, but the only import key lines (x+=dt*vx,...) probably won't require much in translation:

alt text

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()

Like I said, not so efficient, but very easy.

tom10