Snippet Deflection Angle

emjlr3

Change can be a good thing
Reaction score
395
Was asked about stuff bouncing off other stuff a while back, and posted a script of which I couldn't recall the source, and which I wasn't sure how functioned.

To that end, I decided I wanted my own script for doing this, one that I understood, and could manipulate in the future to my needs.

There, for what is worth, here is my own:

Description:

Code:
A missile (or some other assumingly circular object) is traveling along minding its own business.
From out of no where comes a building, or perhaps some other projectile, or maybe even a wall out ahead.
Preferably in a somewhat realistic fashion.
If such a collision were to take place, and the missile interacts in an [U]elastic[/U] fashion,
what should be its new and improved, direction of travel?

JASS:
// Returns angle in radians
function GetDeflectionAngle takes unit missile, unit target returns real
    return 2.*Atan2(GetUnitY(target)-GetUnitY(missile),GetUnitX(target)-GetUnitX(missile))+bj_PI-GetUnitFacing(missile)*bj_DEGTORAD
endfunction

// Wrapper, returns angle in degrees
function GetDeflectionAngleDeg takes unit missile, unit target returns real
    return bj_RADTODEG*GetDeflectionAngle(missile,target)
endfunction


We are presumably colliding a missile with some static object. You can always replace the target with a set of x and y coords, or some other projectile.

It's important to note, however, that this is entirely dependant upon the direction the missile is traveling, which I assume is its facing. If this is not the case, update the script to account for this irregularity.

On a second and equally important note, the first function returns the angle in radians, whereas the wrapper returns the angle in degrees. Remember that, its important!!!

Lastly, a word from the wise, for aesthetics sake, dont update your projectiles facing, its slow and ugly. Simply create a new one at the correct angle in its place.

Simple enough.
Feel free to stop reading here, and just start your collisions. :D

========================================

Then again, if you are feeling bold, try the rest on for size:

Given what we know about deflections, we can see that so long as our entity collides with some flat surface, given we know the angular relationship between the two (incident angle), we can determine the exiting (accidental) angle.

Well, we don't have a flat surface. We have a building, or something like it. Additionally however, we have a center position, or an x and y coordinate system, for our target, the direction our missile is traveling (its facing), and the angle between it and the target its interacting with (which we can calculate using simple trigonometry).

We are therefore going to assume that at some distance out from our center point (collision radius), the missile is interacting with a flat surface. A silly assumption, I know, but it's the only one that works.

Ok, now the goal is to eventually determine our accidental angle (B in the picture), which is directly related to the incidental angle (a in the picture):

Deflection.png


Ergo, if we can calculate our incidental angle, we will be able to calculate our accidental angle. Easy enough, pretty much pie infact, with some simple arithmetic and geometry.

First we need a flat surface. Well, infact, we dont really need the surface, simply it's surface normal, which for our purposes is the angle between the missile and the building:
JASS:
bj_RADTODEG*Atan2(GetUnitY(target)-GetUnitY(missile),GetUnitX(target)-GetUnitX(missile))


This provides us with the WC3 world angle between these two entities, which is the angle perpendicular to our interaction "surface".

Now the difference between the surface normal and the missiles traveling angle is our incident angle:
JASS:
angle-face


This can be negative, infact it needs to be, considering we're working on the positive direction (in other words, clockwise about our WC3 world), so don't fret.

Now that we have this difference, doubling it will give us the difference between the incident and accident angles, since they are both equally spaced apart from the surface normal:
JASS:
2.*(angle-face)


Not so fast, yes this is the difference between the two, but we can't simply add this to our current direction angle to give us the new direction, that won't work at all.

We are bouncing off of and moving in the opposite direction from the target. Therefore our new angle is going to be in the opposite direction of the current:
JASS:
face+180.


There are 360 degrees in a circle, +180 will give us the opposite direction.

Now that we have our opposite direction, adding the multiple of our surface/incident difference will give us the new angle of deflection:
JASS:
face+180.+(2.*(angle-face))


Using simple algebra, this can be further optimized through expansion, into the following form:

JASS:
face+180.+(2.*(angle-face))=face+180.+2.*angle-2.*face
=-face+180.+2.*angle //or,
=2.*angle+180.-face



***
Lets do a simple example on a sheet of paper, go ahead, take one out, I'll wait......

Our missile is traveling at 45 degrees, and when it interacts with the building they are at a 90 degree angle. Draw a compass, label the axis. Draw a dot somewhere, facing 45 degrees, and draw another at a 90 degree angle from the first.

JASS:
ang=90.
face=45.

=face+180.+(2.*(angle-face))
=45.+180.+(2.*(90.-45.))
=225.+(2.*45.)
=225.+90.
=315. degrees


Draw a line directed outward from your first dot at a 315 degree angle. Looks pretty good, no? Well, thats the idea, I knew you'd see things my way.

Enjoy,
Hulk3
 

Zaraf

New Member
Reaction score
22
Well, that's all very easy to understand....but what is this used for?
 

BRUTAL

I'm working
Reaction score
118
If such a collision were to take place, and the missile interacts in an elastic manor,
what should be its new and improved, direction of travel?

