⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xiaoguanview.cpp

📁 看看能不能用
💻 CPP
字号:
// xiaoguanView.cpp : implementation of the CXiaoguanView class
//

#include "stdafx.h"
#include "math.h"
#include "xiaoguan.h"
#include "xiaoguanDoc.h"
#include "xiaoguanView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif



/////////////////////////////////////////////////////////////////////////////
// CXiaoguanView

IMPLEMENT_DYNCREATE(CXiaoguanView, CView)

BEGIN_MESSAGE_MAP(CXiaoguanView, CView)
	//{{AFX_MSG_MAP(CXiaoguanView)
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_MOUSEMOVE()
	ON_COMMAND(ID_xiaoguanLine, OnxiaoguanLine)
	ON_COMMAND(ID_xiaoguanCcircle, OnxiaoguanCcircle)
	ON_COMMAND(ID_BEZIER, OnBezier)
	ON_COMMAND(ID_CLEAR, OnClear)
	ON_COMMAND(ID_DRAWPIXEL, OnDrawpixel)
	ON_COMMAND(ID_xiaoguanduobianxing, Onxiaoguanduobianxing)
	ON_WM_RBUTTONDOWN()
	ON_WM_RBUTTONUP()
	ON_COMMAND(ID_xiaoguanEllipse, OnxiaoguanEllipse)
	ON_COMMAND(ID_xiaoguanfilled, Onxiaoguanfilled)
	ON_COMMAND(ID_xiaoguanColor, OnxiaoguanColor)
	//}}AFX_MSG_MAP
	// Standard printing commands
	ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CXiaoguanView construction/destruction

CXiaoguanView::CXiaoguanView()
{
	// TODO: add construction code here
	m_bmouseDown = false;
	m_hCross = AfxGetApp()->LoadStandardCursor(IDC_CROSS);
	m_hArrow = AfxGetApp()->LoadStandardCursor(IDC_ARROW);
//	m_bmouseDown=false;
	m_start=true;
	m_totnum=0;
	m_drawpixel=false;
	m_makeBezier=false;
	color=RGB(255,255,0);
}

CXiaoguanView::~CXiaoguanView()
{
}

BOOL CXiaoguanView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CXiaoguanView drawing

void CXiaoguanView::OnDraw(CDC* pDC)
{
	CXiaoguanDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here
	
}

/////////////////////////////////////////////////////////////////////////////
// CXiaoguanView printing

BOOL CXiaoguanView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// default preparation
	return DoPreparePrinting(pInfo);
}

void CXiaoguanView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add extra initialization before printing
}

void CXiaoguanView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add cleanup after printing
}

/////////////////////////////////////////////////////////////////////////////
// CXiaoguanView diagnostics

#ifdef _DEBUG
void CXiaoguanView::AssertValid() const
{
	CView::AssertValid();
}

void CXiaoguanView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CXiaoguanDoc* CXiaoguanView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CXiaoguanDoc)));
	return (CXiaoguanDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CXiaoguanView message handlers

void CXiaoguanView::OnLButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	CClientDC dc(this);
	if(n==5)
	{
       m_point[m_totnum++]=point;
	   }


      if(m_drawpixel)
		{ 
		  m_point[m_totnum++]=point;
		if(m_totnum>=2)
		{CClientDC dc(this);
		dc.MoveTo(m_point[m_totnum-2]);
		dc.LineTo(m_point[m_totnum-1]);
		}
		}
    	


	
	/*SetCapture();                         // 将鼠标消息发送到视窗口
    CRect rect;
    GetClientRect(&rect);          // 得到客户窗口的大小
    ClientToScreen(&rect);        // 将当前窗口坐标转换成屏幕坐标
    ClipCursor(&rect);               // 把鼠标限定在其参数指定的矩形区域内
	SetCursor(m_hCross);*/	// 设置鼠标形状为十字形
     
   if((n==1)|(n==2)|(n==8))
   {	
	   SetCapture();                         // 将鼠标消息发送到视窗口
	   CRect rect;
	   GetClientRect(&rect);          // 得到客户窗口的大小
	   ClientToScreen(&rect);        // 将当前窗口坐标转换成屏幕坐标
	   ClipCursor(&rect);               // 把鼠标限定在其参数指定的矩形区域内
	SetCursor(m_hCross);
	   m_bmouseDown = true;        // 鼠标左键按下
	m_ptStart = point;
	m_ptOld = point;
   }
   if(n==3)
   {
    if(m_start)
	{
		m_start=false;
		A=point;
		m_ptStart=point;
		nCount=0;
		lpPoints[nCount]=point;
		nCount++;
	}
	else
	{m_ptOld=point;
	CClientDC dc(this);
	dc.MoveTo(m_ptStart);
	dc.LineTo(m_ptOld);

    m_ptStart=point;
	lpPoints[nCount]=point;
	nCount++;
	} 
	
   }

	CView::OnLButtonDown(nFlags, point);
}

