ID:145225
 
Code:
proc/get_fullcircle_dir(atom/ref,atom/target,startpx,startpy,endpx,endpy)
if(!ref || !target) return 0
var/dy
var/dx
if(startpx)
dy = endpy - startpy
dx = endpx - startpx
world << "dx: [dx]"
world << "dy: [dy]"
else
dy = target.y - ref.y
dx = target.x - ref.x
if(!dy)
world << "test1"
return (dx>=0) ? 90 : 270
. = arctan(dx/dy)
world << "arctan: [.]"
if(dy<0)
world << "test2"
. += 180
else if(dx<0)
world << "test3"
.+=360



proc/arctan(x)
var/y=arcsin(x/sqrt(1+x*x))
if(x>=0) return y
return -y


Problem description:


This is making me pull my hair out. I don't understand how everything can work just fine for every quadrent but the lower right. Seems like I've tried everything but I just can't figure out why I click for a 90 degree angle, it does it fine, but then if I ask it to do anything between 90 and 180, it wigs out and thinks it's like, 56 with the arctangaent and then it will add 180 to that which puts it into the lower-left and upper-left quadrents.

Help, please?

What it's supposed to do is return an angle out of 359 degrees, angle 0 being north.

Could it have anything to do with the fact that your arctan function will only return positive numbers? I never seem able to keep this stuff solid in my head, and I have to go and reaquaint myself with it every time I want to use it, so I might be making a silly mistake, but it seems like you would need to utilize negative numbers since that quadrant has a negative y value.

Even if you did want to return only positive though, you could just use "return abs(y)"
In response to Loduwijk
proc/arctan(x)
var/y=arcsin(x/sqrt(1+x*x))
return y
//if(x>=0) return y
//return -y


I did that and it just made DS freeze :/
In response to Kunark
Alright, apparently I need to go back over my trig book for a refresher. Just ignore me for the moment, and sorry.
In response to Loduwijk
I actually have a arctan proc that I use constantly in my shooting games, and the structure is pretty much the same.

proc/arctan(x)
return abs(arcsin(x/sqrt(1+x**2)))


I really doubt that it's got to do anything with your arctan proc. I was looking through your main proc and it's a little wierd. Can't put my finger on why though.

Of course, my trigonometry isn't too good... and Yota did donate a big chunk of pixel projectiles code (not Shadowdarke's!) for my games. I do understand the code though.

In response to D4RK3 54B3R
You can't use abs() in arctan() because it can return negative numbers. Also, x**2 is infinitely worse than using x*x because it's much much slower and uses a more error-prone process to find the answer.

Lummox JR
Again I'm still not sure why you're using get_fullcircle_dir() like that, since it's a weird hybrid of the correct code and other code that appears to be grafted on. Clearly if you're using the start/end vars, you don't need ref and target, which suggests you just need a single proc to deal with the start/end values. That leaves us with:
proc/GetAngle(x1,y1,x2,y2)   // these can be pixel offsets or real x,y values
var/dx = x2-x1
var/dy = y2-y1
if(!dy) return (dx>=0) ? 90 : 270
. = arctan(dx/dy) // angle offset from vertical, clockwise
if(dy<0) return .+180
if(dx<0) return .+360

The lower right should still be correct. The arctan() in there is providing the offset from vertical. For example, try dx=1 and dy=-4. That's a bearing on the compass of about 166°. arctan(-0.25) is about -14°, and since dy<0, we add 180° to get 166°. Therefore the lower right quadrant is fine. The lower left will be too. The last line handles the upper left quadrant, where we have a negative angle that's correct, but we want to push it within the 0°-360° bounds for the answer.

Lummox JR
In response to Lummox JR
startpx: 60
startpy: 300
endpx: 400
endpy: 240
dx: 340
dy: -60
(arctan proc)
x: -5.66667
x*x: 32.1111
x*x+1: 33.1111
sqrt(1+x*x): 5.75423
x/sqrt(1+x*x): -0.984784
arctan: 79.992
test2
79.992

I actually can't seem to ever get a negative number from arctan, no matter where I click :/
In response to Kunark
Kunark wrote:
I actually can't seem to ever get a negative number from arctan, no matter where I click :/

I see it now. Somebody gave you a bogus version of arctan(). You should not do the sign check that's in there currently. Just return the value of arcsin() directly.

Lummox JR
In response to Lummox JR
Ah! So lodu was right. I must have made a mistake before that caused it to crash when I did it before, but now it works flawlessly.

That's what DAU's code was all about. It was trying to work around the bugs that the arctan proc was outputting.

Thanks!