Moving object is becoming slower

Started by
7 comments, last by Pille456 15 years, 4 months ago
Hey! I've a little design problem. My program calculates the positions of objects on the screen (momently 2D), which react to the mouse position an several other things. The basic structure of every object looks like this: (hmm no code-tags here?) class GraphicObject { private: Vektor3D<double> directionVektor; Vektor3D<double> positionVektor; Vektor3D<double> speedVektor; public: //... void Move(); }; void GraphicObject::Move() { positionVektor = positionVektor + (speedVektor * directionVektor.normal()); } So every object has a position, direction and speed. The direction vector is changed often in the program (e.g. to follow the mouse), which works fine in my program, but I noticed a strange behavior. Sometimes the object is really slow (nearly not moving anymore). I think this is because the normalized direction vector has some rounding errors, which would suppose, that I multiply my speed vector with 0. Any ideas how I could solve that or how I could change the basic structure of the class to let this work right? P.S: the speed vector isnt changed after initialization.
Advertisement
Check out the FAQ for tag information. In the top right next to search.

It's quite difficult to think what might be going wrong. I think you need to give some more info. Is this a basic physics sim?

What is Vektor3D? Is it a class you designed yourself. The problem could lie here. Can you not use something like D3DXVector3? Are you certain that the operators overloads you have written are working correctly?

How certain are you the speed vector is not changed? Is it declared const?

What does the normal() member function do? Does it return a normalised version of the vector?

These were all things that came to mind when i read your post. Hope it sparks something in your head to give you a start on where to look.
The speed shouldn't be a vector, it should be a double. Otherwise, when your speed vector and direction vector become orthogonal at some point, the dot product becomes zero, and you have no movement.
Momently the program just moves a few triangles over the screen and let them follow the mouse and try not to hit obstacles like quads or circles. Vector3D is my own class and should work in the right way, I used this class in several other project without any problems. And yes "normal" return a normalized version of the vector.
The speed vector is more or less a double because the values are the same (x=y=z). Never thought about that deeply, but I think using a double value has the same effect, without using that much space.

Wiggin: How can they become zero? It's a multiplication, so one of the vectors must be zero. And the only changing vector is the direction vector. (Now this because there is no function which let it change, except of the ctor)

I believe I solved it partly - I changed the code, which calculates the new direction vector a bit and now I dont have this problem. But I can imagine several situation when my direction vector becomes zero:
- the direction vector is set randomly, so it might be zero. Up to now no problem, because the vector will change when other objects(like moving triangles) come near. But what if there are not any objects?
- the new directions vector is basically calculated in this line "SetDirectionVektor((GetDirectionVektor() + RunRule1() + RunRule2()));" easy to imagine that this line could set the vector to zero. RunRule1 gives me a vector that follows the mouse, RunRule2 a vector that avoid hitting the quads and triangles.

What I'm questioning now is: should I prevent the direction vector from getting zero and if yes where? The only suitable place is when I run the rules, so something like that:
if (((GetDirectionVektor() + RunRule1() + RunRule2()).GetX() == 0) && (GetDirectionVektor() + RunRule1() + RunRule2()).GetY() == 0))) SetDirectionVektor((GetDirectionVektor()); //ignoring the rules
else SetDirectionVektor((GetDirectionVektor() + RunRule1() + RunRule2()));
GetX() and so on returns the X value of the vector.
Quote:Original post by Pille456
Wiggin: How can they become zero? It's a multiplication, so one of the vectors must be zero.


Um, nope. Vector multiplication isn't like that. From context, it looks like you've defined operator* to be a cross product (since if it were a dot product, you would then be adding a scalar to a vector, which shouldn't compile. Unless you're doing something completely nonsensical like defining it to add the scalar to each component of the vector - I've seen this a fair bit in amateur code, but it is a completely nonsensical and useless operation.). The dot product of two collinear vectors is zero.

There is no reason that 'speed' should be a vector. 'velocity' could be a vector, but that is precisely the name for the product of the (scalar) speed with (normalized vector) direction.
Quote:Original post by Zahlman
From context, it looks like you've defined operator* to be a cross product


I think he defined it to mean component-wise multiplication.

BTW, why does this line compile:

GetDirectionVektor() + RunRule1() + RunRule2()).GetX() == 0

Aren't you trying to add a scalar (the return value of GetX()) to a vector?
Quote:Original post by Gage64
Quote:Original post by Zahlman
From context, it looks like you've defined operator* to be a cross product


I think he defined it to mean component-wise multiplication.
Yes I did, there are extra functions for dot and cross product. For me (never heard about the 'velocity' you mentioned) my version looks good/suitable. If it is not (or it could be improved) please say so.

Quote:Original post by Gage64
BTW, why does this line compile:

GetDirectionVektor() + RunRule1() + RunRule2()).GetX() == 0

Aren't you trying to add a scalar (the return value of GetX()) to a vector?

RunRule1 and RunRule2 returns vectors. Also you have to look at the brackets(looks a bit ugly without code-tags): (GetDirectionVektor() + RunRule1() + RunRule2()).GetX() == 0
The addition returns also a vector. (what a surprise :D)
Quote:Original post by Pille456
Quote:Original post by Gage64
Quote:Original post by Zahlman
From context, it looks like you've defined operator* to be a cross product


I think he defined it to mean component-wise multiplication.
Yes I did


This is also a... suspicious operation, though not quite as much.

Quote:For me (never heard about the 'velocity' you mentioned) my version looks good/suitable.


If you are not familiar with the concept of "velocity", then you really need to stop and learn some actual physics before attempting to write more code of this sort. :)

But think about it: the whole point of the concept of "direction" is to say which way the object is going, hmm? So why would you need to encode any information with separate x/y/z components into the "speed"? If you do actually have the same value for each of the components, then that's just redundant.
Quote:Original post by Zahlman
This is also a... suspicious operation, though not quite as much.

hmm yeha its a bit strange, but I thought it could be confusing using the * operator for the cross or dot product, therefore I've chosen the
more intuitive alternative (even if this is not the mathematics one)
I searched a bit and found out, that using a scalar instead of a vector for the speed is the concept of "velocity", isnt it? Well okay I do not have a force and stuff like that, but for a rectilinear uniform motion(a motion with constant speed) (is that the word? dont know, sry..) it should be enough.

This topic is closed to new replies.

Advertisement