void CXiaoguanView::OnLButtonUp(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	if (m_bmouseDown )
	{
		m_bmouseDown=false;
        ReleaseCapture();
		ClipCursor( NULL );
    	CClientDC dc(this);
		dc.SetROP2( R2_NOT );
		dc.MoveTo( m_ptStart );       //这两行代码擦除从起点(鼠标按下点)到
	    dc.LineTo( m_ptOld );          //上次鼠标移动到的位置之间的临时线   
	    //dc.SetROP2( R2_COPYPEN );
		//dc.MoveTo(m_ptStart);
		//dc.LineTo(point);
	  if (n==2)
	  {
	  
		  m_circle(m_ptStart.x,point.x,m_ptStart.y,point.y,color);
		  
	  }
		if (n==1)
		{
			dda_line(m_ptStart.x,m_ptStart.y,point.x,point.y,color);
		}if (n==8)
		{
			m_Ellipse(m_ptStart.x,m_ptStart.y ,point.x,point.y,m_ptStart,color);
		}
		

		SetCursor(m_hArrow);
	}
	CView::OnLButtonUp(nFlags, point);
}

void CXiaoguanView::OnMouseMove(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	if( m_bmouseDown )
	{
		CClientDC dc(this);
		//dc.SetROP2( R2_NOT );
		//dc.MoveTo( m_ptStart );	//这两行代码擦除从起点(鼠标按下点)到
		//dc.LineTo( m_ptOld );	//上次鼠标移动到的位置之间的临时线
		//dc.MoveTo( m_ptStart );	//这两行代码从起点到鼠标当前位置画线
	//	dc.LineTo( point );		// 
		//m_ptOld = point; //鼠标当前位置在下一次鼠标移动事件看来就是"旧位置"
	}
	CView::OnMouseMove(nFlags, point);
}
void CXiaoguanView::m_circle(float x1,float x2,float y1,float y2,int color)
{
  float r,x=0,y,deltax,deltay,d;
  r=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); 
  y=r;
  CClientDC dc(this);
  dc.SetPixel(x1+x,y1+y,220);
  deltax=3;deltay=2-r-r;d=1-r;
  while(x<y)
  {
	  if(d<0)
	  {
		  d+=deltax;
		  deltax+=2;
		  x++;
	  }
	  else
	  {
		  d+=(deltax+deltay);
		  deltax+=2;deltay+=2;
		  x++;y--;
	  }
	  dc.SetPixel(x1+x,y1+y,color);
	  dc.SetPixel(x1-x,y1-y,color);
	  dc.SetPixel(x1-x,y1+y,color);
	  dc.SetPixel(x1+x,y1-y,color);
	  dc.SetPixel(x1-y,y1-x,color);
	  dc.SetPixel(x1+y,y1+x,color);
	  dc.SetPixel(x1+y,y1-x,color);
	  dc.SetPixel(x1-y,y1+x,color);  
  }
}
void CXiaoguanView::dda_line(int xa,int ya,int  xb,int  yb,int c)
{	
	float delta_x, delta_y, x, y;
	int dx, dy, steps, k;
	dx=xb-xa;
	dy=yb-ya;
    if (abs(dx)>abs(dy)) steps=abs(dx);
	else steps=abs (dy);
	delta_x=(float)dx / (float)steps;
	delta_y=(float)dy / (float)steps;
	x=xa;
	y=ya;
		CClientDC dc(this);
			  dc.SetPixel(x+0.5,y+0.5,c);
	for (k=1; k<=steps; k++)
	{
		x+=delta_x;
		y+=delta_y;
	dc.SetPixel(x+0.5,y+0.5,c);
	}
}	
/*void CXiaoguanView::Onxiaoguandraw() 
{
	// TODO: Add your command handler code here

}*/
void CXiaoguanView::OnxiaoguanLine() 
{	AfxMessageBox("可以用你所选择的颜色画直线了");

n=1;	// TODO: Add your command handler code here	
}
void CXiaoguanView::OnxiaoguanCcircle() 
{	AfxMessageBox("可以用你所选择的颜色画圆了");
n=2	;// TODO: Add your command handler code here	
}
void CXiaoguanView::OnBezier() 
{
	n=5;// TODO: Add your command handler code here
	CString mes;
	CClientDC dc(this);
	mes.Format("一共有%d个控制点!",m_totnum);
	m_drawpixel=false;
	m_makeBezier=true;
	dc.TextOut(400,400,mes);
	AfxMessageBox("开始作Bezier曲线!");

	if(m_makeBezier)
	{
		if(m_totnum>=2)
			makeBezier();
		else
			AfxMessageBox("您给的控制点数量不够!");
	}


}

