Sign in to follow this  
Kest

Dot product limitation

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
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

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this