Kest 547 Report post Posted July 23, 2009 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. 0 Share this post Link to post Share on other sites
Erik Rufelt 5901 Report post Posted July 23, 2009 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);} 0 Share this post Link to post Share on other sites
shultays 187 Report post Posted July 23, 2009 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 limitso if first element of childvector (cv) is x other one is sqrt(1-x^2)if you put this on the equationsv[0]*x + sv[1]*sqrt(1-x^2) = dot_limitthis is a second order equation so you will find two vectors, one should give -dot_limit other one should give +dot_limitwell equation is kinda hard to solve ^^ sorry I am not gonna work on itif your vectors are 3d it will be impossible, because there are infinite number of solution for it 0 Share this post Link to post Share on other sites
haegarr 7385 Report post Posted July 23, 2009 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 := az := norm( a x b )y := z x aWe then can express a as a' and b as b' in the local frame by applying dot-products, where obviouslya' == [ 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 likec' := [ 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 fora' . c' == Lwhere, due to definition, a' == [ 1 , 0 , 0 ] in the local frame. Since furtherc'_{x}^{2} + c'_{y}^{2} == 1is 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} * yAs 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 ;) 0 Share this post Link to post Share on other sites
SiCrane 11839 Report post Posted July 23, 2009 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 0 Share this post Link to post Share on other sites
Kest 547 Report post Posted July 23, 2009 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 SiCraneI'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 * perp2Dude, 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? 0 Share this post Link to post Share on other sites
SiCrane 11839 Report post Posted July 23, 2009 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 0 Share this post Link to post Share on other sites