- Joined
- Mar 28, 2005
- Messages
- 160
Introduction
I 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.
Description
Code:
A missile (or some other assumingly circular object) is traveling along minding its own business.
From out of nowhere 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 coordinates, 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, it's important!!!
Lastly, a word from the wise, for aesthetics sake, don't 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.
========================================
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
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, in fact, we don't 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 missile traveling angle is our incident angle:
JASS:
angle-face
This can be negative, in fact, 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
***
Let's 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
Last edited by a moderator: