Jump to content
  • Advertisement
Sign in to follow this  
Kest

Dot product limitation

This topic is 3372 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

If I have two normalized vectors, and a dot product limitation, is there a cheap gimmick I could use to limit one vector to that dot product of the other vector, without computing angles and performing axis rotations? Here's the data I have: Vector stillvec; // Changes, but can't be changed for this operation Vector childvec; // Rotates around independently of stillvec float dot_state = Dot(stillvec,childvec); float dot_limit; // Probably about 0.5. I want to keep dot_state above this by modifying childvec I know there are a lot of neat tricks to be done with dot products, planes, distances, etc. But I don't know if any of them will help me here. I appreciate any advice.

Share this post


Link to post
Share on other sites
Advertisement
What do you mean by computing angles?
It is ok to use acos on the dot product to get the angle?

You could do something like the following, though perhaps you need to do it on the angle and not the dot-product for it to be accurate, but that would just require an acos on the dot_state.. but then again maybe not.. try write out the equations on paper and see if they give the correct result.
I haven't tried it but it feels like it could work.. =)

if(dot_state < dot_limit) {
distFromStill = (1.0 - dot_state);
distToLimit = (1.0 - dot_limit);
fraction = distToLimit / distFromStill;
childvec = childvec * fraction + stillvec * (1.0 - fraction);
}

Share this post


Link to post
Share on other sites
there are two vectors, and if their dot product is < dot_limit you will rotate one so dot of two will = dot_limit. did I get it right?

if abs of dot of two vectors is smaller than dot_limit you should find the vector which gives dot product equal to dot limit



so if first element of childvector (cv) is x other one is sqrt(1-x^2)

if you put this on the equation


sv[0]*x + sv[1]*sqrt(1-x^2) = dot_limit

this is a second order equation so you will find two vectors, one should give -dot_limit other one should give +dot_limit

well equation is kinda hard to solve ^^ sorry I am not gonna work on it

if your vectors are 3d it will be impossible, because there are infinite number of solution for it

Share this post


Link to post
Share on other sites
Without haven proven it, I'd say "yes". Because:

Both given vectors a and b can be used to define a co-ordinate frame so that a is its principal x axis and b lies in its x-y plane (for example). The cross-product and vector normalization is needed for this purpose.
x := a
z := norm( a x b )
y := z x a

We then can express a as a' and b as b' in the local frame by applying dot-products, where obviously
a' == [ 1 , 0 , 0 ]
b' := [ b'x, b'y , 0 ]
will result.

Searching for a vector c' in-between the others means that it also lies in the x-y plane of that frame. Hence we are searching for something like
c' := [ c'x, c'y , 0 ]
so that the problem is reduced to 2 dimensions (all the z co-ordinates are 0).

The limit of the angle is the same in both frames, so that we're looking for
a' . c' == L
where, due to definition, a' == [ 1 , 0 , 0 ] in the local frame. Since further
c'x2 + c'y2 == 1
is required (a rotation doesn't change the length), we have a quadratic equation with 1 variable left. We are interested in the one solution that points in the same direction as b' - a', what can be checked by another dot-product.

Using the resulting c'x and c'y as co-efficient will result in the vector of interest:
c := c'x * x + c'y * y


As said, its a theory for now, so double check it, please. And, perhaps there is an easier way of doing the trick. And, last but not least, hopefully I've understood your problem correctly at all ;)

Share this post


Link to post
Share on other sites
I'm assuming you want all of the vector inputs and outputs to be normalized vectors. In that case you could use:

Vector proj = projection of childvec onto stillvec
Vector perp1 = childvec - proj
Vector perp2 = perp1 normalized
float scalar_perp = sqrt(1 - dot_limit * dot_limit)
return dot_limit * stillvec + scalar_perp * perp2

Share this post


Link to post
Share on other sites
There are some really detailed answers here. I really appreciate the time you guys put into it. I'm still looking over it all.

Quote:
Original post by SiCrane
I'm assuming you want all of the vector inputs and outputs to be normalized vectors. In that case you could use:

Vector proj = projection of childvec onto stillvec
Vector perp1 = childvec - proj
Vector perp2 = perp1 normalized
float scalar_perp = sqrt(1 - dot_limit * dot_limit)
return dot_limit * stillvec + scalar_perp * perp2

Dude, you're awesome for laying the math out in code syntax for me (not sure if you remembered that I absorb it better that way or not). But I'm not sure I understand the first line. What would be the projection of childvec onto stillvec? Do you mean to smash it onto its normal? Something else?

Share this post


Link to post
Share on other sites
Vector projection. In this case, if the input vector is normalized the denominator of the final formula drops out since a normalized vector dot itself is 1. So you could change the first line to:

Vector proj = dot_state * stillvec

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!