| 01-27-2005, 10:21 PM | #1 |
Im trying to make a squad system so you can move around footmen (or any other) in formations. However, the system I have made so far works, but only for angles close to 0 (90 if you count in the facing - 90 I have made) Code:
function SquadPositionChild1 takes nothing returns nothing
set udg_tempIndex = udg_tempIndex + 1
set udg_tempX = ((udg_tempX * (udg_tempIndex - 1)) + GetUnitX(GetEnumUnit())) / udg_tempIndex
set udg_tempY = ((udg_tempY * (udg_tempIndex - 1)) + GetUnitY(GetEnumUnit())) / udg_tempIndex
endfunction
function GetSquadPosition takes integer index returns location
local location loc
set udg_tempIndex = 0
call ForGroup(udg_Squads[index],function SquadPositionChild1)
set loc = Location(udg_tempX, udg_tempY)
return loc
endfunction
function FormationChild1 takes nothing returns nothing
local location loc
local integer int = 0
local real col = 0
local real row = 0
local real x = 0
local real y = 0
local real angle = 0
local real s = 0
set udg_tempIndex = udg_tempIndex + 1
set int = udg_tempIndex
loop
exitwhen udg_tempInt >= int
set int = int - udg_tempInt
set row = row + 1
endloop
set col = int - ((I2R(udg_tempInt) + 1) / 2)
set row = row - ((I2R(R2I(I2R(CountUnitsInGroup(udg_Squads[udg_tempGlobalIndex])) / I2R(udg_tempInt))) - 1) / 2)
set x = (col * 120)
set y = (row * 120)
set s = SquareRoot(Pow(x,2) + Pow(y,2))
set angle = Atan2BJ(y,x)
set angle = angle + udg_tempReal
if (x<0 and y<0) then
set x = -CosBJ(angle) * s
set y = -SinBJ(angle) * s
endif
if (x<0 and y>=0) then
set x = -CosBJ(angle) * s
set y = SinBJ(angle) * s
endif
if (x>=0 and y<0) then
set x = CosBJ(angle) * s
set y = -SinBJ(angle) * s
endif
if (x>=0 and y>=0) then
set x = CosBJ(angle) * s
set y = SinBJ(angle) * s
endif
set x = GetLocationX(udg_tempPoint) + x
set y = GetLocationY(udg_tempPoint) + y
set loc = Location(x,y)
call IssuePointOrderLoc(GetEnumUnit(),"move",loc)
call RemoveLocation(loc)
set loc = null
endfunction
function TakeFormation takes integer index, integer RowCs, real facing returns nothing
set udg_tempPoint = GetSquadPosition(index)
set udg_tempInt = RowCs
set udg_tempReal = (facing - 90)
set udg_tempIndex = 0
set udg_tempGlobalIndex = index
call ForGroup(udg_Squads[index],function FormationChild1)
call RemoveLocation(udg_tempPoint)
endfunctionI have tested alot and I see the problem lies in: Code:
set angle = Atan2BJ(y,x)
set angle = angle + udg_tempReal
if (x<0 and y<0) then
set x = -CosBJ(angle) * s
set y = -SinBJ(angle) * s
endif
if (x<0 and y>=0) then
set x = -CosBJ(angle) * s
set y = SinBJ(angle) * s
endif
if (x>=0 and y<0) then
set x = CosBJ(angle) * s
set y = -SinBJ(angle) * s
endif
if (x>=0 and y>=0) then
set x = CosBJ(angle) * s
set y = SinBJ(angle) * s
endifIm quite puzzled on how to fix this annoying problem. Seeing -y/x gives the same answer as y/-x and y/x is same as -y/-x. Could anyone help me out a little with this? |
| 01-27-2005, 11:10 PM | #2 |
oops i deleted my post by accident, meant to edit the other one. oh well. |
| 01-27-2005, 11:19 PM | #3 | |
Quote:
if you have Atan (arctangens = invert tangens, gives angle from y/x). It can either be positive or negative. Now seeing, like I said, -y/x and y/-x gives the same value, you need my stupid if/then/elses. if x<0 then set x = -CosBJ(angle) * s else set x = CosBJ(angle) * s endif if y<0 then set y = -SinBJ(angle) * s else set y = SinBJ(angle) * s endif would prolly do the trick aswell. EDIT: found a stupid mistake ... I didnt link the if/then/elses , so when y or x changed from negative to positive or otherwise, it would be changed again. However, this just makes the footies move even more weird... EDIT EDIT: I found a solution, and it seemed you were abit right after all. I replaced the lines with: set x = -CosBJ(angle) * s set y = -SinBJ(angle) * s and somehow it worked. I dont have any idea why tho, someone cares to explain? |
| 01-28-2005, 04:36 AM | #4 |
Facing angles work correctly. 0 degrees is east/right. 90 is up/north. So you shouldn't adjust that. I've tested and atan2 works the same way, and works in all directions. atan only returns values in a 180 degree range like you say, but atan2 is fancy. I don't understand how your code works.. |
| 01-28-2005, 10:32 AM | #5 |
I know facing angles work correctly, but my code has a front at the top instead of a front at the right side, so I had to turn it. It works yay, but why the -Cos and -Sin ... I just cant see why... (it does look alot better than if/then/elses btw ^_^) |
| 01-28-2005, 11:38 AM | #6 |
If you want the front to be up, then shouldn't you *add* 90? so that 0 will get turned into 90. I think by subtracting 90 instead of adding, you end up 180 degrees away from where you wanted. Then the negatives fix that. |
| 01-28-2005, 02:14 PM | #7 |
nope. Look: 0 = up, but normally 90 = up... so when I enter 90 it will make front left, but it must be up, so substracting 90 works. Not that it matters 2 much, it only matters when units die and the formation is not complete. But thats np anyway, I really wanna understand this. My problem is: lets say x = -1 and y=1 Sqrt = Square Root atan2 returns: -45 cos returns: Sqrt(1/2) so -cos returns -Sqrt(1/2) sin returns: -Sqrt(1/2) so -sin returns Sqrt(1/2) This is valid with the starting points, HOWEVER: lets say x=1 and y=-1 atan2 returns: -45 cos returns: Sqrt(1/2) so -cos returns -Sqrt(1/2) sin returns: -Sqrt(1/2) so -sin returns Sqrt(1/2) BUT THIS IS NOT THE CASE!!! I DONT UNDERSTAND... WHY DOES IT WORK (yes, weird question :P) |
| 01-28-2005, 04:36 PM | #8 |
doesn't it work like this: the user who calls your function (you) gives an angle that he wants the group to face. 0 is supposed to mean up, cause you wanted it that way. so say you tell the group to face 0 and you want it to face up. now, to adjust this to normal angles, you must add 90. |
| 01-28-2005, 05:04 PM | #9 |
nono :P its the other way around. I made the function the way that the front is up at 0 angle (thats just the way it is;) cant help it) but I want the front to be right at angle 0, so I decrease with 90. |
