Index | FAQ | Search | Memberlist | Usergroups | Profile | Log in to check your private messages | Log in | Register

Angle turning code

| Inside3d Forums Forum Index -> QuakeC Programming

View previous topic :: View next topic
Author | Message
--- | ---
Wazat Joined: 15 Oct 2004 Posts: 732 Location: Middle 'o the desert, USA |

Posted: Wed Nov 24, 2004 6:42 pm Post subject: Angle turning code |

I don't know who, but somebody posted this code on the old forums a while back: void() meet_new_dir = { if (vlen(self.new_way - self.angles) > 2) self.angles = self.angles + normalize(self.new_way - self.angles) * 2;
else
self.angles = self.new_way;
};
I'd like to know who it is so I can give them credit. Anyway, at first it didn't work, because there is a specific condition needed in order for the code to operate: the angles need to range from -180 to 180, instead of 0-360 or some other system.
So, I've since modified the function to be more general-purpose. Here are the results:

Code:
/* ----------------------------------------- frik_anglemod (part of FrikBot) faster version of id's anglemod -----------------------------------------
*/
float(float v) frik_anglemod =
{
return v - floor(v/360) * 360;
};
/*
-----------------------------------------
capangle (by Wazat)
Quick little function to save time.
Makes sure an angle's 3 floats range from 0-360
-----------------------------------------
*/
vector(vector ang) capangle =
{
ang_x = frik_anglemod(ang_x);
ang_y = frik_anglemod(ang_y);
ang_z = frik_anglemod(ang_z);
return ang;
};
/*
-----------------------------------------
nangle (by Wazat)
Basically makes an angle range from -180 to 180.
-----------------------------------------
*/
vector(vector ang) nangle =
{
ang = capangle(ang);
if (ang_x > 180)
ang_x = ang_x - 360;
else if (ang_x < -180)
ang_x = ang_x + 360;
if (ang_y > 180)
ang_y = ang_y - 360;
else if (ang_y < -180)
ang_y = ang_y + 360;
if (ang_z > 180)
ang_z = ang_z - 360;
else if (ang_z < -180)
ang_z = ang_z + 360;
return ang;
};
/*
-----------------------------------------
angle_turn (by... actually I forget who wrote this one)
Modified by Wazat to be more general-purpose.
Turns oldang toward newang in 'turnrate' increments.
-----------------------------------------
*/
vector(vector oldang, vector newang, float turnrate) angle_turn =
{
newang = nangle(newang);
oldang = nangle(oldang);
if (vlen(newang - oldang) > turnrate)
return oldang + normalize(newang - oldang) * turnrate;
else
return newang;
};

The new function, renamed to angle_turn, is a lot more general-purpose, allowing any angle to turn toward an ideal angle, and any turn rate specified. I use it for the mini-turrets in Conquest, so that I don't have to rely on ChangeYaw(). Here is the code I use:

Code:
newang = vectoangles(dir); self.angles_z = newang_z; // don't modify roll newang = self.angles = angle_turn(self.angles, newang, self.ammo_nails); self.angles_z = 0; // stay level (0 roll) // set self.movedir so turret will know what direction to fire later on
newang_x = newang_x * -1; // x angle is always backward for some reason
makevectors(newang);
self.movedir = v_forward;

I hope this code comes in handy for someone here... And I hope I can find out who posted the original so I can give them credit.
_________________
When my computer inevitably explodes and kills me, my cat inherits everything I own. He may be the only one capable of continuing my work.

Back to top |

Wazat Joined: 15 Oct 2004 Posts: 732 Location: Middle 'o the desert, USA |

Posted: Wed Nov 24, 2004 10:11 pm Post subject: |

I forgot to mention, I'm having one problem with this code: it often turns in the wrong way. In other words, if the enemy is just to the right of the turret, it will turn left all the way around to hit it. Can anyone help me fix that? _________________
When my computer inevitably explodes and kills me, my cat inherits everything I own. He may be the only one capable of continuing my work.

Back to top |

Urre Joined: 05 Nov 2004 Posts: 1073 Location: Sweden |

Posted: Wed Nov 24, 2004 10:57 pm Post subject: |

Wazat wrote:
I forgot to mention, I'm having one problem with this code: it often turns in the wrong way. In other words, if the enemy is just to the right of the turret, it will turn left all the way around to hit it. Can anyone help me fix that?

Sorry, no, I was just going to mention that I've experienced the very same problem. Ticks one off, for sure.
_________________
Look out for Twigboy

Back to top |

IceDagger Joined: 19 Nov 2004 Posts: 20 |

Posted: Thu Nov 25, 2004 3:39 am Post subject: |

You have to check which is the smaller angle, the one on the right, or the one on the left. I think this is what's causing your problem: If the turret were facing 160 degrees, and was told to turn to -160 degrees, your code might be rotating 160 down to 0, down to -160, when it would be faster to rotate from 160 up to 200 (which is the same as -160).
If you've done some C programming, you might want to take a look at the QER frame interpolation tutorial (Specifically, the rotation interpolation code). Essentially you want to interpolate the turret's rotation along the smaller angle, which is what is done in frame interpolation when an entity's angle changes.
Hope this helps.

Back to top |

Wazat Joined: 15 Oct 2004 Posts: 732 Location: Middle 'o the desert, USA |

Posted: Tue Nov 30, 2004 11:44 pm Post subject: |

Hurray, it works! Here's the new function:

Code:
/* ----------------------------------------- angle_turn (by Wazat) Turns oldang toward newang in 'turnrate' increments. -----------------------------------------
*/
vector(vector oldang, vector newang, float turnrate) angle_turn =
{
local vector ang, dir;
local float dist;
newang = nangle(newang);
oldang = nangle(oldang);
if (vlen(newang - oldang) > turnrate)
{
//dir = normalize(newang - oldang);
//ang = oldang + dir * turnrate;
dist = frik_angcomp(newang_x, oldang_x);
if(dist > 0 && dist > turnrate)
dist = turnrate;
else if(dist < 0 && dist < turnrate * -1)
dist = turnrate * -1;
ang_x = oldang_x + dist;
dist = frik_angcomp(newang_y, oldang_y);
if(dist > 0 && dist > turnrate)
dist = turnrate;
else if(dist < 0 && dist < turnrate * -1)
dist = turnrate * -1;
ang_y = oldang_y + dist;
dist = frik_angcomp(newang_z, oldang_z);
if(dist > 0 && dist > turnrate)
dist = turnrate;
else if(dist < 0 && dist < turnrate * -1)
dist = turnrate * -1;
ang_z = oldang_z + dist;
return ang;
}
else
return newang;
};

_________________
When my computer inevitably explodes and kills me, my cat inherits everything I own. He may be the only one capable of continuing my work.

Back to top |

Display posts from previous:

| Inside3d Forums Forum Index -> QuakeC Programming | All times are GMT
Page 1 of 1

Jump to:

You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

Powered by phpBB © 2004 phpBB Group