View Full Version : [AS3] Find closest direction
macco
12-13-2008, 09:25 PM
I want to rotate my baseCannon towards the closest direction possible:
I use this code:
var v:Point = new Point(gamelevel.mouseX - bases[i].x,gamelevel.mouseY - bases[i].y)
bases[i].baseCannons[j].newDirection = Math.atan2(v.y,v.x) * 180/Math.PI
//find the shortest way and then increase the angle to slowly turn towards that direction
bases[i].baseCannons[j].deltaAngle = bases[i].baseCannons[j].newDirection-bases[i].baseCannons[j].rotation;
trace(bases[i].baseCannons[j].newDirection)
if (Math.abs(bases[i].baseCannons[j].deltaAngle)>Math.PI) {
bases[i].baseCannons[j].rotation -= (2*Math.PI-bases[i].baseCannons[j].deltaAngle)*0.1
} else {
bases[i].baseCannons[j].rotation += bases[i].baseCannons[j].deltaAngle*0.1
}
However I get the problem that when newDirection changes from 179 to
-179 my Cannon turns all the way round, but I want it just to turn minimal.
Any suggestions?
Thanks
lordofduct
12-13-2008, 09:28 PM
Check to see what quadrant you are in before you move. If you happen to be in the -x, +/-y quadrants settle up the value for that case.
var ang1:Number = ***;
var ang2:Number = ***;
if ( ang1 < -Math.PI / 2 && a > Math.PI / 2 ) ang1 += Math.PI * 2;
if ( ang1 > Math.PI / 2 && a < -Math.PI / 2 ) ang1 -= Math.PI * 2;
var closestAngle:Number = ang2 - ang1;
in radians of course
there is also a mathematical way to do this, but I find this takes less time and is more efficient.
macco
12-13-2008, 09:56 PM
I don't exactly understand what you mean, what should "a" be?
lordofduct
12-13-2008, 10:03 PM
sorry, a is supposed to be ang2
macco
12-13-2008, 10:23 PM
I still don't get what math is behind this I mean.
Cause this does not work:
if ( bases[i].baseCannons[j].rotation < -Math.PI / 2 && bases[i].baseCannons[j].deltaAngle > Math.PI / 2 ) bases[i].baseCannons[j].rotation += Math.PI * 2;
if ( bases[i].baseCannons[j].rotation / 2 && bases[i].baseCannons[j].deltaAngle < -Math.PI / 2 ) bases[i].baseCannons[j].rotation -= Math.PI * 2;
And I don't know why we add or subtract 2*Math.PI
lordofduct
12-13-2008, 10:46 PM
What I'm saying is this...
if ( ang1 < -Math.PI / 2 && ang2 > Math.PI / 2 ) ang1 += Math.PI * 2;
this means, if angle 1 is in quadrant 4 and angle 2 is in quadrant 3 then measure angle 1 into the positive direction
if ( ang1 > Math.PI / 2 && a < -Math.PI / 2 ) ang1 -= Math.PI * 2;
if angle 1 is in quadrant 3 and angle 2 is in quadrant 4 measure angle 1 in the negative direction
of course the math is in radians... the "rotation" property of a DisplayObject is in degrees. So you need to convert. I always do my math for angles in Radians, so that's the only reason why I use PI in my example.
but lets say we are measuring from 179 to -179. It basically says... oh angle 1 is in quad 3 and angle 2 is in quad 4. Let's subtract 360 degrees from angle 1 making it -181... now the difference between -179 and -181 is -2...
I describe awkward angles verbally in degrees... because 3.12 radians sounds weird compared to saying 179.
macco
12-13-2008, 11:13 PM
I think I slowly get it, but the thing that confuses me is that the rotation is in degrees, but we are calculating in radians. So how would I convert that to get it to work?
lordofduct
12-14-2008, 12:16 AM
well you can either convert you degrees to radians:
radians = degrees * PI / 180
and back:
degrees = radians * 180 / PI
or your can convert the pi stuff in my code to degrees.
1 PI == 180 degrees
so PI / 2 == 90 degrees
The idea of radians is this. If you drew an arc of a circle over as may degrees measured what is the length of said arc?
we know that circumfrence is pi*r*2 and a circle of radius 1 would have a circumfrence of 2pi. In the same if 1 pi is 180 degrees, then 2 pi would be 360. Hence the corrolation.
Some more common angles:
PI /2 == 90
PI / 3 == 60
PI / 4 == 45
PI / 5 == 36
PI / 6 == 30
PI / 9 == 20
PI / 12 == 15
The reason why radians are used is because radians are measured in the special value PI, and due to the special properties of PI radians can be used in certain algorithms to quickly solve different problems. Where in the same situation you couldn't do it in degrees.
This is mainly because the values drop out... back to the circumfrence of a circle. c = 2*pi*r, but we already know that all circles have 360 degrees or 2*pi... so we can just ignore this information regularly. The important value becomes r, and not only in writing, but in algebraic form we no longer care about circumfrence, diameter, or anything about a circle. Logic states that a circle can be described in one number... radius... and all other values are known there in.
macco
12-14-2008, 11:47 AM
Now I understand thanks :), but I don't understand why it won't work.
I use this code now:
bases[i].baseCannons[j].newDirection = Math.atan2(v.y,v.x) * 180/Math.PI
bases[i].baseCannons[j].deltaAngle = bases[i].baseCannons[j].newDirection-bases[i].baseCannons[j].rotation;
if (bases[i].baseCannons[j].deltaAngle > 90 && bases[i].baseCannons[j].rotation < -90) {
bases[i].baseCannons[j].rotation -= (360-bases[i].baseCannons[j].deltaAngle)*0.1
} else {
bases[i].baseCannons[j].rotation += (bases[i].baseCannons[j].deltaAngle)*0.1
}
It does it right for one direction but for the other one it doesn't. No idea why...
Reaper-Media
09-09-2009, 04:51 PM
I know this thread is like 9 months old... but anyway...
I've been trying to find the solution for this for a couple of days, and have come up with a bit of script which tells you whether to turn clockwise or anticlockwise.
Hope you still need the script :D
angle1 = 269 //angle of cannon
angle2 = 90 //angle of target
if(angle1 + 180 < angle2){
trace("turn anti-clockwise")
}else if(angle1 + 180 > 360 && angle1 - 180 < angle2){
trace("turn anti-clockwise")
} else {
trace("turn clockwise")
}
Reaper-Media
09-09-2009, 05:57 PM
Okay, that last bit of code didn't work, so i gave up on being clever and now have this very long peice of glitchless code :D It is veeeery long :D
//change these angles
angle1 = 19 //angle of gun
angle2 = 20 //angle of target
angle1Type = 1
angle2Type = 1
turn = "clockwise"
if(angle1<0){ angle1+= 360 }
if(angle2<0){ angle2+= 360 }
//calculate angle1 sector
if(angle1 >= 0 && angle1 < 90){
angle1Type = 1
} else if(angle1 >= 90 && angle1 < 180){
angle1Type = 2
angle1 -= 90
} else if(angle1 >= 180 && angle1 < 270){
angle1Type = 3
angle1 -= 180
} else {
angle1Type = 4
angle1 -= 270
}
//calculate angle2 sector
if(angle2 >= 0 && angle2 < 90){
angle2Type = 1
} else if(angle2 >= 90 && angle2 < 180){
angle2Type = 2
angle2 -= 90
} else if(angle2 >= 180 && angle2 < 270){
angle2Type = 3
angle2 -= 180
} else {
angle2Type = 4
angle2 -= 270
}
//check variations
if(angle1Type == angle2Type){
if(angle1 > angle2){
turn = "anti-clockwise"
} else {
turn = "clockwise"
}
}
if(angle1Type + 1 == angle2Type){
turn = "clockwise"
}
if(angle1Type - 1 == angle2Type){
turn = "anti-clockwise"
}
if(angle1Type - 3 == angle2Type){
turn = "clockwise"
}
if(angle1Type + 3 == angle2Type){
turn = "anti-clockwise"
}
if(angle1Type +2 == angle2Type || angle1Type -2 == angle2Type){
if(angle1 > angle2){
turn = "clockwise"
} else {
turn = "anti-clockwise"
}
}
trace(turn)
the "turn" variable will either be "clockwise" or "anti-clockwise" after the code has finished depending on which way you need to turn :)
|
vBulletin® v3.8.4, Copyright ©2000-2009, Jelsoft Enterprises Ltd.