void CXiaoguanView::OnClear() 
{
	n=6;// TODO: Add your command handler code here
	Invalidate(TRUE);
	m_totnum=0;
	m_drawpixel=false;
	m_makeBezier=false;
}



double CXiaoguanView::m_power(double tt, int ii)
{
	double ress=1.0;
	int jj=0;
	for(jj=0;jj<ii;jj++)
	{
		ress*=tt;
	}
	return ress;
}

long CXiaoguanView::m_stair(int aaa)
{
	int tem=1;
	int dd;
	int temp_aaa=aaa;
	for(dd=0;dd<aaa;dd++)
	{
		tem*=temp_aaa;
		temp_aaa--;
	}
	return tem;
}

int CXiaoguanView::makeBezier()
{
	CClientDC dc(this);
	int i=0;
	double tempx=0.0;
	double tempy=0.0;
	CPoint cur_point;
	double t=0.0;
	int n=m_totnum-1;
	while(t<=1)
	{
		tempx=0.0;
		tempy=0.0;
		i=0;
		while(i<=n)
		{
			tempx+=(m_point[i].x*m_power(t,i)*m_power((1-t),(n-i))*m_Zuhe(n,i));
			tempy+=(m_point[i].y*m_power(t,i)*m_power((1-t),(n-i))*m_Zuhe(n,i));
			i++;
		}
		cur_point.x=(long)tempx;
		cur_point.y=(long)tempy;
		t+=0.00001;
		dc.SetPixel(cur_point.x,cur_point.y,RGB(255,0,0));
	}	
	return 0;
}

long CXiaoguanView::m_Zuhe(int nn, int ii)
{
	long res;
	res=m_stair(nn)/((m_stair(ii))*m_stair(nn-ii));
	return(res);
}

void CXiaoguanView::OnDrawpixel() 
{
	// TODO: Add your command handler code here
	m_drawpixel=true;
	m_makeBezier=false;
	AfxMessageBox("开始作控制点了!");
}
void CXiaoguanView::Onxiaoguanduobianxing() 
{AfxMessageBox("可以开始用你选择的颜色画多边形了!");
n=3;
// TODO: Add your command handler code here	
}
void CXiaoguanView::OnRButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	if (n==3)
	{
	m_start=true;
    ReleaseCapture();
	ClipCursor( NULL );
    CClientDC dc(this);
    dc.MoveTo(m_ptStart);
	dc.LineTo(A);
	CRect rect;
	}
	CView::OnRButtonDown(nFlags, point);
	
}
void CXiaoguanView::OnRButtonUp(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	if(RightDown)
	{
		RightDown=false;
		ReleaseCapture();
		ClipCursor(NULL);
	}	
	CView::OnRButtonUp(nFlags, point);
}



void CXiaoguanView::m_Ellipse(float x1, float x2, float y1, float y2,CPoint o,int color)
{
	int x,y,a,b;
	a=x1;
	b=x2;
	float d1,d2;
	 CClientDC dc(this);
	x=0;y=b;
	d1=b*b+a*a*(-b+0.25);
    dc.SetPixel(x+0.5+o.x,y+0.5+o.y,255);
	dc.SetPixel(-y+0.5+o.x,x+0.5+o.y,255);
	dc.SetPixel(y+0.5+o.x,-x+0.5+o.y,255);
	dc.SetPixel(-x+0.5+o.x,-y+0.5+o.y,255);
	while (b*b*(x+1)<a*a*(y-0.5))
    {
		if (d1<0)
		{
			d1+=b*b*(2*x+3);
			x++;
		}
	
    	else
		{
		d1+=(b*b*(2*x+3)+a*a*(-2*y+2));
		x++;y--;
		}
		dc.SetPixel(x+0.5,y+0.5,255);
}
d2=sqrt(b*(x+0.5))+sqrt(a*(y-1))-sqrt(a*b);
while(y>0)
{
	if (d2<0)
	{
		
		d2+=b*b*(2*x+2)+a*a*(-2*y+3);
		x++;y--;
	}
	
	else
	{
		d2+=a*a*(-2*y+3);
		y--;
	}
	dc.SetPixel(x+0.5+o.x,y+0.5+o.y,255);
	dc.SetPixel(-y+0.5+o.x,x+0.5+o.y,255);
	dc.SetPixel(y+0.5+o.x,-x+0.5+o.y,255);
	dc.SetPixel(-x+0.5+o.x,-y+0.5+o.y,255);
}
}

void CXiaoguanView::OnxiaoguanEllipse() 
{
	
	n=8;
	
	// TODO: Add your command handler code here
	
}

