📄 testquadricsurface.cpp
字号:
rkOct.m_apkTriangle[2].m_apkVertex[0] = &rkOct.m_apkVertex[0];
rkOct.m_apkTriangle[2].m_apkVertex[1] = &rkOct.m_apkVertex[3];
rkOct.m_apkTriangle[2].m_apkVertex[2] = &rkOct.m_apkVertex[4];
rkOct.m_apkTriangle[2].m_apkEdge[0] = &rkOct.m_apkEdge[2];
rkOct.m_apkTriangle[2].m_apkEdge[1] = &rkOct.m_apkEdge[6];
rkOct.m_apkTriangle[2].m_apkEdge[2] = &rkOct.m_apkEdge[3];
rkOct.m_apkTriangle[2].m_apkAdjacent[0] = &rkOct.m_apkTriangle[1];
rkOct.m_apkTriangle[2].m_apkAdjacent[1] = &rkOct.m_apkTriangle[6];
rkOct.m_apkTriangle[2].m_apkAdjacent[2] = &rkOct.m_apkTriangle[3];
rkOct.m_apkTriangle[3].m_apkVertex[0] = &rkOct.m_apkVertex[0];
rkOct.m_apkTriangle[3].m_apkVertex[1] = &rkOct.m_apkVertex[4];
rkOct.m_apkTriangle[3].m_apkVertex[2] = &rkOct.m_apkVertex[1];
rkOct.m_apkTriangle[3].m_apkEdge[0] = &rkOct.m_apkEdge[3];
rkOct.m_apkTriangle[3].m_apkEdge[1] = &rkOct.m_apkEdge[7];
rkOct.m_apkTriangle[3].m_apkEdge[2] = &rkOct.m_apkEdge[0];
rkOct.m_apkTriangle[3].m_apkAdjacent[0] = &rkOct.m_apkTriangle[2];
rkOct.m_apkTriangle[3].m_apkAdjacent[1] = &rkOct.m_apkTriangle[7];
rkOct.m_apkTriangle[3].m_apkAdjacent[2] = &rkOct.m_apkTriangle[0];
rkOct.m_apkTriangle[4].m_apkVertex[0] = &rkOct.m_apkVertex[5];
rkOct.m_apkTriangle[4].m_apkVertex[1] = &rkOct.m_apkVertex[2];
rkOct.m_apkTriangle[4].m_apkVertex[2] = &rkOct.m_apkVertex[1];
rkOct.m_apkTriangle[4].m_apkEdge[0] = &rkOct.m_apkEdge[9];
rkOct.m_apkTriangle[4].m_apkEdge[1] = &rkOct.m_apkEdge[4];
rkOct.m_apkTriangle[4].m_apkEdge[2] = &rkOct.m_apkEdge[8];
rkOct.m_apkTriangle[4].m_apkAdjacent[0] = &rkOct.m_apkTriangle[5];
rkOct.m_apkTriangle[4].m_apkAdjacent[1] = &rkOct.m_apkTriangle[0];
rkOct.m_apkTriangle[4].m_apkAdjacent[2] = &rkOct.m_apkTriangle[7];
rkOct.m_apkTriangle[5].m_apkVertex[0] = &rkOct.m_apkVertex[5];
rkOct.m_apkTriangle[5].m_apkVertex[1] = &rkOct.m_apkVertex[3];
rkOct.m_apkTriangle[5].m_apkVertex[2] = &rkOct.m_apkVertex[2];
rkOct.m_apkTriangle[5].m_apkEdge[0] = &rkOct.m_apkEdge[10];
rkOct.m_apkTriangle[5].m_apkEdge[1] = &rkOct.m_apkEdge[5];
rkOct.m_apkTriangle[5].m_apkEdge[2] = &rkOct.m_apkEdge[9];
rkOct.m_apkTriangle[5].m_apkAdjacent[0] = &rkOct.m_apkTriangle[6];
rkOct.m_apkTriangle[5].m_apkAdjacent[1] = &rkOct.m_apkTriangle[1];
rkOct.m_apkTriangle[5].m_apkAdjacent[2] = &rkOct.m_apkTriangle[4];
rkOct.m_apkTriangle[6].m_apkVertex[0] = &rkOct.m_apkVertex[5];
rkOct.m_apkTriangle[6].m_apkVertex[1] = &rkOct.m_apkVertex[4];
rkOct.m_apkTriangle[6].m_apkVertex[2] = &rkOct.m_apkVertex[3];
rkOct.m_apkTriangle[6].m_apkEdge[0] = &rkOct.m_apkEdge[11];
rkOct.m_apkTriangle[6].m_apkEdge[1] = &rkOct.m_apkEdge[6];
rkOct.m_apkTriangle[6].m_apkEdge[2] = &rkOct.m_apkEdge[10];
rkOct.m_apkTriangle[6].m_apkAdjacent[0] = &rkOct.m_apkTriangle[7];
rkOct.m_apkTriangle[6].m_apkAdjacent[1] = &rkOct.m_apkTriangle[2];
rkOct.m_apkTriangle[6].m_apkAdjacent[2] = &rkOct.m_apkTriangle[5];
rkOct.m_apkTriangle[7].m_apkVertex[0] = &rkOct.m_apkVertex[5];
rkOct.m_apkTriangle[7].m_apkVertex[1] = &rkOct.m_apkVertex[1];
rkOct.m_apkTriangle[7].m_apkVertex[2] = &rkOct.m_apkVertex[4];
rkOct.m_apkTriangle[7].m_apkEdge[0] = &rkOct.m_apkEdge[8];
rkOct.m_apkTriangle[7].m_apkEdge[1] = &rkOct.m_apkEdge[7];
rkOct.m_apkTriangle[7].m_apkEdge[2] = &rkOct.m_apkEdge[11];
rkOct.m_apkTriangle[7].m_apkAdjacent[0] = &rkOct.m_apkTriangle[4];
rkOct.m_apkTriangle[7].m_apkAdjacent[1] = &rkOct.m_apkTriangle[3];
rkOct.m_apkTriangle[7].m_apkAdjacent[2] = &rkOct.m_apkTriangle[6];
// For testing purposes, but not necessary for the algorithm. This
// allows the display program to show the subdivision structure.
for (int i = 0; i < 12; i++)
rkOct.m_apkEdge[i].m_uiStep = 0;
}
//---------------------------------------------------------------------------
#ifdef PERSPECTIVE
void ProjectPoint (MgcVector3& rkPoint, MgcVector3& rkEye, MgcMatrix3& rkRot,
int& riX, int& riY)
{
// perspective projection
// projection plane is Dot(eye,(x,y,z)) = -4
float fT = 8.0/(4.0-rkEye.Dot(rkPoint));
MgcVector3 kProj = (1.0-fT)*rkEye + fT*rkPoint;
MgcVector3 kDir = kProj + rkEye;
MgcVector3 kProd = kDir*rkRot;
riX = WSIZE/4+int((WSIZE/8)*(kProd.x+2.0));
riY = WSIZE/4+int((WSIZE/8)*(kProd.y+2.0));
}
#else
void ProjectPoint (MgcVector3& rkPoint, MgcVector3& rkEye, MgcMatrix3& rkRot,
int& riX, int& riY)
{
// parallel projection
// projection plane is Dot(eye,(x,y,z)) = -4
MgcVector3 kDir = rkPoint + rkEye;
MgcVector3 kProd = kDir*rkRot;
riX = int((WSIZE/4)*(kProd.x+2.0));
riY = int((WSIZE/4)*(kProd.y+2.0));
}
#endif
//---------------------------------------------------------------------------
void DrawPolyhedron (HDC hDC, MgcVector3& rkEye, MgcMatrix3& rkRot,
MgcQuadricSurface::ConvexPolyhedron& rkPoly)
{
static COLORREF color[4] =
{
RGB(0,0,0),
RGB(255,0,0),
RGB(0,255,0),
RGB(0,0,255)
};
for (int i = 0; i < rkPoly.m_iNumEdges; i++)
{
unsigned int uiIndex = rkPoly.m_apkEdge[i].m_uiStep % 4;
HPEN hPen = CreatePen(PS_SOLID,2,color[uiIndex]);
HGDIOBJ hOldPen = SelectObject(hDC,hPen);
MgcVector3* pP0 = rkPoly.m_apkEdge[i].m_apkVertex[0]->m_pkPoint;
int iX0, iY0;
ProjectPoint(*pP0,rkEye,rkRot,iX0,iY0);
MgcVector3* pP1 = rkPoly.m_apkEdge[i].m_apkVertex[1]->m_pkPoint;
int iX1, iY1;
ProjectPoint(*pP1,rkEye,rkRot,iX1,iY1);
MoveToEx(hDC,iX0,iY0,NULL);
LineTo(hDC,iX1,iY1);
SelectObject(hDC,hOldPen);
DeleteObject(hPen);
}
}
//---------------------------------------------------------------------------
long FAR PASCAL
WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static MgcVector3 s_kEye;
static MgcQuadricSurface::ConvexPolyhedron s_kPoly;
static unsigned int s_uiSteps = 0;
static MgcMatrix3 s_kRot;
MgcMatrix3 kIncr;
switch ( message )
{
case WM_CREATE:
{
CreatePoly(s_kPoly);
MgcQuadricSurface::TessellateSphere(s_uiSteps,s_kPoly);
// initial camera orientation and eye point
s_kRot.FromAxisAngle(MgcVector3::UNIT_Z,0.0);
s_kEye = 2.0*s_kRot.GetColumn(2);
return 0;
}
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hDC = BeginPaint(hWnd,&ps);
DrawPolyhedron(hDC,s_kEye,s_kRot,s_kPoly);
EndPaint(hWnd,&ps);
return 0;
}
case WM_KEYDOWN:
{
switch ( wParam )
{
case VK_LEFT:
{
// rotate camera about its 'up' vector
kIncr.FromAxisAngle(s_kRot.GetColumn(1),0.1);
s_kRot = kIncr*s_kRot;
s_kEye = 2.0*s_kRot.GetColumn(2);
InvalidateRect(hWnd,NULL,TRUE);
break;
}
case VK_RIGHT:
{
// rotate camera about its 'up' vector
kIncr.FromAxisAngle(s_kRot.GetColumn(1),-0.1);
s_kRot = kIncr*s_kRot;
s_kEye = 2.0*s_kRot.GetColumn(2);
InvalidateRect(hWnd,NULL,TRUE);
break;
}
case VK_UP:
{
// rotate camera about its 'right' vector
kIncr.FromAxisAngle(s_kRot.GetColumn(0),-0.1);
s_kRot = kIncr*s_kRot;
s_kEye = 2.0*s_kRot.GetColumn(2);
InvalidateRect(hWnd,NULL,TRUE);
break;
}
case VK_DOWN:
{
// rotate camera about its 'right' vector
kIncr.FromAxisAngle(s_kRot.GetColumn(0),0.1);
s_kRot = kIncr*s_kRot;
s_kEye = 2.0*s_kRot.GetColumn(2);
InvalidateRect(hWnd,NULL,TRUE);
break;
}
}
return 0;
}
case WM_CHAR:
{
switch ( wParam )
{
case '+':
case '=':
{
s_uiSteps++;
MgcQuadricSurface::DeletePolyhedron(s_kPoly);
CreatePoly(s_kPoly);
MgcQuadricSurface::TessellateSphere(s_uiSteps,s_kPoly);
InvalidateRect(hWnd,NULL,TRUE);
break;
}
case '-':
case '_':
{
if ( s_uiSteps >= 1 )
{
s_uiSteps--;
MgcQuadricSurface::DeletePolyhedron(s_kPoly);
CreatePoly(s_kPoly);
MgcQuadricSurface::TessellateSphere(s_uiSteps,s_kPoly);
InvalidateRect(hWnd,NULL,TRUE);
}
break;
}
case 'q':
case 'Q':
case VK_ESCAPE:
{
PostMessage(hWnd,WM_DESTROY,0,0);
break;
}
}
return 0;
}
case WM_DESTROY:
{
MgcQuadricSurface::DeletePolyhedron(s_kPoly);
PostQuitMessage(0);
return 0;
}
}
return DefWindowProc(hWnd,message,wParam,lParam);
}
//---------------------------------------------------------------------------
int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpszCmdLine, int nCmdShow)
{
static char szAppName[] = "Tessellate Test";
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL,IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL,IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = szAppName;
RegisterClass(&wc);
RECT rect = { 0, 0, WSIZE-1, WSIZE-1 };
AdjustWindowRect(&rect,WS_OVERLAPPEDWINDOW,FALSE);
HWND hWnd = CreateWindow (
szAppName,
szAppName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
rect.right-rect.left+1,
rect.bottom-rect.top+1,
NULL,
NULL,
hInstance,
NULL
);
ShowWindow(hWnd,nCmdShow);
UpdateWindow(hWnd);
MSG msg;
while ( TRUE )
{
if ( PeekMessage(&msg,NULL,0,0,PM_REMOVE) )
{
if ( msg.message == WM_QUIT )
break;
HACCEL hAccel = NULL;
if ( !TranslateAccelerator(hWnd,hAccel,&msg) )
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
return msg.wParam;
}
//---------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -