|
This thread is locked; no one can reply to it. |
1
2
|
Angles, how i hate them... |
sicgamemaker
Member #1,365
June 2001
|
NEVER MIND! but let it remain, i do hate angles and trigs _______________________ |
Greyer
Member #1,509
September 2001
|
Remeber your friend ------------------------------------------------ |
23yrold3yrold
Member #1,134
March 2001
|
SOH CAH TOA Some Old Hippie Caught Another Hippie Tripping On Acid There's another with "Old Hags" but I forget it .... -- |
Steve Terry
Member #1,989
March 2002
|
hahahahhahahahhhaahhahahhahahhahahahaha ___________________________________ |
Marty Dill
Member #277
April 2000
|
That brings back memories ... |
gillius
Member #119
April 2000
|
People always mention sohcahtoa or whatever it is but I never learned that one. I guess I learned a different one, which I haven't heard from other people: Oscar Had A Heap Of Apples: sin = O/H O = opposite edge Gillius |
Thomas Harte
Member #33
April 2000
|
I hate to put a dampener on things, but the number of times even a program with 'perfect' physics actually calculates the angle between anything is zero. And certainly the number of times any of that stuff they taught you during the first few years of school about soh cah toa isn't very useful in either the real or programming worlds . . . [My site] [Tetrominoes] |
Derezo
Member #1,666
April 2001
|
I found that when I first started programming.. 'soh cah toa' actually made things worse! I was trying to do the stuff that was already done for me, then add it here.. subtract it here... and voila! A big mess! "He who controls the stuffing controls the Universe" |
Shawn Hargreaves
The Progenitor
April 2000
|
I think angles are very rarely a good idea. They are the obvious way to store orientation because they are what you get taught in school, but vectors are almost always easier and more efficient and more flexible. Especially in 3D (it wasn't until I'd been doing commercial games for several months that I figured out how much a pain it was to use angles for everything!) but even in 2D vectors are nice. If you store all your orientations and positions and speeds as vectors, it becomes incredibly easy to convert between any of them (just a few adds and subtracts). And you can do much more interesting physics type stuff without too much hassle, for instance bouncing off walls is just a dot product to reverse the momentum, plus maybe a multiply if you want to absorb some energy during the collision response. That kind of thing would be a total nightmare to do with an angle+speed type respresentation. And learn how dot products work: that is the most useful basic operation you can possibly have, as almost anything can be done in terms of it. A good C++ vector class is highly recommended, so you can add/subtract/scale vectors as simple data types. And overload operators for some of the more useful operations (I use ^ for cross product, | for dot product, and unary ~ for normalize). There's one in my Speedhack entry that you could use as a starting point... |
sicgamemaker
Member #1,365
June 2001
|
i guess i should learn vectors? point me in a good direction and ill go learn about em closest i come is an angle and a velocity... _______________________ |
Thomas Harte
Member #33
April 2000
|
There isn't much to learn about vectors, they are very simple. A vector is an ordered n-tuple. In geometric space, when people say 'vectors' they usually mean something of the form : (x, y [, z]) Where the components are quantities to move parrallel to the predefined set of axis : (1, 0 [, 0]) The most interesting thing one can do between two vectors in the general case is the dot, or scalar, product. Which maps two vectors to a scalar, like this : (a, b [, c]).(d, e [, f]) = a*d + b*e [+ c*f] The scalar has the property that it is : |(a, b [, c])||(d, e [, f])|cos(angle between) Where || are used to mean 'length of'. Which also means that it is a way of finding out how far either vector travels in the direction of the other, the result being in multiples of the length of the other. There is also the 'cross' product, but this isn't so interesting since it is defined only in 3 and 8 dimensions. It takes two vectors and gives one that is perpendicular to both, by : (a, b, c)x(d, e, f) = ( (b*f - e*c), (c*d - f*a), (a*e - d*b) ) Finally, commonly people like to make vectors unit length, principly because it makes like easier in the dot product. This is easy, you just get the total vector length (using Pythagoras) and divide each component by it. And that is nearly all most programmers know about vectors. The only extra bit of information is that it is very useful to store planes (or lines in 2d) in the form 'normal vector & distance from the origin along normal vector', since then you can dot product away without any adaption. [My site] [Tetrominoes] |
Shawn Hargreaves
The Progenitor
April 2000
|
2d vector: a pair of values, eg. (x, y) So all positions are vectors. Also all directions can be stored as vectors. Given the points A and B, the direction from A to B is the vector B-A. Call this direction vector D. Then you can start doing basic algebra with them, eg. B = A+D (this is where the C++ vector class comes in handy as it lets you write such things directly). The direction vector D contains both direction and distance information. You can extract the distance using Pythagoras: dist = d.magnitude() = sqrt(d.x*d.x + d.y*d.y) Once you have that, you can normalize d: d.x /= dist; Or if you have good C++ classes: d /= dist; or This will give you a unit vector, which holds only direction information. It points in the same direction as the original D, but has length=1. Unit vectors are especially handy for using with dot products... The dot product, a | b = a.x*b.x + a.y*b.y. If a and b are both unit vectors, this gives the cosine of the angle between them. If only a is a unit vector, this tells you how much of vector b lies along the direction of a. Which is a lot more useful than it might seem! It will be zero if the lines are at right angles, positive if they are in the same direction, negative if they are in opposite directions. An example of a simple vector based physics system: Vector pos(0, 0); // add velocity // apply air resistance // apply gravity // apply thrust // turn by angle Which is probably very similar to stuff you are already doing, as a lot of vector math is just common sense! Let's add a bit of collision. Assume we have a wall defined by an infinitely long line (if the line has fixed ends the same principle applies but needs a few extra checks). You can store this line as a vector holding any arbitrary point on the line, and another unit vector holding the normal of the line (the normal is just a vector at 90 degrees to the direction of the line). Say L is a point on the line, N is the normal, and you want to check for collision of a point P. Work out: // direction from point to line // dot the direction with the line normal // which side of the line are we on? Ok, let's try bouncing off the line, rather than just stopping dead after we hit it. For that, we want to reverse the amount of our velocity that was heading towards the surface, but leave the amount of velocity that was sideways on to the surface alone. Really easy to do with dot products: // how much velocity was towards the surface? // recoil away from the surface by that amount // apply recoil. One of it will cancel out You can really easily extend this to support non-elastic collisions, where the surface absorbs some amount of your energy. Either change the last line above to: vel -= recoil*1.5; to absorb half the energy, or for a surface that also absorbs sideways motion: vel = (vel-recoil*2) * 0.5; The really great thing about vectors is that they work pretty much the same in 2d and 3d. Working with angles is ok but sometimes a bit complicated in 2d, but becomes a million times worse if you try to extend it into 3d, while vectors are equally simple in either. |
sicgamemaker
Member #1,365
June 2001
|
wow thats a lot of stuff... yo uthink id be able to pick that crap up easily being in calculus 2, but it seems strange to me... _______________________ |
Damyan Pepper
Member #2,181
April 2002
|
Yup - I normally store the velocity, the position and the front vector. If you're in 3D then also a right vector. You can then work out an up vector by crossing the front and right. Be sure that you keep your direction vectors normalised! Cross products only really make sense in 3D: vc is the cross product of v1 and v2: vc.x = v1.y * v2.z - v1.z * v2.y I think it is quite standard to use the ^ operator in C++ for this. So, (v1 ^ v2) gives you the vector perpendicular to v1 and v2. This only works if v1 and v2 are both normalised. |
Shawn Hargreaves
The Progenitor
April 2000
|
Ignore Damyan. In 3D, sensible people always store the front vector and up vector, and generate the right vector with a cross product. Only a crazy man would suggest storing front and right and regenerating up! Actually it makes no difference: you could store all three if you wanted. But there is no need as given any two of front, up, and right, you can recalculate the other one whenever needed with a cross product. The problem with storing all three is that it only makes sense for them to be at right angles to each other (otherwise your object would be in some weird squashed universe with dimensions at funny angles :-) but even if they start out at right angles, over time as you rotate the object, rounding errors are likely to end up with them getting misaligned. So at the end of each frame, it is worth renormalising everything to make sure all your vectors are perpendicular, eg, if you store front and up: front = ~front; (assuming ~ = normalize and ^ = cross product) This will give you a new up vector that has been corrected to make sure it is exactly 90 degrees from the front vector. Incidentally, Damyan is also wrong in saying that vectors have to be normalised for cross products to work: it's just that if they aren't normalized, or if the input vectors aren't 90 from each other, the result won't be a unit vector (so you have to re-normalize it). Don't you feel stupid now Damyan? :-) In 2D you don't need any of that: just a single front vector is enough to encode a complete orientation. Plus position, obviously, and maybe velocity. |
Thomas Harte
Member #33
April 2000
|
Quote: In 2D you don't need any of that: just a single front vector is enough to encode a complete orientation. Plus position, obviously, and maybe velocity. A whole post of pettiness for you: It depends what you want to do. Even in general case engines, you will usually [numerically] integrate acceleration to get velocity, and integrate that to get position. Note to those scared of maths - this : vel += acc; is actually an approximate integration using the same simple observation as Euler made many centuries ago about graphs, but taking the 'step size', often called h, to be 1. However, my childishness makes me point out - there is no point storing velocity if you don't intend to make your objects move, and if they are moving you are probably storing a list of the forces acting upon the body also. So thats something else you want to store. [My site] [Tetrominoes] |
Damyan Pepper
Member #2,181
April 2002
|
I guess I've had one of those days, Shawn. BTW, are you sure that cupid is frame rate compensated? Also, on the subject of euler integration, some of you may be interested to have a look at the string code in cupid, and grabbing hold of the paper that is linked at the top of heart_trails.cpp that describes a really neat and simple way of doing physics without all the tedious mucking around with forces, inertia tensors and other nastiness. |
sicgamemaker
Member #1,365
June 2001
|
wow, im really confused... id probably get it if you showe dme an example of these few things( all i do is 2-D im not concerned with 3d yet, all it does is confuse me : if i have position vector A and velocity vector B, to move him would be A+B, the result of which is my new position? how would i go about rotating a vector? say i have a sprite pointing straight up and i want him to rotate 128 (fixed numbers ) degress ? how would i clip a vector agaisnt a vector? like tell where, and when a collsion occured? what does normalizing do, why would i want to do it, and how is it done, and how does it effect the numbers stored in the vectors? tehre wre more quations .. confusions i mean? that i may need answers for thanks for he hwelp though _______________________ |
Bob
Free Market Evangelist
September 2000
|
Damyan: That link 404s on me -- |
Peter Wang
Member #23
April 2000
|
I'll answer the easy one :-) Normalising is turning a vector into a unit vector, i.e. a vector of length 1. (divide each component of vector v with the magnitude of v) If that's wrong, I'll look like a fool. This thread has been really useful. If I had read this last year maybe I would have paid attention in class.
|
topaz22
Member #2,049
March 2002
|
sicgamemaker
Member #1,365
June 2001
|
wow, that stuff seems to be over my head _______________________ |
Damyan Pepper
Member #2,181
April 2002
|
It would be worth reading through it - it does end up giving some source code that pretty much works. If you have position A and velocity B, then yes, A+B gives you the new position. This is basically Euler integration - so if you read anything that goes on about Euler integration then don't be scared. (I was so pleased when I realised that!) To rotate an arbitrary vector, F by ang degrees: newF.x = F.x * cos(ang) - F.y * sin(ang) I'd also normalise it after that, just to be sure...although Shawn'll probably complain that I normalise too much! Shawn has also just pointed out that another neat way to deal with rotations is to just add some amount of the right vector and normalise again: newF = ~(F + right*0.2); This is harder to control though! I'm not sure what you mean by clipping a vector against a vector. There's a whole bunch of collision detection stuff in cupid, colliding circles against lines etc. that might be useful. |
Shawn Hargreaves
The Progenitor
April 2000
|
Thomas Harte writes: But acceleration is often a constant, so it's not part of the data you'd bother storing. Even when it is variable, acceleration rarely has state that needs to persist from frame to frame, eg. in MotoGP the acceleration force is a function of the engine revs, torque, current gear, current speed, and so on. > Note to those scared of maths - this : I hate the term 'integration' because it makes the issue seem far more complicated than it really is! It's pretty rare for you to need anything more than the simple Euler integration you give above, and although this is of course just a linear approximation of a proper calculus integration, it's a lot easier to visualise if you just think of it as adding a load of forces together! > However, my childishness makes me point Very true :-) ---------------- Damyan Pepper writes: Haha. (to explain: about halfway through Saturday George complained that the ship turned more slowly if you were near the bottom of the level. After trying to blame Damyan for it, it turned out that I had very carefully adjusted the render function to run at a fixed framerate, while the update just ran as fast as possible in whatever time was left. Oops!) ---------------- Peter Wang writes: Nobody seems to teach vectors properly. Or at least not in ways that make them seem useful for solving real world problems. When someone says "a dot b gives the cosine of the angle between the two vectors, as long as they are unit vectors", that doesn't seem especially handy. When I first heard this I just filed it away as "I'll remember that in case I ever need to know the cosine of the angle between two unit vectors". And I never needed to know that. It is only when you realise that dot product tells you how much of one vector lies in the direction of another that it starts to be useful. It turns out that about 90% of what you do in games and graphics can be expressed in terms of dot products, which is why things like the NVidia vertex shader processor or PS2 vector units are basically just really fast dot product evaluators! When I first started working at Probe, I was doing some flags in the crowd for an N64 football game, and spent about three days working out loads of trig calls to rotate a polygon so it would always face towards the camera. I got it working in the end, but it required about 10 sin/cos calls, two tangents, one inverse tangent, multiple square roots, and a huge amount of head scratching. I couldn't decide whether to be pissed off or incredibly relieved when I started on ExtremeG, and Ash (the lead coder) explained how you can do the same thing using just a couple of dot products and one cross product! |
Matt Smith
Member #783
November 2000
|
Ash Hogg? say Hi from me |
|
1
2
|