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

📄 bezier.cpp

📁 一个复杂的画图系统
💻 CPP
字号:
// Bezier.cpp: implementation of the CBezier class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "geditor.h"
#include "Bezier.h"
#include "prop.h"
#include "geditorView.h"
#include <cmath>
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
IMPLEMENT_SERIAL(CBezier, CShape,1)
CBezier::CBezier()
{
	Curptnum=1;
	edgeclr=0x00C0C0C0;
}

CBezier::~CBezier()
{

}

void CBezier::Draw(CDC* pDC)
{
	CPen pen(linesty,width,(COLORREF)m_color);
	CPen* oldPen = pDC->SelectObject(&pen);
	pDC->PolyBezier(m_tCtlPt,4);
	CPoint pt;
	if(dragmode!=0)
	{
		CPen penb(PS_SOLID,1,RGB(0,0,0));
		pDC->SelectObject(&penb);
		pt=m_tCtlPt[0];
		pDC->Rectangle(pt.x-4,pt.y-4,pt.x+4,pt.y+4);
		UpdateProp(0);
		CPen pena(PS_DOT,1,RGB(0,0,0));
		switch(Curptnum)
		{
		case 4:
			pt=m_tCtlPt[2];
			pDC->Rectangle(pt.x-4,pt.y-4,pt.x+4,pt.y+4);
			pDC->SelectObject(&pena);
			pDC->MoveTo(m_tCtlPt[2]);
			pDC->LineTo(m_tCtlPt[3]);
			pDC->SelectObject(&penb);
			UpdateProp(2);
		case 3:
			pt=m_tCtlPt[1];
			pDC->Rectangle(pt.x-4,pt.y-4,pt.x+4,pt.y+4);
			pDC->SelectObject(&pena);
			pDC->MoveTo(m_tCtlPt[1]);
			pDC->LineTo(m_tCtlPt[0]);
			pDC->SelectObject(&penb);
			UpdateProp(1);
		case 2:
			pt=m_tCtlPt[3];
			pDC->Rectangle(pt.x-4,pt.y-4,pt.x+4,pt.y+4);
			UpdateProp(3);
			break;
		case 0:
			pt=m_tCtlPt[0];
			pDC->Rectangle(pt.x-4,pt.y-4,pt.x+4,pt.y+4);
			pt=m_tCtlPt[3];
			pDC->Rectangle(pt.x-4,pt.y-4,pt.x+4,pt.y+4);
			pt=m_tCtlPt[1];
			pDC->Rectangle(pt.x-4,pt.y-4,pt.x+4,pt.y+4);
			pt=m_tCtlPt[2];
			pDC->Rectangle(pt.x-4,pt.y-4,pt.x+4,pt.y+4);
			pDC->SelectObject(&pena);
			pDC->MoveTo(m_tCtlPt[0]);
			pDC->LineTo(m_tCtlPt[1]);
			pDC->MoveTo(m_tCtlPt[2]);
			pDC->LineTo(m_tCtlPt[3]);
			if(dragmode==1)
				UpdateProp(4);
			else if(dragmode==2)
				UpdateProp(Curpt);
			break;
		default:
			break;
		};
		DeleteObject(pena);
		DeleteObject(penb);
	};
	pDC->SelectObject(oldPen);
	DeleteObject(pen);
}

#ifdef _DEBUG
void CBezier::AssertValid() const
{
	CObject::AssertValid();
	
}

void CBezier::Dump(CDumpContext& dc) const
{
	CObject::Dump(dc);
}

#endif //_DEBUG

void CBezier::Serialize(CArchive &ar)
{
	int i;
	//Call base class Serialize()
	CObject::Serialize(ar);

	if(ar.IsStoring())
	{ 
		for(i =0;i<4;i++)
			ar<<m_tCtlPt[i].x<<m_tCtlPt[i].y;

		ar<<m_color<<dragmode<<name<<linesty;
	}
	else
	{
		for(i =0;i<4;i++)
			ar>>m_tCtlPt[i].x>>m_tCtlPt[i].y;

		ar>>m_color>>dragmode>>name>>linesty;		
	}
}