void CXiaoguanView::FillPolygon(CPoint *lpPoints, int nCount, int nColor)
{
 // 检查参数合法性
 //ASSERT_VALID(pDC);
 ASSERT(lpPoints);
 ASSERT(nCount>2);
 ASSERT(nColor>=0);
 
 // 边结构数据类型
 typedef struct Edge{
  int ymax;  // 边的最大y坐标
  float x; // 与当前扫描线的交点x坐标
  float dx; // 边所在直线斜率的倒数
  struct Edge * pNext; // 指向下一条边
 }Edge, * LPEdge;

 int i=0,j=0,k=0;
 int y0=0,y1=0;  // 扫描线的最大和最小y坐标
 LPEdge pAET=NULL; // 活化边表头指针
 LPEdge * pET=NULL;  // 边表头指针

 pAET=new Edge; // 初始化表头指针,第一个元素不用
 pAET->pNext=NULL;
 
 // 获取y方向扫描线边界
 y0=y1=lpPoints[0].y;
 for(i=1;i<nCount;i++)
 {
  if(lpPoints[i].y<y0)
   y0=lpPoints[i].y;
  else if(lpPoints[i].y>y1)
   y1=lpPoints[i].y;
 }
 if(y0>=y1) return;

 // 初始化边表,第一个元素不用
 pET=new LPEdge[y1-y0+1];
 for(i=0;i<=y1-y0;i++)
 {
  pET[i]= new Edge;
  pET[i]->pNext=NULL;
 }

 for(i=0;i<nCount;i++)   //构造边表
 {
  j=(i+1)%nCount; // 组成边的下一点
  if(lpPoints[i].y != lpPoints[j].y)// 如果该边不是水平的则加入边表
  {
   LPEdge peg;   // 指向该边的指针
   LPEdge ppeg;  // 指向边指针的指针

   // 构造边
   peg =new Edge;
   k=(lpPoints[i].y>lpPoints[j].y)?i:j;
   peg->ymax=lpPoints[k].y; // 该边最大y坐标
   k=(k==j)?i:j;  
   peg->x=(float)lpPoints[k].x; // 该边与扫描线焦点x坐标
   if(lpPoints[i].y != lpPoints[j].y) 
    peg->dx=(float)(lpPoints[i].x-lpPoints[j].x)/(lpPoints[i].y-lpPoints[j].y);// 该边斜率的倒数
   peg->pNext=NULL;

   // 插入边
   ppeg=pET[lpPoints[k].y-y0]; 
   while(ppeg->pNext)
    ppeg=ppeg->pNext;
   ppeg->pNext=peg;
  }// end if
 }// end for i

 // 扫描
 for(i=y0;i<=y1;i++)
 {
  LPEdge peg0=pET[i-y0]->pNext;
  LPEdge peg1=pET[i-y0];
  if(peg0)// 有新边加入
  {
   while(peg1->pNext)
    peg1=peg1->pNext;
   peg1->pNext=pAET->pNext;
   pAET->pNext=peg0;
  }

  // 按照x递增排序pAET
  peg0=pAET;
  while(peg0->pNext)
  {
   LPEdge pegmax=peg0;
   LPEdge peg1=peg0;
   LPEdge pegi=NULL;

   while(peg1->pNext)
   {
    if(peg1->pNext->x>pegmax->pNext->x)
     pegmax=peg1;
    peg1=peg1->pNext;
   }
   pegi=pegmax->pNext;
   pegmax->pNext=pegi->pNext;
   pegi->pNext=pAET->pNext;
   pAET->pNext=pegi;
   if(peg0 == pAET)
    peg0=pegi;
  }

  // 遍历活边表,画线
  peg0=pAET;
  while(peg0->pNext)
  {
   if(peg0->pNext->pNext)
   {
    dda_line((int)peg0->pNext->x,i,(int)peg0->pNext->pNext->x,i,nColor);
    peg0=peg0->pNext->pNext;
   }
   else
    break;
  }

  // 把ymax=i的节点从活边表删除并把每个节点的x值递增dx
  peg0=pAET;
  while(peg0->pNext)
  {
   if(peg0->pNext->ymax < i+2)
   {
    peg1=peg0->pNext;
    peg0->pNext=peg0->pNext->pNext; //删除
    delete peg1;
    continue;
   }
   peg0->pNext->x+=peg0->pNext->dx; //把每个节点的x值递增dx
   peg0=peg0->pNext;
  }
 }

 // 删除边表
 for(i=0;i<y1-y0;i++)
  if(pET[i])
   delete pET[i];
 if(pAET) 
  delete pAET;
 if(pET)
  delete[] pET; 


}


void CXiaoguanView::Onxiaoguanfilled() 
{
	AfxMessageBox("可以填充你所选择的颜色了");
	// TODO: Add your command handler code here
	n==9;
	FillPolygon(lpPoints,nCount,color);
	

}

void CXiaoguanView::OnxiaoguanColor() 
{
		  CColorDialog d;
		  if(d.DoModal()==IDOK)
			  color=d.GetColor();
		  
	  // TODO: Add your command handler code here
	
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -