fuliangliang的Blog

合抱之木,生于毫末;九层之台,起于累土;千里之行,始于足下。

用户操作
[即时聊天] [发私信] [加为好友]
fuliangID:fuliangliang
65518次访问,排名1597好友1人,关注者3
fuliangliang的文章
原创 100 篇
翻译 0 篇
转载 25 篇
评论 29 篇
fuliang的公告

我的联系方式:20542606

Email:fuliangliang@gmail.com


最近评论
topgunqq:条理清楚,简单易学.比网上其他例子要好一些.至少按照楼主写的过程,我这个初学者实验成功了!
marshluca:恭喜~~
请问有没rails 做的项目,比方blog?
marshluca@gmail.com
marshluca:恭喜~~
请问有没rails 做的项目,比方blog?
marshluca@gmail.com
chucai:写的非常的好,仔细的拜读了。思路很清晰。考虑的问题也比较全面。
tbsc3:我也遇到了这个问题,如果配1 M就有用,大于2M就还是默认的 不知道你有没有解决呀,教教我
文章分类
收藏
    相册
    净月潭一日游
    页面图片
    日历
    文章收藏
    我的JavaEye博客
    存档
    软件项目交易
    订阅我的博客
    XML聚合  FeedSky
    订阅到鲜果
    订阅到Google
    订阅到抓虾
    订阅到BlogLines
    订阅到Yahoo
    订阅到GouGou
    订阅到飞鸽
    订阅到Rojo
    订阅到newsgator
    订阅到netvibes

    原创 MFC下实现图形学之Hermite、Bezier曲线的绘制收藏

    新一篇: 今天用Windows API写的扫雷程序 | 旧一篇: MFC下实现图形学之立方体平移、比例、旋转、投影变换算法

    //*******************************************************
    //捕捉鼠标左键按下消息,获得两个起始控制点的坐标
    //*******************************************************
    void CDrawCurvesView::OnLButtonDown(UINT nFlags, CPoint point)
    {
     // TODO: Add your message handler code here and/or call default
     oldPoint = point;
     newPoint = point;
     CurveCtrlPoints[count++] = point;
     SetCapture();
     isLButtonDown = true;
     CRect rect;
        GetClientRect(&rect);
     ClientToScreen(&rect);  //用用户区坐标重新计算屏幕坐标
        ClipCursor(&rect);      //限制光标在用户区内
                                //默认处理,调用基类消息处理函数
        CView::OnLButtonDown(nFlags, point);
    }
    //******************************************
    //按下键盘清除客户区的内容,为下次绘制作准备
    //******************************************
    void CDrawCurvesView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
    {
     // TODO: Add your message handler code here and/or call default
     count = 0;
     Invalidate();
     CView::OnKeyDown(nChar, nRepCnt, nFlags);
    }
    //******************
    //矩阵乘法
    //******************
    void CDrawCurvesView::MultiMatrix(int a[4][4],double b[4][2])
    {
     int i,j,k;
     for(i=0;i<4;i++)
          for(j=0;j<2;j++)
         result[i][j] = 0;

     for(i=0;i<2;i++)
       for(j=0;j<4;j++)
        for(k=0;k<4;k++)
                 result[j][i] += a[j][k]*b[k][i];
    }
    //***************************************
    // 捕捉鼠标移动消息,绘制橡皮筋线,
    //作为Hermite曲线的控制点处的切线
    //***************************************
    void CDrawCurvesView::OnMouseMove(UINT nFlags, CPoint point)
    {
     // TODO: Add your message handler code here and/or call default
     if(isLButtonDown)
     {
        CView::OnMouseMove(nFlags, point);
        CClientDC dc(this);
        dc.SetROP2(R2_NOT);
        dc.MoveTo(newPoint);
        dc.LineTo(oldPoint);
        dc.MoveTo(newPoint);
        dc.LineTo(point);
        oldPoint = point;
     }
    }
    //*****************************************************
    //捕捉鼠标左键松开消息,并在捕捉到第四个控制点
    //后,根据从菜单选择项的不同,开始绘制不同曲线
    //******************************************************
    void CDrawCurvesView::OnLButtonUp(UINT nFlags, CPoint point)
    {
     // TODO: Add your message handler code here and/or call default
     isLButtonDown=false;//标志鼠标释放
        ReleaseCapture();//释放鼠标捕捉
        ClipCursor(NULL);//
     CurveCtrlPoints[count++] = point;
      if(count == 4)
      {
      CClientDC dc(this);
      CPen pen;
      pen.CreatePen(PS_SOLID,3,RGB(255,0,0));
      dc.SelectObject(pen);
      switch(type)
      {
        case HERMITE:
                 DrawHermiteCurve(dc,200);
        break;
        case BEZIER:
         DrawBezierCurve(dc,400);
         break;
      }
      pen.DeleteObject();
     }
     CView::OnLButtonUp(nFlags, point);
    }
    //*******************************************
    //菜单响应函数,当菜单项选为Hermite时,
    //绘制曲线的类型设置为HERMITE
    //*******************************************
    void CDrawCurvesView::OnHermite()
    {
     // TODO: Add your command handler code here
     type = HERMITE;
    }
    //******************************************
    //菜单响应函数,当菜单项选为Bezier时,
    //绘制曲线的类型设置为BEZIER
    //******************************************
    void CDrawCurvesView::OnBezier()
    {
     // TODO: Add your command handler code here
     type = BEZIER;
    }
    //**************************
    //绘制hermite曲线的函数
    //**************************
    void CDrawCurvesView::DrawHermiteCurve(CDC &dc,int nPoints)
    {
     int a[4][4] =
     {
      {2,-2,1,1},
      {-3,3,-2,-1},
      {0,0,1,0},
      {1,0,0,0}
     };
        double b[4][2] = {
      {CurveCtrlPoints[0].x,CurveCtrlPoints[0].y},
      {CurveCtrlPoints[2].x,CurveCtrlPoints[2].y},
      {CurveCtrlPoints[1].x-CurveCtrlPoints[0].x,CurveCtrlPoints[1].y-CurveCtrlPoints[1].y},
      {CurveCtrlPoints[3].x-CurveCtrlPoints[2].x,CurveCtrlPoints[3].y-CurveCtrlPoints[2].y}
     };
     CPoint *pt=new CPoint[nPoints];
     double delt = 1.0/nPoints;
     double u = 0.0;
        MultiMatrix(a,b);
     for(int i = 0; i < nPoints; i++)
     {
           pt[i].x =(int) (pow(u,3)*result[0][0] + pow(u,2)*result[1][0]
         + u*result[2][0] + result[3][0]);
        pt[i].y =(int) (pow(u,3)*result[0][1] + pow(u,2)*result[1][1]
         + u*result[2][1] + result[3][1]);
        u += delt;
     }
     dc.Polyline(pt,nPoints);
     delete pt;
    }
    //************************
    //绘制Bezier曲线的函数
    //************************
    void CDrawCurvesView::DrawBezierCurve(CDC &dc,int nPoints)
    {
      double t = 0.0,delt = 0.0;
      delt = 1.0/(double)nPoints;
      CPoint *points = new CPoint[nPoints+1];
      for(int i=0; i<= nPoints;i++)
      {
       points[i] = Decas(4,t);
       t += delt;
      }
      dc.Polyline(points,nPoints);
    }
    //********************************
    //绘制Bezier曲线的辅助函数,
    //主要完成t在某个值时,bezier
    //曲线上的一个点的坐标的计算
    //*********************************
    CPoint CDrawCurvesView::Decas(int ptNum, double t)
    {
     CPoint *coeffa = new CPoint[ptNum+1],coeffa0;
        for(int i=0;i<=ptNum;i++)
     {
      coeffa[i] = CurveCtrlPoints[i];
     }
     for(int r = 1;r <= ptNum;r++)
      for(int j = 0;j < ptNum-r;j++)
      {
       coeffa[j].x=(int)(coeffa[j].x+t*(coeffa[j+1].x-coeffa[j].x));
       coeffa[j].y=(int)(coeffa[j].y+t*(coeffa[j+1].y-coeffa[j].y));
      }
         coeffa0 = coeffa[0];
      delete coeffa;
      return coeffa0;
    }

    发表于 @ 2005年11月13日 09:53:00|评论(loading...)|编辑

    新一篇: 今天用Windows API写的扫雷程序 | 旧一篇: MFC下实现图形学之立方体平移、比例、旋转、投影变换算法

    评论:没有评论。

    发表评论  


    当前用户设置只有注册用户才能发表评论。如果你没有登录,请点击登录
    Csdn Blog version 3.1a
    Copyright © fuliang