回 帖 发 新 帖 刷新版面

主题:一个相当好的生成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();
};



回复列表 (共2个回复)

沙发

哪找的?
还是自己编的?
能教我吗?
我是菜鸟![em2]

板凳

这不是VC++吗,应该发到VC++论坛上去啊?这里讨论的都是标准c++

我来回复

您尚未登录,请登录后再回复。点此登录或注册