程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 矩陣中的數學旋轉公式 轉換到 C++中函數 替換DirectX 9.0中D3DXMatrixRotationAxis函數

矩陣中的數學旋轉公式 轉換到 C++中函數 替換DirectX 9.0中D3DXMatrixRotationAxis函數

編輯:C++入門知識

首先看下數學公式:     由上面的數學公式,我們轉換的C++函數: [cpp]   //-----------------------------------------------------------------------------   // Name: setupRotate()   // Desc: 繞x,y,z軸旋轉,axis:1表示繞x軸,2表示y軸,3表示z軸   //-----------------------------------------------------------------------------   VOID setupRotate(D3DXMATRIXA16 *returnMatrix,int axis, float theta)   {   www.2cto.com     float s, c;       s = sin(theta),c=cos(theta);              switch (axis) {       case 1: // Rotate about the x-axis           returnMatrix->_11 = 1.0f; returnMatrix->_12 = 0.0f; returnMatrix->_13 = 0.0f; returnMatrix->_14 = 0.0f;           returnMatrix->_21 = 0.0f; returnMatrix->_22 = c; returnMatrix->_23 = s; returnMatrix->_24 = 0.0f;           returnMatrix->_31 = 0.0f; returnMatrix->_32 = -s; returnMatrix->_33 = c; returnMatrix->_34 = 0.0f;           returnMatrix->_41 = 0.0f; returnMatrix->_42 = 0.0f; returnMatrix->_43 = 0.0f; returnMatrix->_44 = 1.0f;           break;       case 2: // Rotate about the y-axis           returnMatrix->_11 = c; returnMatrix->_12 = 0.0f; returnMatrix->_13 = -s; returnMatrix->_14 = 0.0f;           returnMatrix->_21 = 0.0f; returnMatrix->_22 = 1.0f; returnMatrix->_23 = 0.0f; returnMatrix->_24 = 0.0f;           returnMatrix->_31 = s; returnMatrix->_32 = 0.0f; returnMatrix->_33 = c; returnMatrix->_34 = 0.0f;           returnMatrix->_41 = 0.0f; returnMatrix->_42 = 0.0f; returnMatrix->_43 = 0.0f; returnMatrix->_44 = 1.0f;           break;       case 3: // Rotate about the z-axis           returnMatrix->_11 = c; returnMatrix->_12 = s; returnMatrix->_13 = 0.0f; returnMatrix->_14 = 0.0f;           returnMatrix->_21 = -s; returnMatrix->_22 = c; returnMatrix->_23 = 0.0f; returnMatrix->_24 = 0.0f;           returnMatrix->_31 = 0.0f; returnMatrix->_32 = 0.0f; returnMatrix->_33 = 1.0f; returnMatrix->_34 = 0.0f;           returnMatrix->_41 = 0.0f; returnMatrix->_42 = 0.0f; returnMatrix->_43 = 0.0f; returnMatrix->_44 = 1.0f;           break;       default:           // bogus axis index           assert(false);       }   }   //-----------------------------------------------------------------------------   // Name: setupRotate()   // Desc: 繞自定義軸旋轉   //-----------------------------------------------------------------------------   VOID setupRotate(const D3DXVECTOR3 &axis, D3DXMATRIXA16 *returnMatrix, float theta)   {      //要旋轉的向量軸必須是單位向量,不然物體會變形      //assert(fabs(axis*axis - 1.0f) < .01f);      float s, c;       s = sin(theta),c=cos(theta);       // 計算出一些重復利用的子表達式。       float a = 1.0f - c;       float ax = a * axis.x;       float ay = a * axis.y;       float az = a * axis.z;       returnMatrix->_11 = ax*axis.x + c;       returnMatrix->_12 = ax*axis.y + axis.z*s;       returnMatrix->_13 = ax*axis.z - axis.y*s;       returnMatrix->_14 = 0.0f;       returnMatrix->_21 = ay*axis.x - axis.z*s;       returnMatrix->_22 = ay*axis.y + c;       returnMatrix->_23 = ay*axis.z + axis.x*s;       returnMatrix->_24 = 0.0f;       returnMatrix->_31 = az*axis.x + axis.y*s;       returnMatrix->_32 = az*axis.y - axis.x*s;       returnMatrix->_33 = az*axis.z + c;       returnMatrix->_34 = 0.0f;       returnMatrix->_41 = 0.0f;       returnMatrix->_42 = 0.0f;       returnMatrix->_43 = 0.0f;       returnMatrix->_44 = 1.0f;   }   可能會有人對上面函數中的D3DXMATRIXA16和D3DXVECTOR3不理解,他們其實是Direct3D中表示4維矩陣和3維向量的結構體,可是我們數學公式裡涉及到的是3維矩陣,可以看下下面的轉換,因為要設計到矩陣相乘,故只能4維矩陣跟4維矩陣相乘,故把3維的轉換成4維的了。 具體使用上面兩個函數的例子: [cpp]      // 旋轉      D3DXMATRIXA16 matWorld;   //自定義旋轉的軸   D3DXVECTOR3 axis(1.0f/sqrt(3), 1.0f/sqrt(3), 1.0f/sqrt(3));         D3DXMatrixIdentity( &matWorld );      /*DirectX 官方API*/      //D3DXMatrixRotationY( &matWorld, timeGetTime()/500.0f );      /*使用自定義旋轉函數1*/   //setupRotate(&matWorld,2,timeGetTime()/500.0f);         /*使用自定義旋轉函數2*/   setupRotate(axis,&matWorld,timeGetTime()/500.0f);      g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );     旋轉效果: 我稍微修改了下自定義旋轉的軸,改成一個非單位向量,(1.0f, 1.0f, 0.0f),旋轉效果(變形的飛起,哈哈): 完整代碼(看的麻煩的同學,可以拉到底下載整個項目來看): [cpp]  //-----------------------------------------------------------------------------   // File: Lights.cpp   // Copyright (c) Microsoft Corporation & Waitingfy.com. All rights reserved.   //-----------------------------------------------------------------------------   #include <Windows.h>   #include <mmsystem.h>   #include <d3dx9.h>   #include <strsafe.h>   #include <math.h>   #include <assert.h>            //-----------------------------------------------------------------------------   // Global variables   //-----------------------------------------------------------------------------   LPDIRECT3D9             g_pD3D       = NULL; // Used to create the D3DDevice   LPDIRECT3DDEVICE9       g_pd3dDevice = NULL; // Our rendering device   LPDIRECT3DVERTEXBUFFER9 g_pVB        = NULL; // Buffer to hold vertices   ID3DXMesh* Objects;//茶壺      // A structure for our custom vertex type. We added a normal, and omitted the   // color (which is provided by the material)   struct CUSTOMVERTEX   {       D3DXVECTOR3 position; // The 3D position for the vertex       D3DXVECTOR3 normal;   // The surface normal for the vertex   };      // Our custom FVF, which describes our custom vertex structure   #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_NORMAL)               //-----------------------------------------------------------------------------   // Name: InitD3D()   // Desc: Initializes Direct3D   //-----------------------------------------------------------------------------   HRESULT InitD3D( HWND hWnd )   {       // Create the D3D object.       if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )           return E_FAIL;          // Set up the structure used to create the D3DDevice. Since we are now       // using more complex geometry, we will create a device with a zbuffer.       D3DPRESENT_PARAMETERS d3dpp;       ZeroMemory( &d3dpp, sizeof(d3dpp) );       d3dpp.Windowed = TRUE;       d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;       d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;       d3dpp.EnableAutoDepthStencil = TRUE;       d3dpp.AutoDepthStencilFormat = D3DFMT_D16;          // Create the D3DDevice       if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,                                         D3DCREATE_SOFTWARE_VERTEXPROCESSING,                                         &d3dpp, &g_pd3dDevice ) ) )       {           return E_FAIL;       }          // Turn off culling       g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );          // Turn on the zbuffer       g_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );          return S_OK;   }            //-----------------------------------------------------------------------------   // Name: Cleanup()   // Desc: Releases all previously initialized objects   //-----------------------------------------------------------------------------   VOID Cleanup()   {       if( g_pVB != NULL )           g_pVB->Release();          if( g_pd3dDevice != NULL )           g_pd3dDevice->Release();          if( g_pD3D != NULL )           g_pD3D->Release();       if(Objects != NULL)          Objects->Release();   }   //-----------------------------------------------------------------------------   // Name: setupRotate()   // Desc: 繞x,y,z軸旋轉,axis:1表示繞x軸,2表示y軸,3表示z軸   //-----------------------------------------------------------------------------   VOID setupRotate(D3DXMATRIXA16 *returnMatrix,int axis, float theta)   {       float s, c;       s = sin(theta),c=cos(theta);              switch (axis) {       case 1: // Rotate about the x-axis           returnMatrix->_11 = 1.0f; returnMatrix->_12 = 0.0f; returnMatrix->_13 = 0.0f; returnMatrix->_14 = 0.0f;           returnMatrix->_21 = 0.0f; returnMatrix->_22 = c; returnMatrix->_23 = s; returnMatrix->_24 = 0.0f;           returnMatrix->_31 = 0.0f; returnMatrix->_32 = -s; returnMatrix->_33 = c; returnMatrix->_34 = 0.0f;           returnMatrix->_41 = 0.0f; returnMatrix->_42 = 0.0f; returnMatrix->_43 = 0.0f; returnMatrix->_44 = 1.0f;           break;       case 2: // Rotate about the y-axis           returnMatrix->_11 = c; returnMatrix->_12 = 0.0f; returnMatrix->_13 = -s; returnMatrix->_14 = 0.0f;           returnMatrix->_21 = 0.0f; returnMatrix->_22 = 1.0f; returnMatrix->_23 = 0.0f; returnMatrix->_24 = 0.0f;           returnMatrix->_31 = s; returnMatrix->_32 = 0.0f; returnMatrix->_33 = c; returnMatrix->_34 = 0.0f;           returnMatrix->_41 = 0.0f; returnMatrix->_42 = 0.0f; returnMatrix->_43 = 0.0f; returnMatrix->_44 = 1.0f;           break;       case 3: // Rotate about the z-axis           returnMatrix->_11 = c; returnMatrix->_12 = s; returnMatrix->_13 = 0.0f; returnMatrix->_14 = 0.0f;           returnMatrix->_21 = -s; returnMatrix->_22 = c; returnMatrix->_23 = 0.0f; returnMatrix->_24 = 0.0f;           returnMatrix->_31 = 0.0f; returnMatrix->_32 = 0.0f; returnMatrix->_33 = 1.0f; returnMatrix->_34 = 0.0f;           returnMatrix->_41 = 0.0f; returnMatrix->_42 = 0.0f; returnMatrix->_43 = 0.0f; returnMatrix->_44 = 1.0f;           break;       default:           // bogus axis index           assert(false);       }   }   //-----------------------------------------------------------------------------   // Name: setupRotate()   // Desc: 繞自定義軸旋轉,類似DirectX中的函數D3DXMatrixRotationAxis   //-----------------------------------------------------------------------------   VOID setupRotate(const D3DXVECTOR3 &axis, D3DXMATRIXA16 *returnMatrix, float theta)   {      //要旋轉的向量軸必須是單位向量,不然物體會變形      //assert(fabs(axis*axis - 1.0f) < .01f);      float s, c;       s = sin(theta),c=cos(theta);       // 計算出一些重復利用的子表達式。       float a = 1.0f - c;       float ax = a * axis.x;       float ay = a * axis.y;       float az = a * axis.z;       returnMatrix->_11 = ax*axis.x + c;       returnMatrix->_12 = ax*axis.y + axis.z*s;       returnMatrix->_13 = ax*axis.z - axis.y*s;       returnMatrix->_14 = 0.0f;       returnMatrix->_21 = ay*axis.x - axis.z*s;       returnMatrix->_22 = ay*axis.y + c;       returnMatrix->_23 = ay*axis.z + axis.x*s;       returnMatrix->_24 = 0.0f;       returnMatrix->_31 = az*axis.x + axis.y*s;       returnMatrix->_32 = az*axis.y - axis.x*s;       returnMatrix->_33 = az*axis.z + c;       returnMatrix->_34 = 0.0f;       returnMatrix->_41 = 0.0f;       returnMatrix->_42 = 0.0f;       returnMatrix->_43 = 0.0f;       returnMatrix->_44 = 1.0f;   }      //-----------------------------------------------------------------------------   // Name: SetupMatrices()   // Desc: Sets up the world, view, and projection transform matrices.   //-----------------------------------------------------------------------------   VOID SetupMatrices()   {       // 旋轉       D3DXMATRIXA16 matWorld;       //自定義旋轉的軸       //D3DXVECTOR3 axis(1.0f/sqrt(3), 1.0f/sqrt(3), 1.0f/sqrt(3));       D3DXVECTOR3 axis(1.0f, 1.0f, 0.0f);       D3DXMatrixIdentity( &matWorld );          /*DirectX 官方API*/       //D3DXMatrixRotationY( &matWorld, timeGetTime()/500.0f );          /*使用自定義旋轉函數1*/       //setupRotate(&matWorld,2,timeGetTime()/500.0f);          /*使用自定義旋轉函數2*/       setupRotate(axis,&matWorld,timeGetTime()/500.0f);       g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );          // 攝像機的位置       D3DXVECTOR3 vEyePt( 0.0f, 3.0f,-5.0f );       D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );       D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );       D3DXMATRIXA16 matView;       D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );       g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );          // 設置視錐體大小       D3DXMATRIXA16 matProj;       D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, 1.0f, 1.0f, 100.0f );       g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );   }               //-----------------------------------------------------------------------------   // Name: SetupLights()   // Desc: Sets up the Lights and materials for the scene.   //-----------------------------------------------------------------------------   VOID SetupLights()   {       // 初始化一個材料       D3DMATERIAL9 mtrl;       ZeroMemory( &mtrl, sizeof(D3DMATERIAL9) );       mtrl.Diffuse = mtrl.Ambient = D3DXCOLOR(1.0f,1.0f,0.0f,1.0f); //材質有漫射和環境光的設置,都為黃色       g_pd3dDevice->SetMaterial( &mtrl );          // 初始化一個白色的方向光       D3DXVECTOR3 vecDir;       D3DLIGHT9 light;       ZeroMemory( &light, sizeof(D3DLIGHT9) );       light.Type       = D3DLIGHT_DIRECTIONAL;//方向光       light.Diffuse = D3DXCOLOR(1.0f,1.0f,1.0f,1.0f);//設置光源的漫射光顏色為白色       light.Direction = D3DXVECTOR3(0.0f,0.0f,1.0f);//光的傳播方向平行z軸       light.Range       = 1000.0f;       g_pd3dDevice->SetLight( 0, &light );       g_pd3dDevice->LightEnable( 0, TRUE );       g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE );          // Finally, turn on some ambient light.       g_pd3dDevice->SetRenderState( D3DRS_AMBIENT, 0x00202020 );   }               //-----------------------------------------------------------------------------   // Name: Render()   // Desc: Draws the scene   //-----------------------------------------------------------------------------   VOID Render()   {       // 背景為藍色       g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,                            D3DCOLOR_XRGB(0,0,255), 1.0f, 0 );          // Begin the scene       if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )       {           // 茶壺的材料顏色也定義在這個函數中           SetupLights();              // Setup the world, view, and projection matrices           SetupMatrices();              // Render the vertex buffer contents           g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof(CUSTOMVERTEX) );           g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );              //創建一個茶壺           Objects = 0;           D3DXMATRIX  Worlds;           D3DXCreateTeapot(g_pd3dDevice, &Objects, 0);           Objects->DrawSubset(0);                   Objects->Release();                    Objects=0;           // End the scene           g_pd3dDevice->EndScene();       }          // Present the backbuffer contents to the display       g_pd3dDevice->Present( NULL, NULL, NULL, NULL );   }               //-----------------------------------------------------------------------------   // Name: MsgProc()   // Desc: The window's message handler   //-----------------------------------------------------------------------------   LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )   {       switch( msg )       {           case WM_DESTROY:               Cleanup();               PostQuitMessage( 0 );               return 0;       }          return DefWindowProc( hWnd, msg, wParam, lParam );   }               //-----------------------------------------------------------------------------   // Name: WinMain()   // Desc: The application's entry point   //-----------------------------------------------------------------------------   INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )   {       // Register the window class       WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,                         GetModuleHandle(NULL), NULL, NULL, NULL, NULL,                         "D3D Tutorial", NULL };       RegisterClassEx( &wc );          // Create the application's window       HWND hWnd = CreateWindow( "D3D Tutorial", "D3D Tutorial 04: Lights",                                 WS_OVERLAPPEDWINDOW, 100, 100, 300, 300,                                 GetDesktopWindow(), NULL, wc.hInstance, NULL );          // Initialize Direct3D       if( SUCCEEDED( InitD3D( hWnd ) ) )       {               // Show the window               ShowWindow( hWnd, SW_SHOWDEFAULT );               UpdateWindow( hWnd );                  // Enter the message loop               MSG msg;               ZeroMemory( &msg, sizeof(msg) );               while( msg.message!=WM_QUIT )               {                   if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )                   {                       TranslateMessage( &msg );                       DispatchMessage( &msg );                   }                   else                       Render();               }       }          UnregisterClass( "D3D Tutorial", wc.hInstance );       return 0;   }    

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved