1、定义。

DIRECTX9文档中定义,令q为一四元数,theta为绕轴axis旋转的角度,则:
q.x = sin(theta/2) * axis.x
q.y = sin(theta/2) * axis.y
q.z = sin(theta/2) * axis.z
q.w = cos(theta/2)

可以简单写为:q = [sin(theta/2)axis, sin(theta/2)w] 或者 [x,y,z,w] 或者[v,w]

2、负四元数-q 。
-q = [-q.x, -q.y, -q.z, -q.w]

3D几何意义:轴变换了方向,角度也换了方向,刚好 -q = q。这个特性比较郁闷,在3D中任意方位,都有2种不同的四元数表示方法,竟然不是唯一的。

3、单位四元数q = [0,0,0,1].
3D几何意义:好像还看不出有什么几何意义。补充:用处是为了表示旋转0角度,一般用在变量初始化,和矩阵的单位初始话一个道理。
D3DXQuaternionIdentity

D3DXQuaternionIsIdentity

4、四元数的长度或者模 ||q||。
D3DXQuaternionLengthSq 长度的平方 = x*x + y*y + z*z + w*w;
D3DXQuaternionLength 长度,上式的平方根。
根据3D中四元数的定义,只有单位长度的四元数才有意义。尽管在DIRECTX中很多公式并不要求单位四元数,但是我们必须明白,只有单位四元数才有意义。补充:单位四元数的长度为1.

D3DXQuaternionNormalize,这个公式是求标准四元数,类似矢量的正则化。

5、共轭: [-x, -y, -z, w]。逆:共轭除于长度,记为q-1 。
共轭: D3DXQuaternionConjugate
逆:D3DXQuaternionInverse

3D几何意义:相当于转了一个相反的角。由于3D中只有单位长度的四元数才有意义,共轭和逆是一样的。

6、四元数的点积。
D3DXQuaternionDot
q1.q2 = [v1,w1].[v2,w2]=v1.v2 + w1.w2 = x1x2+y1y2+z1z2+w1w2;

3D几何意义:绝对值越大,2个方位越近似,夹角的余弦。补充:对于单位四元数,有-1 <= a.b <= +1,我们一般只关心其绝对值,和矢量点乘类似,绝对值越大,表示2个角度的角位移越小(即相似)。

7、四元数的叉积,一般我们说四元数的乘,指的就是这个叉积。
D3DXQuaternionMultiply
[v1,w1] X [v2,w2] = [w1v2 + w2v1 + v1 X v2, w1w2 - v1.v2];
=[ w1x2 + x1w2 + z1y2 - y1z2,
w1y2 + y1w2 + x1z2 - z1x2,
w1z2 + z1w2 + y1x2 - x1y2,
w1w2 - x1x2 - y1y2 - z1z2 ]
特性:
a、 结合律 (ab)c = a(bc). 交换律不满足ab != ba 
b、 ||q1 q2|| = ||q1|| ||q2|| 这个说明:单位四元数相乘的结果还是单位四元数。
c、 (ab)-1 = b-1a-1. 这个和矩阵的逆是一样的。同理:

(Q1Q2...Q(n-1)Qn)-1 = Qn-1Q(n-1)-1...Q2-1Q1-1

8、四元数的差:一个方位到另一个方位的角位移。方位a旋转到b的角位移为d,则ad = b. 经过推导:d = a-1b

这个差找不到相应的DIRECTX公式。

9、四元数的对数、指数运算。

D3DXQuaternionLn,描述为:
A unit quaternion, is defined by:
Q == (cos(theta), sin(theta) * v) where |v| = 1
The natural logarithm of Q is, ln(Q) = (0, theta * v)

D3DXQuaternionExp,描述为:
Given a pure quaternion defined by:
Q = (0, theta * v);
This method calculates the exponential result.

exp(Q) = (cos(theta), sin(theta) * v)