im guessing if you want to code something that will bounce off another thing, like a wall, and you want the angle of which its supposed to head towards after impact.
 

13lade619

is now a game developer :)
Reaction score
400
Lastly, a word from the wise, for aesthetics sake, dont update your projectiles facing, its slow and ugly. Simply create a new one at the correct angle in its place.

well, i was constantly changing the facing of my missile here..
and it looks not that bad.

[Snippet]Advanced Projectile Motion Experiment
 

Builder Bob

Live free or don't
Reaction score
249
This is a commonly asked for snippet, so it'll be very useful.

Short, but well explained. Exactly how it should be. The only thing missing are some titles to separate the different chapters.
 

emjlr3

Change can be a good thing
Reaction score
395
you were also changing it by just a wee bit

trying turning it 180 degrees
 

Tom Jones

N/A
Reaction score
437
It's important to note, however, that this is entirely dependant upon the direction the missile is traveling, which I assume is its facing. If this is not the case, update the script to accommodate this.
:rolleyes:

Introduce wrappers to remove that limitation:

JASS:
function GetDeflectionAngleXY takes real angle, real x1, real y1, real x2, real y2 returns real
    return angle+180.+(2.*((bj_RADTODEG*Atan2(y2-y1,x2-x1))-angle))
endfunction

//GetDeflectionAngleLoc(...)?

function GetDeflectionAngle takes unit u, unit obstacle returns real
    return GetDeflectionAngleXY(GetUnitFacing(u),GetUnitX(u),GetUnitY(u),GetUnitX(obstacle),GetUnitY(obstacle))
endfunction
Also, I never use degrees. So maybe it would be more user friendly to take and return the angle in radians? Users who insist on using degrees can convert the argument and returned value with bj_DEGTORAD and bj_RADTODEG.
 

emjlr3

Change can be a good thing
Reaction score
395
thats not a bad idea

I usually work in radians myself - but for me this was easier to accomplish in degrees, from a spacial perspective

its not impossible for the user to correct for this, or simply add it to the snippet themselves
 

Blackrage

Ultra Cool Member
Reaction score
25
Does missle leak?

What missile? There are no missiles created, unless I'm misunderstanding something (or if your begging for help on a map your making). Reals don't leak, if that's what your asking.


Anyway, nice job. I find this VERY useful for a map that I'm making. +Rep.
 

Romek

Super Moderator
Reaction score
963
This is indeed very useful.

I was thinking about making you make this a 1-liner, so that it'd be inlined, but that'd really lower the readability and the editability of it.
Anyway, it's not like this is going to be called very often. How often does a missile bounce? :rolleyes:

Anyway, I'll be sure to use this sometime. Thanks for submitting.

Approved.
 

emjlr3

Change can be a good thing
Reaction score
395
optimized script and added radian return function - should be inline friendly now
 

Troll-Brain

You can change this now in User CP.
Reaction score
85
optimized script and added radian return function - should be inline friendly now

No it wouldn't, check the jasshelper documentation about inline, arguments must be use only one time and in the order of the function header.
 

Bribe

vJass errors are legion
Reaction score
67
It would inline if he kept the original "2 * angle + bj_PI - facing * bj_DEGTORAD"
 

Bribe

vJass errors are legion
Reaction score
67
JASS:
function Double takes integer i returns integer
    return i * i
endfunction


^This wouldn't inline by JassHelper because the parameter is referenced more than once.
 

emjlr3

Change can be a good thing
Reaction score
395
o well

this shouldn't really be called periodically, and the math aint all that bad anyhow
 

Romek

Super Moderator
Reaction score
963
Inlining wouldn't make the math any faster anyway. It's just a little bonus really (if it's possible to do), and has no noticeable benefits in the world of JASS.
The function is fine as it is.
 

emjlr3

Change can be a good thing
Reaction score
395
no but there would be a net effect to reduce processing time, ergo, removing a bj wrapper
 

Sgqvur

FullOfUltimateTruthsAndEt ernalPrinciples, i.e shi
Reaction score
62
I am not getting the example : (. Can you upload another picture that explains it please?

Edit:
emjlr3: Our missile is traveling at 45 degrees, and when it interacts with the building they are at a 90 degree angle. Draw a compass, label the axis. Draw a dot somewhere, facing 45 degrees, and draw another at a 90 degree angle from the first.

Code:
        this line is 
        "southern wall of 
        building"
        ----------------------
                  /\
                 /  \
                /    \
               /      \
              /        \
             /          \
            /            \
          45deg        315deg
          *                *
          ^                ^ 
       the missile         missile after
       traveling at        colliding with 
       45deg               the wall

Looking at the numbers it seams that this is happening but I still can't understand your example (drawing the dots).


Edit2: "...and when it interacts with the building they are at a 90 degree angle"

Is it possible "entity1" to "interact" with "entity2" at an angle other than 90 degree?


Edit3:
emjlr3: Well, infact, we dont really need the surface, simply it's surface normal, which for our purposes is the angle between the missile and the building

Why do we (emjlr3) say that the angle between the missile and the target (building) is equivalent to the surface normal??
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top