主题:一个相当好的生成3-D茶壶程序
//teapot.cpp
#include"teapot.h"
void CMyWnd::OnLButtonUp(UINT nFlags,CPoint point)
{
Invalidate(FALSE);
}
void CMyWnd::OnRButtonUp(UINT nFlags,CPoint point)
{
CString mess="计算机图形学实验(ISBN 7-302-03082-0)\n刘丽平(01081373)\n6,6,2004\nVersion 1.0";
MessageBox(mess,NULL,MB_OK|MB_ICONEXCLAMATION);
Invalidate(FALSE);
}
void CMyWnd::OnPaint()
{
CPaintDC* dc;
dc=new CPaintDC(this);
//设置坐标系原点在窗口中间,X向右,Y向上,0.01mm
dc->SetMapMode(MM_LOENGLISH);
RECT rect;
GetClientRect(&rect);
dc->SetViewportOrg((rect.right-rect.left)/2,(rect.bottom-rect.top)/2);
//end
Powell.drawpowell(dc);
delete(dc);
}
//消息映射
BEGIN_MESSAGE_MAP(CMyWnd,CFrameWnd)
ON_WM_LBUTTONUP()
ON_WM_RBUTTONUP()
ON_WM_PAINT()
END_MESSAGE_MAP()
BOOL CMyApp::InitInstance()
{
CMyWnd *pFrame=new CMyWnd;
pFrame->Create(0,_T("计算机图形学实验_Powell茶壶"));
pFrame->ShowWindow(SW_SHOWMAXIMIZED);
this->m_pMainWnd=pFrame;
return TRUE;
}
CMyApp ThisApp;
CPowell::CPowell()
{
propoint.x=0;
propoint.y=3000;
propoint.z=3000;
flatpoint.x=75;
flatpoint.y=600;
flatpoint.z=500;
}
void CPowell::drawpowell(CPaintDC* dc)
{
/* CDC* MemDC;
CBitmap *MemBitmap;
CBitmap *pOldBit;
MemDC->CreateCompatibleDC(dc);
RECT rect;
GetClientRect(&rect);
int nWidth;
int nHeight; //窗口大小
nWidth=rect.right-rect.left;
nHeight=rect.bottom-rect.top;
MemBitmap->CreateCompatibleBitmap(dc,nWidth,nHeight);
pOldBit=MemDC->SelectObject(MemBitmap);
MemDC->FillSolidRect(0,0,nWidth,nHeight,0XFFFFFF); //内存设备设置完毕
*/
//**********************************************************
//壶盖第一条bezier
lpPoints[0].x=0;
lpPoints[0].y=300;
lpPoints[1].x=80;
lpPoints[1].y=300;
lpPoints[2].x=0;
lpPoints[2].y=270;
lpPoints[3].x=20;
lpPoints[3].y=255;
projector1(dc,lpPoints,0XFF0000);
//************************************************************
//壶盖第二条bezier
lpPoints[0].x=20;
lpPoints[0].y=255;
lpPoints[1].x=40;
lpPoints[1].y=240;
lpPoints[2].x=130;
lpPoints[2].y=240;
lpPoints[3].x=130;
lpPoints[3].y=255;
projector1(dc,lpPoints,0XFF0000);
//***********************************************************
//壶体第一条bezier
lpPoints[0].x=140;
lpPoints[0].y=255;
lpPoints[1].x=133.75;
lpPoints[1].y=238.135;
lpPoints[2].x=143.75;
lpPoints[2].y=238.125;
lpPoints[3].x=150;
lpPoints[3].y=225;
projector1(dc,lpPoints,0X00FF00);
//*********************************************************
//壶体第二条bezier
lpPoints[0].x=150;
lpPoints[0].y=225;
lpPoints[1].x=175;
lpPoints[1].y=172.5;
lpPoints[2].x=200;
lpPoints[2].y=120;
lpPoints[3].x=200;
lpPoints[3].y=75;
projector1(dc,lpPoints,0X00FF00);
//*******************************
//壶体第三条bezier
lpPoints[0].x=200;
lpPoints[0].y=75;
lpPoints[1].x=200;
lpPoints[1].y=30;
lpPoints[2].x=150;
lpPoints[2].y=7.5;
lpPoints[3].x=150;
lpPoints[3].y=0;
projector1(dc,lpPoints,0X00FF00);
//*************************************************
//壶嘴第一部分
lpPoint[0][0].x=-170;
lpPoint[0][0].y=127;
lpPoint[0][0].z=0;
lpPoint[0][1].x=-170;
lpPoint[0][1].y=127;
lpPoint[0][1].z=66;
lpPoint[0][2].x=-170;
lpPoint[0][2].y=40;
lpPoint[0][2].z=66;
lpPoint[0][3].x=-170;
lpPoint[0][3].y=40;
lpPoint[0][3].z=0;
lpPoint[1][0].x=-260;
lpPoint[1][0].y=127.5;
lpPoint[1][0].z=0;
lpPoint[1][1].x=-260;
lpPoint[1][1].y=127.5;
lpPoint[1][1].z=66;
lpPoint[1][2].x=-310;
lpPoint[1][2].y=67.5;
lpPoint[1][2].z=66;
lpPoint[1][3].x=-310;
lpPoint[1][3].y=67.5;
lpPoint[1][3].z=0;
lpPoint[2][0].x=-230;
lpPoint[2][0].y=195;
lpPoint[2][0].z=0;
lpPoint[2][1].x=-230;
lpPoint[2][1].y=195;
lpPoint[2][1].z=25;
lpPoint[2][2].x=-240;
lpPoint[2][2].y=187.5;
lpPoint[2][2].z=25;
lpPoint[2][3].x=-240;
lpPoint[2][3].y=187.5;
lpPoint[2][3].z=0;
lpPoint[3][0].x=-270;
lpPoint[3][0].y=225;
lpPoint[3][0].z=0;
lpPoint[3][1].x=-270;
lpPoint[3][1].y=225;
lpPoint[3][1].z=25;
lpPoint[3][2].x=-330;
lpPoint[3][2].y=220;
lpPoint[3][2].z=25;
lpPoint[3][3].x=-330;
lpPoint[3][3].y=220;
lpPoint[3][3].z=0;
projector2(dc,lpPoint,0X0000FF);
//*************************************************
//壶嘴第二部分
lpPoint[0][0].x=-270;
lpPoint[0][0].y=225;
lpPoint[0][0].z=0;
lpPoint[0][1].x=-270;
lpPoint[0][1].y=225;
lpPoint[0][1].z=25;
lpPoint[0][2].x=-330;
lpPoint[0][2].y=220;
lpPoint[0][2].z=25;
lpPoint[0][3].x=-330;
lpPoint[0][3].y=220;
lpPoint[0][3].z=0;
lpPoint[1][0].x=-280;
lpPoint[1][0].y=232.5;
lpPoint[1][0].z=0;
lpPoint[1][1].x=-280;
lpPoint[1][1].y=232.5;
lpPoint[1][1].z=25;
lpPoint[1][2].x=-352.5;
lpPoint[1][2].y=234.375;
lpPoint[1][2].z=25;
lpPoint[1][3].x=-352.5;
lpPoint[1][3].y=234.375;
lpPoint[1][3].z=0;
lpPoint[2][0].x=-290;
lpPoint[2][0].y=232.5;
lpPoint[2][0].z=0;
lpPoint[2][1].x=-290;
lpPoint[2][1].y=232.5;
lpPoint[2][1].z=15;
lpPoint[2][2].x=-340;
lpPoint[2][2].y=236.25;
lpPoint[2][2].z=15;
lpPoint[2][3].x=-340;
lpPoint[2][3].y=236.25;
lpPoint[2][3].z=0;
lpPoint[3][0].x=-280;
lpPoint[3][0].y=225;
lpPoint[3][0].z=0;
lpPoint[3][1].x=-280;
lpPoint[3][1].y=225;
lpPoint[3][1].z=15;
lpPoint[3][2].x=-320;
lpPoint[3][2].y=225;
lpPoint[3][2].z=15;
lpPoint[3][3].x=-320;
lpPoint[3][3].y=225;
lpPoint[3][3].z=0;
projector2(dc,lpPoint,0X0000FF);
//*************************************************
//壶把手第一部分
lpPoint[0][0].x=270;
lpPoint[0][0].y=165;
lpPoint[0][0].z=0;
lpPoint[0][1].x=270;
lpPoint[0][1].y=165;
lpPoint[0][1].z=30;
lpPoint[0][2].x=300;
lpPoint[0][2].y=165;
lpPoint[0][2].z=30;
lpPoint[0][3].x=300;
lpPoint[0][3].y=165;
lpPoint[0][3].z=0;
lpPoint[1][0].x=270;
lpPoint[1][0].y=142.5;
lpPoint[1][0].z=0;
lpPoint[1][1].x=270;
lpPoint[1][1].y=242.5;
lpPoint[1][1].z=30;
lpPoint[1][2].x=300;
lpPoint[1][2].y=120;
lpPoint[1][2].z=30;
lpPoint[1][3].x=300;
lpPoint[1][3].y=120;
lpPoint[1][3].z=0;
lpPoint[2][0].x=250;
lpPoint[2][0].y=97.5;
lpPoint[2][0].z=0;
lpPoint[2][1].x=250;
lpPoint[2][1].y=97.5;
lpPoint[2][1].z=30;
lpPoint[2][2].x=265;
lpPoint[2][2].y=78.75;
lpPoint[2][2].z=30;
lpPoint[2][3].x=265;
lpPoint[2][3].y=78.75;
lpPoint[2][3].z=0;
lpPoint[3][0].x=200;
lpPoint[3][0].y=75;
lpPoint[3][0].z=0;
lpPoint[3][1].x=200;
lpPoint[3][1].y=75;
lpPoint[3][1].z=30;
lpPoint[3][2].x=190;
lpPoint[3][2].y=45;
lpPoint[3][2].z=30;
lpPoint[3][3].x=190;
lpPoint[3][3].y=45;
lpPoint[3][3].z=0;
projector2(dc,lpPoint,0X0FFFF0);
//**************************************************************
//壶把手第二部分
lpPoint[0][0].x=160;
lpPoint[0][0].y=187.5;
lpPoint[0][0].z=0;
lpPoint[0][1].x=160;
lpPoint[0][1].y=187.5;
lpPoint[0][1].z=30;
lpPoint[0][2].x=150;
lpPoint[0][2].y=210;
lpPoint[0][2].z=30;
lpPoint[0][3].x=150;
lpPoint[0][3].y=210;
lpPoint[0][3].z=0;
lpPoint[1][0].x=230;
lpPoint[1][0].y=187.5;
lpPoint[1][0].z=0;
lpPoint[1][1].x=230;
lpPoint[1][1].y=187.5;
lpPoint[1][1].z=30;
lpPoint[1][2].x=250;
lpPoint[1][2].y=210;
lpPoint[1][2].z=30;
lpPoint[1][3].x=250;
lpPoint[1][3].y=210;
lpPoint[1][3].z=0;
lpPoint[2][0].x=270;
lpPoint[2][0].y=187.5;
lpPoint[2][0].z=0;
lpPoint[2][1].x=270;
lpPoint[2][1].y=187.5;
lpPoint[2][1].z=30;
lpPoint[2][2].x=300;
lpPoint[2][2].y=210;
lpPoint[2][2].z=30;
lpPoint[2][3].x=300;
lpPoint[2][3].y=210;
lpPoint[2][3].z=0;
lpPoint[3][0].x=270;
lpPoint[3][0].y=165;
lpPoint[3][0].z=0;
lpPoint[3][1].x=270;
lpPoint[3][1].y=165;
lpPoint[3][1].z=30;
lpPoint[3][2].x=300;
lpPoint[3][2].y=165;
lpPoint[3][2].z=30;
lpPoint[3][3].x=300;
lpPoint[3][3].y=165;
lpPoint[3][3].z=0;
projector2(dc,lpPoint,0X0FFFF0);
//***********************************************
/* dc->BitBlt(0,0,nWidth,nHeight,MemDC,0,0,SRCCOPY); //内存copy
MemBitmap->DeleteObject();
MemDC->DeleteDC();
*/
}
void CPowell::projector1(CDC* dc,POINT lpPoints[], COLORREF color)
{
for(double t=0;t<=1;t+=0.01) //得bezier上的点
{
POINT p1;
p1.x=pow((1-t),3)*lpPoints[0].x+3*t*pow((1-t),2)*lpPoints[1].x+3*pow(t,2)*(1-t)*lpPoints[2].x+pow(t,3)*lpPoints[3].x;
p1.y=pow((1-t),3)*lpPoints[0].y+3*t*pow((1-t),2)*lpPoints[1].y+3*pow(t,2)*(1-t)*lpPoints[2].y+pow(t,3)*lpPoints[3].y;
for(double angle=0;angle<=2*PAI;angle+=0.02)
{
VPOINT p2;
p2.x=p1.x*cos(angle); //绕z旋转
p2.y=p1.x*sin(angle);
p2.z=p1.y;
VPOINT p3;
p3.x=p2.x+flatpoint.x; //平移
p3.y=p2.y+flatpoint.y;
p3.z=p2.z+flatpoint.z;
POINT p;
p.x=(p3.y*propoint.x-p3.x*propoint.y)/(p3.y-propoint.y); //一点投影
p.y=(p3.y*propoint.z-p3.z*propoint.y)/(p3.y-propoint.y);
dc->SetPixel(p,color);
}
}
}
void CPowell::projector2(CDC* dc,VPOINT lpPoint[4][4],COLORREF color)
{
VPOINT p1;
VPOINT p3; //茶壶特点,嘴和把手各自对称
for(double u=0;u<=1;u+=0.01)
for(double w=0;w<=1;w+=0.01)
{
p1.x=p1.y=p1.z=0; //清0
p3.x=p3.y=p3.z=0;
for(int i=0;i<=3;i++)
for(int j=0;j<=3;j++) //4*4矩阵得点
{
p1.x+=c(i,3)*pow(u,i)*pow((1-u),(3-i))*c(j,3)*pow(w,j)*pow((1-w),(3-j))*lpPoint[i][j].x;
p1.y+=c(i,3)*pow(u,i)*pow((1-u),(3-i))*c(j,3)*pow(w,j)*pow((1-w),(3-j))*lpPoint[i][j].y;
p1.z+=c(i,3)*pow(u,i)*pow((1-u),(3-i))*c(j,3)*pow(w,j)*pow((1-w),(3-j))*lpPoint[i][j].z;
}
VPOINT p2;
p2.x=p1.x+flatpoint.x; //平移
p2.y=-p1.y+flatpoint.y; //坐标系变化,左手到右手系
p2.z=p1.z+flatpoint.z;
POINT p;
p.x=(p2.y*propoint.x-p2.x*propoint.y)/(p2.y-propoint.y); //一点投影
p.y=(p2.y*propoint.z-p2.z*propoint.y)/(p2.y-propoint.y);
dc->SetPixel(p,color);
p3.x=p1.x;
p3.y=p1.y;
p3.z=-p1.z; //平面对称得另一半点
p2.x=p3.x+flatpoint.x; //平移
p2.y=-p3.y+flatpoint.y;
p2.z=p3.z+flatpoint.z;
p.x=(p2.y*propoint.x-p2.x*propoint.y)/(p2.y-propoint.y); //一点投影
p.y=(p2.y*propoint.z-p2.z*propoint.y)/(p2.y-propoint.y);
dc->SetPixel(p,color); //*/
}
}
long CPowell::c(int n,int m)
{
long p1=1;
long p2=1;
long p3=1;
long result;
if (n==0)
result=1;
else
{
for (int i=1;i<=m;i++)
p1*=i;
for (int j=1;j<=n;j++)
p2*=j;
for (int k=1;k<=m-n;k++)
p3*=k;
result=p1/(p2*p3);
}
return(result);
}
//teapot.h
#include<afxwin.h>
#include <math.h>
struct VPOINT
{
long x;
long y;
long z;
};
#define PAI 3.14159265
//Powell类
class CPowell
{
private:
POINT lpPoints[4]; //bezier控制点
VPOINT lpPoint[4][4]; //bezier曲面控制点
VPOINT propoint; //透视灭点(0,3000,3000)
VPOINT flatpoint; //平移向量(75,600,500)
protected:
void projector1(CDC* dc,POINT lpPoints[],COLORREF color); //旋转bezier三维图
void projector2(CDC* dc,VPOINT lpPoint[4][4],COLORREF color); //双三次bezier三维图
long c(int n, int m); //算m个i的组合
public:
CPowell();
void drawpowell(CPaintDC* dc);
};
//窗口类
class CMyWnd:public CFrameWnd
{
private:
CPowell Powell;
protected:
afx_msg void OnLButtonUp(UINT nFlags,CPoint point);
afx_msg void OnRButtonUp(UINT nFlags,CPoint point);
afx_msg void OnPaint();
DECLARE_MESSAGE_MAP()
};
//应用程序类
class CMyApp: public CWinApp
{
public:
BOOL InitInstance();
};
#include"teapot.h"
void CMyWnd::OnLButtonUp(UINT nFlags,CPoint point)
{
Invalidate(FALSE);
}
void CMyWnd::OnRButtonUp(UINT nFlags,CPoint point)
{
CString mess="计算机图形学实验(ISBN 7-302-03082-0)\n刘丽平(01081373)\n6,6,2004\nVersion 1.0";
MessageBox(mess,NULL,MB_OK|MB_ICONEXCLAMATION);
Invalidate(FALSE);
}
void CMyWnd::OnPaint()
{
CPaintDC* dc;
dc=new CPaintDC(this);
//设置坐标系原点在窗口中间,X向右,Y向上,0.01mm
dc->SetMapMode(MM_LOENGLISH);
RECT rect;
GetClientRect(&rect);
dc->SetViewportOrg((rect.right-rect.left)/2,(rect.bottom-rect.top)/2);
//end
Powell.drawpowell(dc);
delete(dc);
}
//消息映射
BEGIN_MESSAGE_MAP(CMyWnd,CFrameWnd)
ON_WM_LBUTTONUP()
ON_WM_RBUTTONUP()
ON_WM_PAINT()
END_MESSAGE_MAP()
BOOL CMyApp::InitInstance()
{
CMyWnd *pFrame=new CMyWnd;
pFrame->Create(0,_T("计算机图形学实验_Powell茶壶"));
pFrame->ShowWindow(SW_SHOWMAXIMIZED);
this->m_pMainWnd=pFrame;
return TRUE;
}
CMyApp ThisApp;
CPowell::CPowell()
{
propoint.x=0;
propoint.y=3000;
propoint.z=3000;
flatpoint.x=75;
flatpoint.y=600;
flatpoint.z=500;
}
void CPowell::drawpowell(CPaintDC* dc)
{
/* CDC* MemDC;
CBitmap *MemBitmap;
CBitmap *pOldBit;
MemDC->CreateCompatibleDC(dc);
RECT rect;
GetClientRect(&rect);
int nWidth;
int nHeight; //窗口大小
nWidth=rect.right-rect.left;
nHeight=rect.bottom-rect.top;
MemBitmap->CreateCompatibleBitmap(dc,nWidth,nHeight);
pOldBit=MemDC->SelectObject(MemBitmap);
MemDC->FillSolidRect(0,0,nWidth,nHeight,0XFFFFFF); //内存设备设置完毕
*/
//**********************************************************
//壶盖第一条bezier
lpPoints[0].x=0;
lpPoints[0].y=300;
lpPoints[1].x=80;
lpPoints[1].y=300;
lpPoints[2].x=0;
lpPoints[2].y=270;
lpPoints[3].x=20;
lpPoints[3].y=255;
projector1(dc,lpPoints,0XFF0000);
//************************************************************
//壶盖第二条bezier
lpPoints[0].x=20;
lpPoints[0].y=255;
lpPoints[1].x=40;
lpPoints[1].y=240;
lpPoints[2].x=130;
lpPoints[2].y=240;
lpPoints[3].x=130;
lpPoints[3].y=255;
projector1(dc,lpPoints,0XFF0000);
//***********************************************************
//壶体第一条bezier
lpPoints[0].x=140;
lpPoints[0].y=255;
lpPoints[1].x=133.75;
lpPoints[1].y=238.135;
lpPoints[2].x=143.75;
lpPoints[2].y=238.125;
lpPoints[3].x=150;
lpPoints[3].y=225;
projector1(dc,lpPoints,0X00FF00);
//*********************************************************
//壶体第二条bezier
lpPoints[0].x=150;
lpPoints[0].y=225;
lpPoints[1].x=175;
lpPoints[1].y=172.5;
lpPoints[2].x=200;
lpPoints[2].y=120;
lpPoints[3].x=200;
lpPoints[3].y=75;
projector1(dc,lpPoints,0X00FF00);
//*******************************
//壶体第三条bezier
lpPoints[0].x=200;
lpPoints[0].y=75;
lpPoints[1].x=200;
lpPoints[1].y=30;
lpPoints[2].x=150;
lpPoints[2].y=7.5;
lpPoints[3].x=150;
lpPoints[3].y=0;
projector1(dc,lpPoints,0X00FF00);
//*************************************************
//壶嘴第一部分
lpPoint[0][0].x=-170;
lpPoint[0][0].y=127;
lpPoint[0][0].z=0;
lpPoint[0][1].x=-170;
lpPoint[0][1].y=127;
lpPoint[0][1].z=66;
lpPoint[0][2].x=-170;
lpPoint[0][2].y=40;
lpPoint[0][2].z=66;
lpPoint[0][3].x=-170;
lpPoint[0][3].y=40;
lpPoint[0][3].z=0;
lpPoint[1][0].x=-260;
lpPoint[1][0].y=127.5;
lpPoint[1][0].z=0;
lpPoint[1][1].x=-260;
lpPoint[1][1].y=127.5;
lpPoint[1][1].z=66;
lpPoint[1][2].x=-310;
lpPoint[1][2].y=67.5;
lpPoint[1][2].z=66;
lpPoint[1][3].x=-310;
lpPoint[1][3].y=67.5;
lpPoint[1][3].z=0;
lpPoint[2][0].x=-230;
lpPoint[2][0].y=195;
lpPoint[2][0].z=0;
lpPoint[2][1].x=-230;
lpPoint[2][1].y=195;
lpPoint[2][1].z=25;
lpPoint[2][2].x=-240;
lpPoint[2][2].y=187.5;
lpPoint[2][2].z=25;
lpPoint[2][3].x=-240;
lpPoint[2][3].y=187.5;
lpPoint[2][3].z=0;
lpPoint[3][0].x=-270;
lpPoint[3][0].y=225;
lpPoint[3][0].z=0;
lpPoint[3][1].x=-270;
lpPoint[3][1].y=225;
lpPoint[3][1].z=25;
lpPoint[3][2].x=-330;
lpPoint[3][2].y=220;
lpPoint[3][2].z=25;
lpPoint[3][3].x=-330;
lpPoint[3][3].y=220;
lpPoint[3][3].z=0;
projector2(dc,lpPoint,0X0000FF);
//*************************************************
//壶嘴第二部分
lpPoint[0][0].x=-270;
lpPoint[0][0].y=225;
lpPoint[0][0].z=0;
lpPoint[0][1].x=-270;
lpPoint[0][1].y=225;
lpPoint[0][1].z=25;
lpPoint[0][2].x=-330;
lpPoint[0][2].y=220;
lpPoint[0][2].z=25;
lpPoint[0][3].x=-330;
lpPoint[0][3].y=220;
lpPoint[0][3].z=0;
lpPoint[1][0].x=-280;
lpPoint[1][0].y=232.5;
lpPoint[1][0].z=0;
lpPoint[1][1].x=-280;
lpPoint[1][1].y=232.5;
lpPoint[1][1].z=25;
lpPoint[1][2].x=-352.5;
lpPoint[1][2].y=234.375;
lpPoint[1][2].z=25;
lpPoint[1][3].x=-352.5;
lpPoint[1][3].y=234.375;
lpPoint[1][3].z=0;
lpPoint[2][0].x=-290;
lpPoint[2][0].y=232.5;
lpPoint[2][0].z=0;
lpPoint[2][1].x=-290;
lpPoint[2][1].y=232.5;
lpPoint[2][1].z=15;
lpPoint[2][2].x=-340;
lpPoint[2][2].y=236.25;
lpPoint[2][2].z=15;
lpPoint[2][3].x=-340;
lpPoint[2][3].y=236.25;
lpPoint[2][3].z=0;
lpPoint[3][0].x=-280;
lpPoint[3][0].y=225;
lpPoint[3][0].z=0;
lpPoint[3][1].x=-280;
lpPoint[3][1].y=225;
lpPoint[3][1].z=15;
lpPoint[3][2].x=-320;
lpPoint[3][2].y=225;
lpPoint[3][2].z=15;
lpPoint[3][3].x=-320;
lpPoint[3][3].y=225;
lpPoint[3][3].z=0;
projector2(dc,lpPoint,0X0000FF);
//*************************************************
//壶把手第一部分
lpPoint[0][0].x=270;
lpPoint[0][0].y=165;
lpPoint[0][0].z=0;
lpPoint[0][1].x=270;
lpPoint[0][1].y=165;
lpPoint[0][1].z=30;
lpPoint[0][2].x=300;
lpPoint[0][2].y=165;
lpPoint[0][2].z=30;
lpPoint[0][3].x=300;
lpPoint[0][3].y=165;
lpPoint[0][3].z=0;
lpPoint[1][0].x=270;
lpPoint[1][0].y=142.5;
lpPoint[1][0].z=0;
lpPoint[1][1].x=270;
lpPoint[1][1].y=242.5;
lpPoint[1][1].z=30;
lpPoint[1][2].x=300;
lpPoint[1][2].y=120;
lpPoint[1][2].z=30;
lpPoint[1][3].x=300;
lpPoint[1][3].y=120;
lpPoint[1][3].z=0;
lpPoint[2][0].x=250;
lpPoint[2][0].y=97.5;
lpPoint[2][0].z=0;
lpPoint[2][1].x=250;
lpPoint[2][1].y=97.5;
lpPoint[2][1].z=30;
lpPoint[2][2].x=265;
lpPoint[2][2].y=78.75;
lpPoint[2][2].z=30;
lpPoint[2][3].x=265;
lpPoint[2][3].y=78.75;
lpPoint[2][3].z=0;
lpPoint[3][0].x=200;
lpPoint[3][0].y=75;
lpPoint[3][0].z=0;
lpPoint[3][1].x=200;
lpPoint[3][1].y=75;
lpPoint[3][1].z=30;
lpPoint[3][2].x=190;
lpPoint[3][2].y=45;
lpPoint[3][2].z=30;
lpPoint[3][3].x=190;
lpPoint[3][3].y=45;
lpPoint[3][3].z=0;
projector2(dc,lpPoint,0X0FFFF0);
//**************************************************************
//壶把手第二部分
lpPoint[0][0].x=160;
lpPoint[0][0].y=187.5;
lpPoint[0][0].z=0;
lpPoint[0][1].x=160;
lpPoint[0][1].y=187.5;
lpPoint[0][1].z=30;
lpPoint[0][2].x=150;
lpPoint[0][2].y=210;
lpPoint[0][2].z=30;
lpPoint[0][3].x=150;
lpPoint[0][3].y=210;
lpPoint[0][3].z=0;
lpPoint[1][0].x=230;
lpPoint[1][0].y=187.5;
lpPoint[1][0].z=0;
lpPoint[1][1].x=230;
lpPoint[1][1].y=187.5;
lpPoint[1][1].z=30;
lpPoint[1][2].x=250;
lpPoint[1][2].y=210;
lpPoint[1][2].z=30;
lpPoint[1][3].x=250;
lpPoint[1][3].y=210;
lpPoint[1][3].z=0;
lpPoint[2][0].x=270;
lpPoint[2][0].y=187.5;
lpPoint[2][0].z=0;
lpPoint[2][1].x=270;
lpPoint[2][1].y=187.5;
lpPoint[2][1].z=30;
lpPoint[2][2].x=300;
lpPoint[2][2].y=210;
lpPoint[2][2].z=30;
lpPoint[2][3].x=300;
lpPoint[2][3].y=210;
lpPoint[2][3].z=0;
lpPoint[3][0].x=270;
lpPoint[3][0].y=165;
lpPoint[3][0].z=0;
lpPoint[3][1].x=270;
lpPoint[3][1].y=165;
lpPoint[3][1].z=30;
lpPoint[3][2].x=300;
lpPoint[3][2].y=165;
lpPoint[3][2].z=30;
lpPoint[3][3].x=300;
lpPoint[3][3].y=165;
lpPoint[3][3].z=0;
projector2(dc,lpPoint,0X0FFFF0);
//***********************************************
/* dc->BitBlt(0,0,nWidth,nHeight,MemDC,0,0,SRCCOPY); //内存copy
MemBitmap->DeleteObject();
MemDC->DeleteDC();
*/
}
void CPowell::projector1(CDC* dc,POINT lpPoints[], COLORREF color)
{
for(double t=0;t<=1;t+=0.01) //得bezier上的点
{
POINT p1;
p1.x=pow((1-t),3)*lpPoints[0].x+3*t*pow((1-t),2)*lpPoints[1].x+3*pow(t,2)*(1-t)*lpPoints[2].x+pow(t,3)*lpPoints[3].x;
p1.y=pow((1-t),3)*lpPoints[0].y+3*t*pow((1-t),2)*lpPoints[1].y+3*pow(t,2)*(1-t)*lpPoints[2].y+pow(t,3)*lpPoints[3].y;
for(double angle=0;angle<=2*PAI;angle+=0.02)
{
VPOINT p2;
p2.x=p1.x*cos(angle); //绕z旋转
p2.y=p1.x*sin(angle);
p2.z=p1.y;
VPOINT p3;
p3.x=p2.x+flatpoint.x; //平移
p3.y=p2.y+flatpoint.y;
p3.z=p2.z+flatpoint.z;
POINT p;
p.x=(p3.y*propoint.x-p3.x*propoint.y)/(p3.y-propoint.y); //一点投影
p.y=(p3.y*propoint.z-p3.z*propoint.y)/(p3.y-propoint.y);
dc->SetPixel(p,color);
}
}
}
void CPowell::projector2(CDC* dc,VPOINT lpPoint[4][4],COLORREF color)
{
VPOINT p1;
VPOINT p3; //茶壶特点,嘴和把手各自对称
for(double u=0;u<=1;u+=0.01)
for(double w=0;w<=1;w+=0.01)
{
p1.x=p1.y=p1.z=0; //清0
p3.x=p3.y=p3.z=0;
for(int i=0;i<=3;i++)
for(int j=0;j<=3;j++) //4*4矩阵得点
{
p1.x+=c(i,3)*pow(u,i)*pow((1-u),(3-i))*c(j,3)*pow(w,j)*pow((1-w),(3-j))*lpPoint[i][j].x;
p1.y+=c(i,3)*pow(u,i)*pow((1-u),(3-i))*c(j,3)*pow(w,j)*pow((1-w),(3-j))*lpPoint[i][j].y;
p1.z+=c(i,3)*pow(u,i)*pow((1-u),(3-i))*c(j,3)*pow(w,j)*pow((1-w),(3-j))*lpPoint[i][j].z;
}
VPOINT p2;
p2.x=p1.x+flatpoint.x; //平移
p2.y=-p1.y+flatpoint.y; //坐标系变化,左手到右手系
p2.z=p1.z+flatpoint.z;
POINT p;
p.x=(p2.y*propoint.x-p2.x*propoint.y)/(p2.y-propoint.y); //一点投影
p.y=(p2.y*propoint.z-p2.z*propoint.y)/(p2.y-propoint.y);
dc->SetPixel(p,color);
p3.x=p1.x;
p3.y=p1.y;
p3.z=-p1.z; //平面对称得另一半点
p2.x=p3.x+flatpoint.x; //平移
p2.y=-p3.y+flatpoint.y;
p2.z=p3.z+flatpoint.z;
p.x=(p2.y*propoint.x-p2.x*propoint.y)/(p2.y-propoint.y); //一点投影
p.y=(p2.y*propoint.z-p2.z*propoint.y)/(p2.y-propoint.y);
dc->SetPixel(p,color); //*/
}
}
long CPowell::c(int n,int m)
{
long p1=1;
long p2=1;
long p3=1;
long result;
if (n==0)
result=1;
else
{
for (int i=1;i<=m;i++)
p1*=i;
for (int j=1;j<=n;j++)
p2*=j;
for (int k=1;k<=m-n;k++)
p3*=k;
result=p1/(p2*p3);
}
return(result);
}
//teapot.h
#include<afxwin.h>
#include <math.h>
struct VPOINT
{
long x;
long y;
long z;
};
#define PAI 3.14159265
//Powell类
class CPowell
{
private:
POINT lpPoints[4]; //bezier控制点
VPOINT lpPoint[4][4]; //bezier曲面控制点
VPOINT propoint; //透视灭点(0,3000,3000)
VPOINT flatpoint; //平移向量(75,600,500)
protected:
void projector1(CDC* dc,POINT lpPoints[],COLORREF color); //旋转bezier三维图
void projector2(CDC* dc,VPOINT lpPoint[4][4],COLORREF color); //双三次bezier三维图
long c(int n, int m); //算m个i的组合
public:
CPowell();
void drawpowell(CPaintDC* dc);
};
//窗口类
class CMyWnd:public CFrameWnd
{
private:
CPowell Powell;
protected:
afx_msg void OnLButtonUp(UINT nFlags,CPoint point);
afx_msg void OnRButtonUp(UINT nFlags,CPoint point);
afx_msg void OnPaint();
DECLARE_MESSAGE_MAP()
};
//应用程序类
class CMyApp: public CWinApp
{
public:
BOOL InitInstance();
};