10、四元数的插值--slerp
D3DXQuaternionSlerp
四元数的精华就是可以线性平滑的进行插值。slerp__ Spherical Liear Interpolation.
令矢量v0 v1之间的夹角为a, vt = k0v0 + k1v1;
则:k0 = sin((1-t)a)/sin(a); k1 = sin(ta)/sin(a);

其中,二四元数之间的夹角余弦可以用点积来计算:x1x2+y1y2+z1z2+w1w2;

11、四个四元数之间的插值__Squad。很显然是为了插值平滑平保证过渡点之间连续(DIRECTX 文档说是保证过渡点间的切线连续,可以理解为矢量插值的二阶连续)。用到如下2个公式:
D3DXQuaternionSquadSetup
D3DXQuaternionSquad
DIRCTX 文档中的例子:
The following example shows how to use a set of quaternion keys (Q0, Q1, Q2, Q3) to compute the inner quadrangle points (A, B, C). This ensures that the tangents are continuous across adjacent segments.
A B Q0 Q1 Q2 Q3
The following code example demonstrates how you can interpolate between Q1 and Q2.
// Rotation about the z-axis
D3DXQUATERNION Q0 = D3DXQUATERNION(0, 0, 0.707f, -.707f);
D3DXQUATERNION Q1 = D3DXQUATERNION(0, 0, 0.000f, 1.000f);
D3DXQUATERNION Q2 = D3DXQUATERNION(0, 0, 0.707f, 0.707f);
D3DXQUATERNION Q3 = D3DXQUATERNION(0, 0, 1.000f, 0.000f);
D3DXQUATERNION A, B, C, Qt;
FLOAT time = 0.5f;
D3DXQuaternionSquadSetup(&A, &B, &C, &Q0, &Q1, &Q2, &Q3);
D3DXQuaternionSquad(&Qt, &Q1, &A, &B, &C, time);
注意: 
1 C is +/- Q2 depending on the result of the function. (这点我还是不太明白哦?)
2 Qt is the result of the function.
The result is a rotation of 45 degrees around the z-axis for time = 0.5.

DIRCTX9 的例子:SkinnedMesh Sample.

12、四元数和矩阵的变换
a. 矩阵变换到四元数,D3DXQuaternionRotationMatrix
b. 更一般的,矩阵分解为比例,旋转和位移三个分量:HRESULT WINAPI D3DXMatrixDecompose
( D3DXVECTOR3 *pOutScale, D3DXQUATERNION *pOutRotation,
D3DXVECTOR3 *pOutTranslation, CONST D3DXMATRIX *pM );
c. 四元数变换到矩阵
D3DXMATRIX* WINAPI D3DXMatrixRotationQuaternion
( D3DXMATRIX *pOut, CONST D3DXQUATERNION *pQ);
13、四元数和欧拉角的变换
a. 欧拉角到四元数
// Yaw around the Y axis, a pitch around the X axis,
// and a roll around the Z axis.
D3DXQUATERNION* WINAPI D3DXQuaternionRotationYawPitchRoll
( D3DXQUATERNION *pOut, FLOAT Yaw, FLOAT Pitch, FLOAT Roll );
b.绕轴旋转
// Rotation about arbitrary axis.
D3DXQUATERNION* WINAPI D3DXQuaternionRotationAxis

( D3DXQUATERNION *pOut, CONST D3DXVECTOR3 *pV, FLOAT Angle );

插值的例子:

bool AnimationModelClass::UpdateMD5Model(float deltaTime, int animation)
{   MD5Model.m_animations[animation].currAnimTime += deltaTime;         // Update the current animation timeif(MD5Model.m_animations[animation].currAnimTime > MD5Model.m_animations[animation].totalAnimTime)MD5Model.m_animations[animation].currAnimTime = 0.0f;// Which frame are we onfloat currentFrame = MD5Model.m_animations[animation].currAnimTime * MD5Model.m_animations[animation].frameRate;    int frame0 = floorf( currentFrame );int frame1 = frame0 + 1;// Make sure we don't go over the number of frames  if(frame0 == MD5Model.m_animations[animation].numFrames-1)frame1 = 0;float interpolation = currentFrame - frame0;    // Get the remainder (in time) between frame0 and frame1 to use as interpolation factorstd::vector<Joint> interpolatedSkeleton;        // Create a frame skeleton to store the interpolated skeletons in// Compute the interpolated skeletonfor( int i = 0; i < MD5Model.m_animations[animation].numJoints; i++){Joint tempJoint;Joint joint0 = MD5Model.m_animations[animation].frameSkeleton[frame0][i];       // Get the i'th joint of frame0's skeletonJoint joint1 = MD5Model.m_animations[animation].frameSkeleton[frame1][i];       // Get the i'th joint of frame1's skeletontempJoint.parentID = joint0.parentID;                                           // Set the tempJoints parent id// Turn the two quaternions into XMVECTORs for easy computationsD3DXQUATERNION joint0Orient = D3DXQUATERNION(joint0.orientation.x, joint0.orientation.y, joint0.orientation.z, joint0.orientation.w);D3DXQUATERNION joint1Orient = D3DXQUATERNION(joint1.orientation.x, joint1.orientation.y, joint1.orientation.z, joint1.orientation.w);// Interpolate positionstempJoint.pos.x = joint0.pos.x + (interpolation * (joint1.pos.x - joint0.pos.x));tempJoint.pos.y = joint0.pos.y + (interpolation * (joint1.pos.y - joint0.pos.y));tempJoint.pos.z = joint0.pos.z + (interpolation * (joint1.pos.z - joint0.pos.z));// Interpolate orientations using spherical interpolation (Slerp)D3DXQUATERNION qtemp;D3DXQuaternionSlerp(&qtemp, &joint0Orient, &joint1Orient, interpolation);tempJoint.orientation.x = qtemp.x;tempJoint.orientation.y = qtemp.y;tempJoint.orientation.z = qtemp.z;tempJoint.orientation.w = qtemp.w;// Push the joint back into our interpolated skeletoninterpolatedSkeleton.push_back(tempJoint);      }for ( int k = 0; k < MD5Model.numSubsets; k++){for ( int i = 0; i < MD5Model.m_subsets[k].numVertices; ++i ){Vertex tempVert = MD5Model.m_subsets[k].m_vertices[i];// Make sure the vertex's pos is cleared firsttempVert.x = 0;tempVert.y = 0;tempVert.z = 0;// Clear vertices normaltempVert.nx = 0;tempVert.ny = 0;tempVert.nz = 0;// Sum up the joints and weights information to get vertex's position and normalfor ( int j = 0; j < tempVert.WeightCount; ++j ){Weight tempWeight = MD5Model.m_subsets[k].m_weights[tempVert.StartWeight + j];Joint tempJoint = interpolatedSkeleton[tempWeight.jointID];// Convert joint orientation and weight pos to vectors for easier computationD3DXQUATERNION tempJointOrientation = D3DXQUATERNION(tempJoint.orientation.x, tempJoint.orientation.y, tempJoint.orientation.z, tempJoint.orientation.w);D3DXQUATERNION tempWeightPos = D3DXQUATERNION(tempWeight.pos.x, tempWeight.pos.y, tempWeight.pos.z, 0.0f);// We will need to use the conjugate of the joint orientation quaternionD3DXQUATERNION tempJointOrientationConjugate;D3DXQuaternionInverse(&tempJointOrientationConjugate, &tempJointOrientation);// Calculate vertex position (in joint space, eg. rotate the point around (0,0,0)) for this weight using the joint orientation quaternion and its conjugate// We can rotate a point using a quaternion with the equation "rotatedPoint = quaternion * point * quaternionConjugate"D3DXVECTOR3 rotatedPoint;D3DXQUATERNION qqtemp;D3DXQuaternionMultiply(&qqtemp, &tempJointOrientation, &tempWeightPos);D3DXQuaternionMultiply(&qqtemp, &qqtemp, &tempJointOrientationConjugate);rotatedPoint.x = qqtemp.x;rotatedPoint.y = qqtemp.y;rotatedPoint.z = qqtemp.z;// Now move the verices position from joint space (0,0,0) to the joints position in world space, taking the weights bias into accounttempVert.x += ( tempJoint.pos.x + rotatedPoint.x ) * tempWeight.bias;tempVert.y += ( tempJoint.pos.y + rotatedPoint.y ) * tempWeight.bias;tempVert.z += ( tempJoint.pos.z + rotatedPoint.z ) * tempWeight.bias;// Compute the normals for this frames skeleton using the weight normals from before// We can comput the normals the same way we compute the vertices position, only we don't have to translate them (just rotate)D3DXQUATERNION tempWeightNormal = D3DXQUATERNION(tempWeight.normal.x, tempWeight.normal.y, tempWeight.normal.z, 0.0f);D3DXQuaternionMultiply(&qqtemp, &tempJointOrientation, &tempWeightNormal);D3DXQuaternionMultiply(&qqtemp, &qqtemp, &tempJointOrientationConjugate);// Rotate the normalrotatedPoint.x = qqtemp.x;rotatedPoint.y = qqtemp.y;rotatedPoint.z = qqtemp.z;  // Add to vertices normal and ake weight bias into accounttempVert.nx -= rotatedPoint.x * tempWeight.bias;tempVert.ny -= rotatedPoint.y * tempWeight.bias;tempVert.nz -= rotatedPoint.z * tempWeight.bias;}// Store the vertices position in the position vector instead of straight into the vertex vectorMD5Model.m_subsets[k].m_positions[i].x = tempVert.x;    MD5Model.m_subsets[k].m_positions[i].y = tempVert.y;    MD5Model.m_subsets[k].m_positions[i].z = tempVert.z;    // Store the vertices normalMD5Model.m_subsets[k].m_vertices[i].nx = tempVert.nx;   MD5Model.m_subsets[k].m_vertices[i].ny = tempVert.ny;   MD5Model.m_subsets[k].m_vertices[i].nz = tempVert.nz;   // Create the temp D3DXVECTOR3 for normalizeD3DXVECTOR3 dtemp = D3DXVECTOR3(0,0,0);dtemp.x = MD5Model.m_subsets[k].m_vertices[i].nx;dtemp.y = MD5Model.m_subsets[k].m_vertices[i].ny;dtemp.z = MD5Model.m_subsets[k].m_vertices[i].nz;D3DXVec3Normalize(&dtemp, &dtemp);MD5Model.m_subsets[k].m_vertices[i].nx = dtemp.x;MD5Model.m_subsets[k].m_vertices[i].ny = dtemp.y;MD5Model.m_subsets[k].m_vertices[i].nz = dtemp.z;// Put the positions into the vertices for this subsetMD5Model.m_subsets[k].m_vertices[i].x = MD5Model.m_subsets[k].m_positions[i].x;MD5Model.m_subsets[k].m_vertices[i].y = MD5Model.m_subsets[k].m_positions[i].y;MD5Model.m_subsets[k].m_vertices[i].z = MD5Model.m_subsets[k].m_positions[i].z;}// Update the subsets vertex buffer// First lock the buffervoid* mappedVertBuff;bool result;result = MD5Model.m_subsets[k].vertBuff->Map(D3D10_MAP_WRITE_DISCARD, 0, &mappedVertBuff);if(FAILED(result)){return false;}// Copy the data into the vertex buffer.memcpy(mappedVertBuff, &MD5Model.m_subsets[k].m_vertices[0], (sizeof(Vertex) * MD5Model.m_subsets[k].numVertices));MD5Model.m_subsets[k].vertBuff->Unmap();}return true;
}

相关的函数:

D3DXQUATERNION* WINAPI D3DXQuaternionBaryCentric//三个四元数的重心
D3DXQUATERNION* D3DXQuaternionConjugate   //求共轭四元数
FLOAT D3DXQuaternionDot     //四元数点乘
D3DXQUATERNION* WINAPI D3DXQuaternionExp //四元数指数
D3DXQUATERNION* WINAPI D3DXQuaternionInverse//共轭变换并规格化四元数
D3DXQUATERNION* D3DXQuaternionIdentity   //单位四元数
BOOL D3DXQuaternionIsIdentity    //判断单位四元数
FLOAT D3DXQuaternionLength    //返回四元数长度
FLOAT D3DXQuaternionLengthSq    //返回四元数长度平方
D3DXQUATERNION* WINAPI D3DXQuaternionLn   //计算自然对数
D3DXQUATERNION* WINAPI D3DXQuaternionMultiply //两个四元数相乘
D3DXQUATERNION* WINAPI D3DXQuaternionNormalize //单位长度的四元数
D3DXQUATERNION* WINAPI D3DXQuaternionRotationAxis//绕轴旋转四元数
D3DXQUATERNION* WINAPI D3DXQuaternionRotationMatrix//旋转矩阵创建四元数
D3DXQUATERNION* WINAPI D3DXQuaternionRotationYawPitchRoll//绕XYZ旋转创建的四元数
D3DXQUATERNION* WINAPI D3DXQuaternionSlerp //两个四元数球面插值
D3DXQUATERNION* WINAPI D3DXQuaternionSquad //球面四边形插四元数
void WINAPI D3DXQuaternionSquadSetup //创建球面四边形插值的控制点
void WINAPI D3DXQuaternionToAxisAngle//向量绕自身旋转角度计算四元数