void CBezier::InitProp()
{	
/*	int count=p->m_list.GetItemCount();
	if (count!=0)
	{
		for(int i=0;i<count;i++)
		p->m_list.DeleteItem(0);
	};
	item.mask=LVIF_TEXT|LVIF_STATE;
	item.state=0;
	item.stateMask=0;

	item.iItem=0;
	item.iSubItem=0;
	item.pszText="StartPt.X";
	p->m_list.InsertItem(&item);
	sprintf(svalue,"%3d",m_tCtlPt[0].x);
	p->m_list.SetItemText(0,1,svalue);

	item.iItem=1;
	item.iSubItem=0;
	item.pszText="StartPt.Y";
	p->m_list.InsertItem(&item);
	sprintf(svalue,"%3d",m_tCtlPt[0].y);
	p->m_list.SetItemText(1,1,svalue);

	item.iItem=2;
	item.iSubItem=0;
	item.pszText="EndPt.X";
	p->m_list.InsertItem(&item);
	sprintf(svalue,"%3d",m_tCtlPt[3].x);
	p->m_list.SetItemText(2,1,svalue);
	
	item.iItem=3;
	item.iSubItem=0;
	item.pszText="EndPt.Y";
	p->m_list.InsertItem(&item);	
	sprintf(svalue,"%3d",m_tCtlPt[3].y);
	p->m_list.SetItemText(3,1,svalue);
	
	item.iItem=4;
	item.iSubItem=0;
	item.pszText="CtlPtA.X";
	p->m_list.InsertItem(&item);
	
	item.iItem=5;
	item.iSubItem=0;
	item.pszText="CtlPtA.Y";
	p->m_list.InsertItem(&item);
	
	item.iItem=6;
	item.iSubItem=0;
	item.pszText="CtlPtB.X";
	p->m_list.InsertItem(&item);
	
	item.iItem=7;
	item.iSubItem=0;
	item.pszText="CtlPtB.Y";
	p->m_list.InsertItem(&item);	
	
	p->m_Fill.EnableWindow(FALSE);
	p->bkclr=0;
	p->m_fill=FALSE;
	p->OtherShow(m_color,width,linesty);*/
}

int CBezier::InTest(CPoint pt)
{
	int Rng=4;
	int i=0;
	BOOL None=TRUE;
	while((i<4)&&(None))
	{
		if ((abs(pt.x-m_tCtlPt[i].x)<Rng)&&(abs(pt.y-m_tCtlPt[i].y)<Rng))
			None=FALSE;
		i++;
	};
	if (!None) 
	{
		::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZEALL));
		Curpt=i-1;
		return 2;
	};
	int x=0;
	int num=0,j=0;
	float deltax=0,deltay=0,yt=0;
	for (i=0;i<4;i++)
	{
		if (i==3) j=0;
		else j=i+1;
		if (((pt.y<=m_tCtlPt[j].y)&&(pt.y>=m_tCtlPt[i].y))
			|((pt.y>=m_tCtlPt[j].y)&&(pt.y<=m_tCtlPt[i].y)))
		{
			deltax=(float)(m_tCtlPt[j].x-m_tCtlPt[i].x);
			deltay=(float)(m_tCtlPt[j].y-m_tCtlPt[i].y);
			yt=(float)(pt.y-m_tCtlPt[i].y);
			x=(int)((deltax/deltay)*yt)+m_tCtlPt[i].x;
			if(pt.x<=x)
				num++; 
		};
	};
	if ((num%2)==1)//取模
	{
		::SetCursor(AfxGetApp()->LoadCursor(IDC_CURSEL));
		return 1;
	};
	return 0;
}

void CBezier::dragobj(int leash, CDC *pDC, CPoint pt, CGeditorView *pView)
{
	if (leash==1)//约束轴
		pt.y=movept.y;
	else if (leash==2)
		pt.x=movept.x;
	invalid(pView);
	if(dragmode==1) 
	{
		for(int i=0;i<4;i++)
		{
			m_tCtlPt[i].x+=pt.x-movept.x;
			m_tCtlPt[i].y+=pt.y-movept.y;
		};
		movept.x=pt.x;
		movept.y=pt.y;
	} else if (dragmode==2) 
		m_tCtlPt[Curpt]=pt;
	Draw(pDC);
}

void CBezier::Mirror(int syd, CDC *pDC, CPoint &basept, CGeditorView *pView)
{
	invalid(pView);
	int i=0;
	int txy=0;
	switch(syd)
	{
	case 0://x轴为对称轴
		for(i=0;i<4;i++)
			m_tCtlPt[i].y=2*basept.y-m_tCtlPt[i].y;
		break;
	case 1://y轴为对称轴
		for(i=0;i<4;i++)
			m_tCtlPt[i].x=2*basept.x-m_tCtlPt[i].x;
		break;
	case 2://原点对称
		for(i=0;i<4;i++)
		{
			m_tCtlPt[i].y=2*basept.y-m_tCtlPt[i].y;
			m_tCtlPt[i].x=2*basept.x-m_tCtlPt[i].x;
		};
		break;
	case 3://自对称
		break;
	default:
		break;
	};
	Draw(pDC);
}

void CBezier::rotate(int rsel, CDC *pDC, CPoint pt, CGeditorView *pView)
{
	invalid(pView);
	if(dragmode==2)
	{
		double r=sqrt((m_ptAry[Curpt].x-basept.x)*(m_ptAry[Curpt].x-basept.x)+(m_ptAry[Curpt].y-basept.y)*(m_ptAry[Curpt].y-basept.y));
		double R=sqrt((pt.x-basept.x)*(pt.x-basept.x)+(pt.y-basept.y)*(pt.y-basept.y));
		double x=(r/R)*(pt.x-basept.x)+basept.x;
		double y=(r/R)*(pt.y-basept.y)+basept.y;
		double l=sqrt((x-m_ptAry[Curpt].x)*(x-m_ptAry[Curpt].x)+(y-m_ptAry[Curpt].y)*(y-m_ptAry[Curpt].y));
		double sindelt0=l/(2*r);     //1/2 A0
		double cosdelt0=1-2*sindelt0*sindelt0;
		sindelt0=sqrt(1-cosdelt0*cosdelt0);
		double tg01=(double)(movept.y-basept.y)/(double)(movept.x-basept.x);
		double tg02=(double)(pt.y-basept.y)/(double)(pt.x-basept.x);
		if ((tg02-tg01)<0) sindelt0=-sindelt0;
		movept=pt;
		for (int i=0;i<4;i++)
		{
			double x=(m_ptAry[i].x-basept.x);
			double y=(m_ptAry[i].y-basept.y);
			double cos0=x/m_RAry[i];
			double sin0=y/m_RAry[i];
			cos0=cos0*cosdelt0-sin0*sindelt0;
			sin0=sin0*cosdelt0+cos0*sindelt0;
			m_ptAry[i].x=m_RAry[i]*cos0+basept.x;
			m_ptAry[i].y=m_RAry[i]*sin0+basept.y;
			double jd=0.5;
			m_tCtlPt[i].x=(int)(m_ptAry[i].x+jd);
			m_tCtlPt[i].y=(int)(m_ptAry[i].y+jd);
		};
	};
	Draw(pDC);

}

void CBezier::invalid(CGeditorView *pView)
{
	CPoint apoly[4];
	CRgn* pRgne=new CRgn();
	pRgne->CreatePolygonRgn(&(m_tCtlPt[0]),4,ALTERNATE);
	pView->InvalidateRgn(pRgne);
	delete pRgne;
	CRgn* pRgns;
	int j=0;
	CPoint spt,ept;
	for (int i=0;i<4;i++)
	{
		apoly[0].x=m_tCtlPt[i].x-10;
		apoly[1].x=m_tCtlPt[i].x-10;
		apoly[2].x=m_tCtlPt[i].x+10;
		apoly[3].x=m_tCtlPt[i].x+10;
		apoly[0].y=m_tCtlPt[i].y-10;
		apoly[1].y=m_tCtlPt[i].y+10;
		apoly[2].y=m_tCtlPt[i].y+10;
		apoly[3].y=m_tCtlPt[i].y-10;
		pRgns=new CRgn();
		pRgns->CreatePolygonRgn(apoly,4,ALTERNATE);
		pView->InvalidateRgn(pRgns);
		if (i==3)
			j=0;
		else j=i+1;
		spt=m_tCtlPt[i];
		ept=m_tCtlPt[j];
		int itwd=width/2+1;
		if ((spt.x>ept.x)&&(spt.y>ept.y)||
		(spt.x<ept.x)&&(spt.y<ept.y)) 
		{
			apoly[0].x=spt.x-itwd;
			apoly[1].x=spt.x+itwd;
			apoly[2].x=ept.x+itwd;
			apoly[3].x=ept.x-itwd;
			apoly[0].y=spt.y+itwd;
			apoly[1].y=spt.y-itwd;
			apoly[2].y=ept.y-itwd;
			apoly[3].y=ept.y+itwd;
		} else 
		{
			apoly[0].x=spt.x-itwd;
			apoly[1].x=spt.x+itwd;
			apoly[2].x=ept.x+itwd;
			apoly[3].x=ept.x-itwd;
			apoly[0].y=spt.y-itwd;
			apoly[1].y=spt.y+itwd;
			apoly[2].y=ept.y+itwd;
			apoly[3].y=ept.y-itwd;
		};
		pRgns=new CRgn();
		pRgns->CreatePolygonRgn(apoly,4,ALTERNATE);
		pView->InvalidateRgn(pRgns);
	};
	delete pRgns;

}

void CBezier::CalForRot(CPoint &pt)
{
	movept=m_tCtlPt[Curpt];
	basept.x=290;
	basept.y=200;
	for (int i=0;i<4;i++)
	{
		double r=sqrt((m_tCtlPt[i].x-basept.x)*(m_tCtlPt[i].x-basept.x)+(m_tCtlPt[i].y-basept.y)*(m_tCtlPt[i].y-basept.y));
		m_RAry[i]=r;
		m_ptAry[i].x=m_tCtlPt[i].x;//在生成时单独计算可减少计算量
		m_ptAry[i].y=m_tCtlPt[i].y;
	};
}

CShape * CBezier::copys(TCHAR &ch)
{
	CBezier *b;
	b=new CBezier;
	for(int i=0;i<4;i++)
	{
		b->m_tCtlPt[i]=m_tCtlPt[i];
		b->m_tCtlPt[i].x+=10;
		b->m_tCtlPt[i].y+=10;
	};
	b->Curptnum=0;
	ch='B';
	return b;
}

⌨️ 快捷键说明

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