📄 bezier.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 + -