四元数旋转物品:

首先我们需要定义一些变量来储存所需信息
D3DXQUATERNION g_qNow, g_qDown; //分别是 现在的旋转用四元数 按下鼠标时的旋转用四元数
D3DXVECTOR3 g_vDownPt, g_vCurrentPt; //分别是 按下鼠标时的球面上的位置向量 当前的位置向量
bool g_bDrag = false; //是否按下鼠标左键 用来判断按键拖拽

然后初始化这些变量
D3DXQuaternionIdentity(&g_qNow);
D3DXQuaternionIdentity(&g_qDown);
g_bDrag = false;
好了,初始化工作做完了,然后具体讲下算法。
在鼠标按下处理过程

case WM_LBUTTONDOWN:
   {
    int iMouseX = ( short )LOWORD( lParam );
    int iMouseY = ( short )HIWORD( lParam );    //得到屏幕坐标
    g_bDrag = true;
    g_qDown = g_qNow;
    g_vDownPt = ScreenToVector( ( float )iMouseX, ( float )iMouseY );   //得到投影窗口下的坐标
   }
在鼠标移动处理过程

case WM_MOUSEMOVE:
   {
    if( g_bDrag )
    {
     int iMouseX = ( short )LOWORD( lParam );
     int iMouseY = ( short )HIWORD( lParam );  //得到屏幕坐标
     g_vCurrentPt = ScreenToVector( ( float )iMouseX, ( float )iMouseY );//得到投影窗口下的坐标
     g_qNow = g_qDown * QuatFromBallPoints( g_vDownPt, g_vCurrentPt );
    }
   }

//看看QuatFromBallPoints函数

D3DXQUATERNION QuatFromBallPoints( const D3DXVECTOR3& vFrom, const D3DXVECTOR3& vTo )
{
 D3DXVECTOR3 vPart;

float fDot = D3DXVec3Dot( &vFrom, &vTo ); //取得两向量的点乘,因为两个都是单位向量,所以fDot等于cos theta

D3DXVec3Cross( &vPart, &vFrom, &vTo );//叉乘,获得的是垂直于两个向量的一个向量,即旋转轴。其模等于|a||b|sin theta等于sin theta

return D3DXQUATERNION( vPart.x, vPart.y, vPart.z, fDot );//正好构成一个旋转2*theta角度的四元数

}

首先说一下旋转四元数,一个(x*sin theta, y*sin theta, z*sin theta, cos theta)的四元数被用来旋转2*theta角度。在上面的代码中通过两个单位向量得到了一个旋转四元数。从效果上来说就是鼠标在球体上做过theta角度,物体就旋转2*theta角度。这是一个很方便的解决方法,不仅省却了换算,也使得物体能够在一次拖拽中旋转360度。现在大部分事情都清楚了,接下来只要在绘制之前把世界矩阵按所得的旋转四元数旋转之后绘制物体就可以了。
我们使用D3DXMatrixRotationQuaternion这个函数从四元数得到一个旋转矩阵作为世界矩阵。
D3DXMATRIXA16 matWorld;
D3DXMatrixRotationQuaternion( &matWorld, &g_qNow );
g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
至此完成,我们只需要在每一次绘制的时候按当前的旋转四元数即g_qNow来设置世界矩阵即可。

//
for (unsigned int i = 0; i < bones->size(); i++) {// unsigned long t0, t1;D3DXQUATERNION q0, q1;D3DXVECTOR3 p0, p1;//========================================//========================================if (ite_keyFrames[i] != keyFrames[i].end()) {//t0 = (*ite_keyFrames[i]).frameNo;//boneRot[i] = q0 = (*ite_keyFrames[i]).rotation;//bonePos[i] = p0 = (*ite_keyFrames[i]).position;//if (++ite_keyFrames[i] != keyFrames[i].end()) {//KeyFrame k = *ite_keyFrames[i];//t1 = k.frameNo;//q1 = k.rotation;//p1 = k.position;//========================================//(25 - 10) / 30 - 10 = 3 / 4 = 0.75 → 75%//========================================float s = (float)(time - t0) / (float)(t1 - t0);//========================================//========================================D3DXQuaternionSlerp(&boneRot[i], &q0, &q1, k.bezie_r->GetY(s));bonePos[i].x = p0.x + (p1.x - p0.x)*k.bezie_x->GetY(s);bonePos[i].y = p0.y + (p1.y - p0.y)*k.bezie_y->GetY(s);bonePos[i].z = p0.z + (p1.z - p0.z)*k.bezie_z->GetY(s);if (time != t1) --ite_keyFrames[i];}}//========================================//========================================D3DXMATRIX rot, trans;D3DXMatrixRotationQuaternion(&rot, &boneRot[i]);D3DXMatrixTranslation(&trans, bonePos[i].x, bonePos[i].y, bonePos[i].z);//========================================//========================================(*bones)[i].boneMatBL = rot*trans*(*bones)[i].initMatBL;}

参考:

http://blog.csdn.net/silangquan/article/details/50390570
http://blog.csdn.net/ycl295644/article/details/50961201

1. C++标准模板库从入门到精通

http://edu.csdn.net/course/detail/3324

2.跟老菜鸟学C++

http://edu.csdn.net/course/detail/2901

3. 跟老菜鸟学python

http://edu.csdn.net/course/detail/2592

4. 在VC2015里学会使用tinyxml库

http://edu.csdn.net/course/detail/2590

5. 在Windows下SVN的版本管理与实战

http://edu.csdn.net/course/detail/2579

6.Visual Studio 2015开发C++程序的基本使用

http://edu.csdn.net/course/detail/2570

7.在VC2015里使用protobuf协议

http://edu.csdn.net/course/detail/2582

8.在VC2015里学会使用MySQL数据库

http://edu.csdn.net/course/detail/2672

D3D中四元数的表示相关推荐

  1. D3D中简单的截图方法 (转)

    [ZT]D3D中简单的截图方法 试了下,果然可以. 在渲染完所有东东后(Present之前) 获得BackBuffer表面 然后用D3DX的函数保存 void ScreenShot (char *fi ...

  2. D3D中材质通过D3DMATERIAL9结构说明

    光照的两大要素是光源和物体的材质,物体表面材质属性决定了它能反射什么颜色的光线以及反射多少光线. 一.Direct3D中材质的定义 D3D中材质通过D3DMATERIAL9结构来表示: typedef ...

  3. D3D中2D图片的绘制

    想要在D3D中加载2D图片可以使用如下两种方法(我只想到这两种方法,如果有其他方法,请指教).第一种就是把图片以纹理方式加载,然后以此为纹理绘制一个四边形即可:第二种就是使用2D点精灵,不解释,你懂得 ...

  4. D3D中2D图片的绘制两种方法

    2014/09/19 (转载自:http://blog.csdn.net/rabbit729/article/details/6388703) 想要在D3D中加载2D图片可以使用如下两种方法(我只想到 ...

  5. D3D中的纹理贴图(1)

    D3D中的纹理贴图(1) 提示: 阅读本文需要一定的3D图形学和DirectX9基础,如果你发现阅读困难,请参阅 D3D中基本三角形面的绘制. 本文用到的坐标系统变换函数请参阅 DirectX 9的坐 ...

  6. 在D3D中绘制一个三角形的一个完整过程(学习3D游戏笔记一)

    本笔记是基于Microsfot DirectX 9.0 SDK Update的SimpleSample生成的框架. 在3D场景中,所有的对象和模型均由三角形构成;而三角形由三个顶点构成;每个顶点不仅包 ...

  7. D3D中的网格(Mesh)

    该教程基于DirectX 8.0 Graphics, 一部分内容由DirectX 8.0 SDK 英文文档翻译而来,一部分是自己工作经验的总结,作者对此享有著作权,读者可任意拷贝和传播,但不包含商业的 ...

  8. D3D中基本立体面的绘制

    [转][收藏]2010-09-01 D3D中基本立体面的绘制 提示: 阅读本文需要一定的3D图形学和DirectX9基础,如果你发现阅读困难,请参阅D3D 中基本三角形面的绘制. 本文用到的坐标系统变 ...

  9. [ZZ] D3D中的模板缓存(3)

    http://www.cppblog.com/lovedday/archive/2008/03/25/45334.html http://www.cppblog.com/lovedday/ D3D中的 ...

最新文章

  1. Solr配置与简单Demo[转]
  2. ORACLE 定时执行存储过程
  3. java 多线程缓存_[Java教程]【JAVA并发编程实战】12、使用condition实现多线程下的有界缓存先进先出队列...
  4. mysql中ifnull函数
  5. 解决Ubuntu下pycharm无法输入中文的问题
  6. C#高级编程----反射的小结
  7. CAD软件中怎么计算雨水?CAD雨水计算技巧
  8. win10窗口设置眼睛保护色
  9. 众包专访:开源众包让我安心——开源中国众包使用记录
  10. 【CSS应用篇】——CSS如何实现渐变背景
  11. 【坐标系统】高斯克吕格平面直角坐标系(笔记)
  12. Migrando电子商务可以实现Iluria para o Shopify(Python的标准)
  13. 在线博客系统——获取用户信息,退出登录
  14. 经济危机为什么也是创业良机?
  15. 2020磺化工艺证考试及磺化工艺考试试题
  16. 微信公众号开发---自定义菜单的创建及菜单事件响应(java)
  17. Linux常用命令——tftp命令
  18. cartographer源码分析(4)sensor_bridge.cc以及sensor_bridge.h
  19. linux中配置 http_proxy 代理的方法
  20. 数组转JSON json对象 json字符串

热门文章

  1. 【USB笔记】 USB1.0与USB1.1差异概述
  2. 领域驱动设计DDD和CQRS落地
  3. (java)创建型模式之生成器模式
  4. 图像处理_Ostu算法(大律法、最大类间方差法)
  5. docker安装及修改默认镜像下载路径和配置加速器
  6. iview_admin兼容ie11,ie9
  7. OpenFlow:简述对OpenFlow协议1.3的认识
  8. 视频编辑软件‘编辑星’推百款圣诞新年素材
  9. react支持android5吗,react原生应用程序在真正的android设备上崩溃
  10. RabbitMQ 修改默认端口