LoginLogin
Nintendo shutting down 3DS + Wii U online services, see our post

Finding the Angle of Reflection

Root / Programming Questions / [.]

MZ952Created:
And then there was a time I thought I was so cool in my Advanced Topics class in HS, yet, here I am, struggling to find a simple angle. I thought it was simple, and I have a version of it that seems to work most of the time, but I suspect I'm missing one crucial component. So basically, I'm trying to determine the angle of reflection of a traveling point contacting a circle, or really, a point ricochetting off a sloped tangential line to the circle. Consider A# to be the angle of the point to (0,0), measured positionally, so that A# = ATAN(Position_y#,Position_x#), and A0# to be the angle of the attack velocity, so that A0# = ATAN(Velocity_y#,Velocity_x#). From the plethora of diagrams I've sketched out, I had somehow figured that the angle of reflection should be A0# - A#, and after implementing this into the physics engine, this appears to work like half the time. The other half, the object follows a wrong trajectory, probably opposite the vector it is supposed to fall on. It seems to be dependent on the quadrant as well, but I'm having a hard time confirming that mere suspicion. I've searched so many Stack Exchange posts, all of which say pretty much the same thing, yet I must be missing something. As far as I can tell, I'm not using any special coordinate system, just the bare naked one underlying the trigonometric functions of SB. So, is there something painfully obvious and wrong with my implementation? Did two years really shave away all my mathematical knowledge from HS? How would you go about this, anyway?

The object probably won't exactly hit the circle, most of the time you'll detect the collision after it has traveled partway into the circle. So you might have to work backwards and calculate the exact collision point. Calculating the reflection from the position at frame 3 will probably cause the object to reflect BACK into the circle, which will make the result even weirder.

That's not quite the issue I'm having. The routine I'm using only checks for collision if the two objects are moving toward one another so that after a successful reflection—if the smaller object is still within the larger object—it is seen as moving away and is not checked for collision, allowing it to traverse the collision boundary again. The fault lies somewhere in the reflection method itself. Ordinarily, you'd expect the object to reflect off a line at the angle its approach, but whatever's wrong with my method is causing the object to travel back the way it came. Imagine a falling, horizontally moving baseball hitting the dirt and suddenly reversing direction, moving back to whence it came. Doesn't always seem to be the exact same angle though, just general direction. Like I sorta said, I suspect the way in which it reflects (correctly or incorrectly) is dependent on the quadrant of the unit circle it is in, but then again it varies correspondingly to direction in a way I can't quite figure out. I've been playing with the additions and subtractions and signs but whatever it is, it's beyond me. Edit: But then again, if there were a problem with how the routine checks for moving- away/towardness, then maybe it could cause the issue I'm seeing

Skimming this thread makes me wonder if it's a sign issue, like losing the sign on the x component after a trig function... it'd explain the quadrant-based nature that was alluded to. Trinitro told me that Atan doesn't have range issues in SB, snd you probably already considered that, but I figured I'd leave it here just in case.

I usually use the eauation: angle of reflection=positional angle×2-velosity angle+180 Example:
ACLS
XSCREEN 2

CX=170
CY=10
CR=10

PX=200
PY=160
PR=40

REPEAT
 CU=CU*.98
 CV=CV*.98+.2
 CX=CX+CU
 CY=CY+CV
 A1=DEG(ATAN(CX-PX,CY-PY))
 A2=DEG(ATAN(CU,CV))
 IF SQR(POW(CX-PX,2)+POW(CY-PY,2))<CR+PR && COS(RAD(A1-A2))<0 THEN
  A3=A1*2-A2+180
  SP=SQR(CU*CU+CV*CV)
  CU=SIN(RAD(A3))*SP
  CV=COS(RAD(A3))*SP
  CX=PX+SIN(RAD(A1))*(CR+PR)
  CY=PY+COS(RAD(A1))*(CR+PR)
 ENDIF
 GCLS
 GCIRCLE CX,CY,CR
 GCIRCLE PX,PY,PR
 VSYNC
UNTIL 0

Great example! I'll have to mull over it a little to figure out why it works and what makes it different from mine. Right off the bat, I see you're substituting X's for Y's in the ATAN function, which I'm pretty sure rotates the angle by +90 degrees. To say the least, I'm very happy to see some version of this code that actually works, thanks!