• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            Maths - Angle between vectors

            LINK: http://www.euclideanspace.com/maths/algebra/vectors/angleBetween/index.htm

            How do we calculate the angle between two vectors?

            For 2D Vectors

            This is relatively simple because there is only one degree of freedom for 2D rotations. If v1 and v2 are normalised so that |v1|=|v2|=1, then,

            angle = acos(v1•v2)

            where:

            • • = 'dot' product (see box on right of page).
            • acos = arc cos = inverse of cosine function see trigonometry page.
            • |v1|= magnitude of v1.

            The only problem is, this won't give all possible values between 0° and 360°, or -180° and +180°. In other words, it won't tell us if v1 is ahead or behind v2, to go from v1 to v2 is the opposite direction from v2 to v1.

            In most math libraries acos will usually return a value between 0 and PI (in radians) which is 0° and 180°.

            If we want a + or - value to indicate which vector is ahead, then we probably need to use the atan2 function (as explained on this page). using:

            angle of 2 relative to 1= atan2(v2.y,v2.x) - atan2(v1.y,v1.x)

            For 3D Vectors

            Axis Angle Result

            This is easiest to calculate using axis-angle representation because:

            • the angle is given by acos of the dot product of the two (normalised) vectors: v1•v2 = |v1||v2| cos(angle)
            • the axis is given by the cross product of the two vectors, the length of this axis is given by |v1 x v2| = |v1||v2| sin(angle).

            as explained here

            this is taken from this discussion.

            So, if v1 and v2 are normalised so that |v1|=|v2|=1, then,

            angle = acos(v1•v2)

            axis = norm(v1 x v2)

            If the vectors are parallel (angle = 0 or 180 degrees) then the length of v1 x v2 will be zero because sin(0)=sin(180)=0. In the zero case the axis does not matter and can be anything because there is no rotation round it. In the 180 degree case the axis can be anything at 90 degrees to the vectors so there is a whole range of possible axies.

            angle (degrees) sin(angle) cos(angle) v1•v2 v1 x v2
            0 0 1 1 0,0,0
            90 1 0 0 unit len
            180 0 -1 -1 0,0,0
            270 -1 0 0 unit len

            Quaternion Result

            One approach might be to define a quaternion which, when multiplied by a vector, rotates it:

            p2=q * p1

            This almost works as explained on this page.

            However, to rotate a vector, we must use this formula:

            p2=q * p1 * conj(q)

            where:

            • p2 = is a vector representing a point after being rotated
            • q = is a quaternion representing a rotation.
            • p1= is a vector representing a point before being rotated

            This is a bit messy to solve for q, I am therefore grateful to minorlogic for the following approach which converts the axis angle result to a quaternion:

            The axis angle can be converted to a quaternion as follows, let x,y,z,w be elements of quaternion, these can be expressed in terms of axis angle as explained here.

            angle = arcos(v1•v2/ |v1||v2|)
            axis = norm(v1 x v2)
            s = sin(angle/2)
            x = axis.x *s
            y = axis.y *s
            z = axis.z *s
            w = cos(angle/2)

            We can use this half angle trig formula on this page: sin(angle/2) = 0.5 sin(angle) / cos(angle/2)

            so substituting in quaternion formula gives:
            s = 0.5 sin(angle) / cos(angle/2)
            x = norm(v1 x v2).x *s
            y = norm(v1 x v2).y *s
            z = norm(v1 x v2).z *s
            w = cos(angle/2)

            multiply x,y,z and w by 2* cos(angle/2) (this will de normalise the quaternion but we can always normalise later)

            x = norm(v1 x v2).x * sin(angle)
            y = norm(v1 x v2).y * sin(angle)
            z = norm(v1 x v2).z * sin(angle)
            w = 2 * cos(angle/2) * cos(angle/2)

            now substitute half angle trig formula on this page: cos(angle/2) = sqrt(0.5*(1 + cos (angle)))

            x = norm(v1 x v2).x * sin(angle)
            y = norm(v1 x v2).y * sin(angle)
            z = norm(v1 x v2).z * sin(angle)
            w = 1 + cos (angle)

            because |v1 x v2| = |v1||v2| sin(angle) we can normalise (v1 x v2) by dividing it with sin(angle),

            also apply v1•v2 = |v1||v2| cos(angle)so,

            x = (v1 x v2).x / |v1||v2|
            y = (v1 x v2).y/ |v1||v2|
            z = (v1 x v2).z/ |v1||v2|
            w = 1 + v1•v2 / |v1||v2|

            If v1 and v2 are already normalised then |v1||v2|=1 so,

            x = (v1 x v2).x
            y = (v1 x v2).y
            z = (v1 x v2).z
            w = 1 + v1•v2

            If v1 and v2 are not already normalised then multiply by |v1||v2| gives:

            x = (v1 x v2).x
            y = (v1 x v2).y
            z = (v1 x v2).z
            w = |v1||v2| + v1•v2

            Matrix Result

            Using the quaternion to matrix conversion here we get:

            1 - 2*qy2 - 2*qz2 2*qx*qy - 2*qz*qw 2*qx*qz + 2*qy*qw
            2*qx*qy + 2*qz*qw 1 - 2*qx2 - 2*qz2 2*qy*qz - 2*qx*qw
            2*qx*qz - 2*qy*qw 2*qy*qz + 2*qx*qw 1 - 2*qx2 - 2*qy2

            so substituting the quaternion results above into the matrix we get:

            1 - 2*(v1 x v2).y2 - 2*(v1 x v2).z2 2*(v1 x v2).x*(v1 x v2).y - 2*(v1 x v2).z*(1 + v1•v2) 2*(v1 x v2).x*(v1 x v2).z + 2*(v1 x v2).y*(1 + v1•v2)
            2*(v1 x v2).x*(v1 x v2).y + 2*(v1 x v2).z*(1 + v1•v2) 1 - 2*(v1 x v2).x2 - 2*(v1 x v2).z2 2*(v1 x v2).y*(v1 x v2).z - 2*(v1 x v2).x*(1 + v1•v2)
            2*(v1 x v2).x*(v1 x v2).z - 2*(v1 x v2).y*(1 + v1•v2) 2*(v1 x v2).y*(v1 x v2).z + 2*(v1 x v2).x*(1 + v1•v2) 1 - 2*(v1 x v2).x2 - 2*(v1 x v2).y2

            Substituting the following expansions:

            (v1 x v2).x = v1.y * v2.z - v2.y * v1.z
            (v1 x v2).y = v1.z * v2.x - v2.z * v1.x
            (v1 x v2).z = v1.x * v2.y - v2.x * v1.y
            (v1 x v2).x2 = v1.y * v2.z * v1.y * v2.z + v2.y * v1.z * v2.y * v1.z - 2 * v2.y * v1.z * v1.y * v2.z
            (v1 x v2).y2 = v1.z * v2.x * v1.z * v2.x + v2.z * v1.x * v2.z * v1.x - 2* v2.z * v1.x * v1.z * v2.x
            (v1 x v2).z2 = v1.x * v2.y * v1.x * v2.y +v2.x * v1.y * v2.x * v1.y - 2 * v2.x * v1.y * v1.x * v2.y
            v1•v2 = v1.x * v2.x + v1.y * v2.y + v1.z * v2.z

            This is getting far too complicated ! can anyone help me simplify this?

            Thank you again to minorlogic who gave me the following solution:

            Hi !
            and i think can help in matrix version.

            you can use :
            http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToMatrix/index.htm

            And will get some thing :

            matrix33 RotAngonst vector3& from, const vector3& to )
            {
            from.norm();
            to.norm();

            vector3 vs = cross(from, to); // axis multiplied by sin

            vector3 v(vs);
            v.norm(); // axis of rotation
            float ca = dot(from, to) ; // cos angle

            vector3 vt(v*(1.0f - ca));

            matrix33 rotM;
            rotM.M11 = vt.x * v.x + ca;
            rotM.M22 = vt.y * v.y + ca;
            rotM.M33 = vt.z * v.z + ca;

            vt.x *= v.y;
            vt.z *= v.x;
            vt.y *= v.z;

            rotM.M12 = vt.x - vs.z;
            rotM.M13 = vt.z + vs.y;
            rotM.M21 = vt.x + vs.z;
            rotM.M23 = vt.y - vs.x;
            rotM.M31 = vt.z - vs.y;
            rotM.M32 = vt.y + vs.x;
            return rotM;
            }

            Code

            axis-angle version
            sfrotation angleBetween(sfvec3f v1,sfvec3f v2) {
            float angle;
            // turn vectors into unit vectors
            n1 = v1.norm();
            n2 = v2.norm();
            angle = Math.acos( sfvec3f.dot(n1,n2) );
            // if no noticable rotation is available return zero rotation
            // this way we avoid Cross product artifacts
            if( Math.abs(angle) < 0.0001 ) return new sfrotation( 0, 0, 1, 0 );
            // in this case there are 2 lines on the same axis
            if(Math.abs(angle)-Math.pi) < 0.001){
            n1 = n1.Rotx( 0.5f );
            // there are an infinite number of normals
            // in this case. Anyone of these normals will be
            // a valid rotation (180 degrees). so I rotate the curr axis by 0.5 radians this way we get one of these normals
            }
            sfvec3f axis = n1;
            axis.cross(n2);
            return new sfrotation(axis.x,axis.y,axis.z,angle);
            }
            
            quaternion version
            /** note v1 and v2 dont have to be nomalised, thanks to minorlogic for telling me about this:
            * http://www.euclideanspace.com/maths/algebra/vectors/angleBetween/minorlogic.htm
            */
            sfquat angleBetween(sfvec3f v1,sfvec3f v2) {
            float d = sfvec3f.dot(v1,v2);
            sfvec3f axis = v1;
            axis.cross(v2);
            float qw = (float)Math.sqrt(v1.len_squared()*v2.len_squared()) + d;
            if (qw < 0.0001) { // vectors are 180 degrees apart
            return (new sfquat(0,-v1.z,v1.y,v1.x)).norm;
            }
            sfquat q= new sfquat(qw,axis.x,axis.y,axis.z);
            return q.norm();
            }
            

            matrix version

            sfmatrix angleBetween(sfvec3f v1,sfvec3f v2) {
            // turn vectors into unit vectors
            n1 = v1.norm();
            n2 = v2.norm(); 	sfvec3f vs = new sfvec3f(n1);
            vs.cross(n2); // axis multiplied by sin	sfvec3f v = new sfvec3f(vs);
            v = v.norm(); // axis of rotation
            float ca = dot(n1, n2) ; // cos angle	sfvec3f vt = new sfvec3f(v);	vt.scale((1.0f - ca);	sfmatrix rotM = new sfmatrix();
            rotM.m11 = vt.x * v.x + ca;
            rotM.m22 = vt.y * v.y + ca;
            rotM.m33 = vt.z * v.z + ca;	vt.x *= v.y;
            vt.z *= v.x;
            vt.y *= v.z;	rotM.m12 = vt.x - vs.z;
            rotM.m13 = vt.z + vs.y;
            rotM.m21 = vt.x + vs.z;
            rotM.m23 = vt.y - vs.x;
            rotM.m31 = vt.z - vs.y;
            rotM.m32 = vt.y + vs.x;
            return rotM;
            }

            see also code from minorlogic

            posted on 2009-05-31 13:50 zmj 閱讀(1583) 評論(0)  編輯 收藏 引用

            99国产精品久久| 久久精品国产精品亚洲| 精品久久久久久国产| 色欲av伊人久久大香线蕉影院 | 欧美国产精品久久高清| 人妻无码αv中文字幕久久琪琪布 人妻无码久久一区二区三区免费 人妻无码中文久久久久专区 | 人人狠狠综合久久亚洲婷婷| 精品久久久久久久久久中文字幕| 久久国产成人精品国产成人亚洲| 精品国产99久久久久久麻豆| 青青青青久久精品国产| 亚洲精品无码久久久久| 久久久久久亚洲精品无码| 久久久精品人妻一区二区三区蜜桃| 青青草原1769久久免费播放| 亚洲中文字幕久久精品无码喷水| 99久久亚洲综合精品成人| 狠狠色婷婷久久综合频道日韩| 色综合色天天久久婷婷基地| 亚洲精品蜜桃久久久久久| 久久综合给合综合久久| 久久九九亚洲精品| 97久久国产亚洲精品超碰热 | 精品亚洲综合久久中文字幕| 久久久精品人妻一区二区三区蜜桃| 国产精品美女久久久久AV福利 | 久久无码国产| 国产视频久久| 一级做a爰片久久毛片16| 久久久av波多野一区二区| 色偷偷偷久久伊人大杳蕉| 亚洲国产另类久久久精品黑人| 亚洲另类欧美综合久久图片区| 久久久精品久久久久久 | 色天使久久综合网天天| 久久精品国产亚洲7777| 久久精品亚洲乱码伦伦中文| 精品乱码久久久久久夜夜嗨| 久久久久亚洲av成人无码电影 | 伊人久久大香线蕉无码麻豆| 少妇被又大又粗又爽毛片久久黑人|