百度首页 | 百度空间
 
查看文章
 
编写圆和椭圆的扫描转换算法程序
2006-06-15 02:14

4.2.3 程序实现与上机实习(二)

一、实验目的

编写圆和椭圆的扫描转换算法程序,验证算法的正确性。

二、实验任务

1. 编写中点画圆法的扫描转换程序,考虑原点在(x0,y0)处程序的改动;

2. 添加鼠标程序,实现交互式画圆;

3. 编写中点画椭圆法的扫描转换程序;

4. 添加鼠标程序,实现交互式画椭圆;

三、实验内容

 1.编写中点画圆法的扫描转换程序,考虑原点在(x0,y0)处程序的改动;

分析:考虑圆心不再原点,设圆心坐标为(x0,y0)。通过平移坐标原点到圆心,则第二个8分圆上一点p(x,y),其原始坐标为

              x’=x+x0

              y’=y+y0

                  即p’1(x0 +x, y+y0)

其它7个对称点分别是:p’2(x0+y,y+x0), p’3 (x0+y,y0-x),p’4 (x0+x,y0-y),p’5 (x0-x,y0-y),p’6 (x0-y,y0-x),p’7 (x0-y,y0+x),p’8 (x0-x,y0+y)

算法程序如下:

MidpointCircle(int x0,int y0,int r, int color)

     {

      int x,y;

float d;

x=0;y=r;d=1.25-r;

CirPot(x0,y0,x,y,color);

while (x<=y)

{

 if(d<0)

  {

    d+=2*x+3; x++;

  }

  else

   {

     d+=2*(x-y)+5;

    x++;  y--;

    }

CirPot(x0,y0,x,y,color);

}  /*  while*/

} /* MidpointCiecle */

   

   int CirPot(int x0,int y0,int x,int y,int color)

 {

   Setpixel((x0+x),(y0+y));

   Setpixel((x0+y),(y0+x));

   Setpixel((x0+y),(y0-x));

   Setpixel((x0+x),(y0-y));

   Setpixel((x0-x),(y0-y));

   Setpixel((x0-y),(y0-x));

   Setpixel((x0-y),(y0+x));

   Setpixel((x0-x),(y0+y));

}

程序实现步骤:

(1) 建立MidPointCircle工程文件;

(2) 右击CMidPointCircleView类,建立成员函数

     void MidpointCircle(CDC *pDC,int x0, int y0, int r, COLORREF color)

     int CirPot(CDC *pDC,int x0, int y0, int x, int y, COLORREF color)

 (3)  编写成员函数代码,程序如下:

void CMidPointCircleView::MidpointCircle(CDC *pDC,int x0, int y0, int r, COLORREF color)

{

  int x,y;

  float d;

  x=0;y=r;d=1.25-r;

  CirPot(pDC,x0,y0,x,y,color);

while (x<=y)

{

 if(d<0)

 {

    d+=2*x+3; x++;

  }

  else

   {

     d+=2*(x-y)+5;

    x++;  y--;

    }

CirPot(pDC,x0,y0,x,y,color);

}  /*  while*/

}

int CMidPointCircleView::CirPot(CDC *pDC,int x0, int y0, int x, int y, COLORREF color)

{

   pDC->SetPixel((x0+x),(y0+y),color);

   pDC->SetPixel((x0+y),(y0+x),color);

   pDC->SetPixel((x0+y),(y0-x),color);

   pDC->SetPixel((x0+x),(y0-y),color);

   pDC->SetPixel((x0-x),(y0-y),color);

   pDC->SetPixel((x0-y),(y0-x),color);

   pDC->SetPixel((x0-y),(y0+x),color);

   pDC->SetPixel((x0-x),(y0+y),color);

return 0;

}

(4)编写OnDraw(CDC* pDC)函数,程序如下:

void CMidPointCircleView::OnDraw(CDC* pDC)

{

 CMidPointCircleDoc* pDoc = GetDocument();

 ASSERT_VALID(pDoc);

 // TODO: add draw code for native data here

 MidpointCircle(pDC,100, 100, 10, RGB(255,0,0));

    MidpointCircle(pDC,500, 300, 60, RGB(255,255,0));

}

(6) 编译、运行程序,查看结果。

任务2:添加鼠标程序,实现交互式画圆

在任务1的基础上,完成下列步骤:

 (1)向视图类中添加自定义的成员变量

   用鼠标右键单击视图类,选择“Add Member Variable…”,添加下面三个成员变量。

proctected :

      int m_r;   // 半径

CPoint  m_bO;  // 圆心

     CPoint  m_bR;  //圆上的点

     int      m_ist;  //圆心与圆周上点的区别,m_ist=0,表示鼠标左击点为圆心,

                    //m_ist=1,表示鼠标左击点为圆周上的点

  (2)在视图类CPP文件的构造函数中初始化成员变量

CMidPointCircleMouseView::CMidPointCircleMouseView()

{

 // TODO: add construction code here

   m_bO.x=0;  m_bO.y=0;  //圆心

   m_bR.x=0;  m_bR.y=0;  //圆上的点

   m_ist=0;   //圆心与圆上的点区别

   m_r=0;  //圆的半径

}

(3)向视图类中添加自定义的成员函数原型:

      public:

         int  ComputeRadius(CPoint cenp,CPoint ardp);

添加成员函数的程序代码:

int CMouseSpringView::ComputeRadius(CPoint cenp, CPoint ardp)

{

  int dx=cenp.x-ardp.x;

  int dy=cenp.y-ardp.y;

  //sqrt()函数的调用,在头文件中加入#include "math.h"

  return (int)sqrt(dx*dx+dy*dy);

}

(4)向视图类中添加两个鼠标消息响应函数,并输入鼠标处理程序代码。

    具体操作方法与鼠标示例1方法相同。一个是OnLButtonDown()函数,另一个是OnMouseMove()函数。程序如下:

void CMidPointCircleMouseView::OnLButtonDown(UINT nFlags, CPoint point)

{

 // TODO: Add your message handler code here and/or call default

   

 CDC *pDC=GetDC();

    pDC->SelectStockObject(NULL_BRUSH);

 if (!m_ist)  //绘制圆

 {

  m_bO=m_bR=point; //纪录第一次单击鼠标位置,定圆心

  m_ist++;

 }

 else

 {

  m_bR=point;  //记录第二次单击鼠标的位置,定圆周上的点

  m_ist--;   // 为新绘图作准备

  m_r=ComputeRadius(m_bO,m_bR);

  MidpointCircle(pDC,m_bO.x,m_bO.y,m_r,RGB(255,0,0));

 }

 ReleaseDC(pDC); //释放设备环境

 CView::OnLButtonDown(nFlags, point);

}

void CMidPointCircleMouseView::OnMouseMove(UINT nFlags, CPoint point)

{

 // TODO: Add your message handler code here and/or call default

 CDC *pDC=GetDC();

    int nDrawmode=pDC->SetROP2(R2_NOT); //设置异或绘图模式,并保存原来绘图模式

 pDC->SelectStockObject(NULL_BRUSH);

 if(m_ist==1)

 {

  CPoint prePnt,curPnt;

     prePnt=m_bR;  //获得鼠标所在的前一位置

  curPnt=point;

  //绘制橡皮筋线

        m_r=ComputeRadius(m_bO,prePnt);

        MidpointCircle(pDC,m_bO.x,m_bO.y,m_r,RGB(255,0,0));//用异或模式重复画圆,擦出所画的圆

 // DrawCircle(pDC,m_bO,prePnt); 

        m_r=ComputeRadius(m_bO,curPnt);

        MidpointCircle(pDC,m_bO.x,m_bO.y,m_r,RGB(255,0,0)); //用当前位置作为圆周上的点画圆

  m_bR=point;

    }

 pDC->SetROP2(nDrawmode);  //恢复原绘图模式

 ReleaseDC(pDC);  //释放设备环境

 CView::OnMouseMove(nFlags, point);

}

 


类别:c/c++ | 添加到搜藏 | 浏览() | 评论 (1)
 
最近读者:
 
网友评论:
1
2008-05-02 23:14
3. 编写中点画椭圆法的扫描转换程序;
这个在哪?骗人!!
 
发表评论:
姓 名:
网址或邮箱: (选填)
内 容:
验证码:
 

     

©2008 Baidu