Dot product limitation
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.
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.. =)
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);}
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
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
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 ;)
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 ;)
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 stillvecVector perp1 = childvec - projVector perp2 = perp1 normalizedfloat scalar_perp = sqrt(1 - dot_limit * dot_limit)return dot_limit * stillvec + scalar_perp * perp2
There are some really detailed answers here. I really appreciate the time you guys put into it. I'm still looking over it all.
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?
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 stillvecVector perp1 = childvec - projVector perp2 = perp1 normalizedfloat 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?
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
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement