www.pudn.com > 44757463.rar > Circle.cpp
// Circle.cpp: implementation of the CCircle class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "GraphSoft.h"
#include "Circle.h"
#include "GlobalFunction.h"
#include "math.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
///////////////////////////////////
IMPLEMENT_SERIAL( CCircle, CShape, 0 )
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
CCircle::CCircle():CShape()
{
m_flRadiusTemp=m_flRadius=0;
m_flCenterxTemp=m_flCenterx=0;
m_flCenteryTemp=m_flCentery=0;
}
CCircle::CCircle(COLORREF color,int penWidth,float angle):CShape(color,penWidth,angle)
{
m_flRadiusTemp=m_flRadius=0;
m_flCenterxTemp=m_flCenterx=0;
m_flCenteryTemp=m_flCentery=0;
}
CCircle::CCircle(CCircle * const pCircle):CShape(pCircle)
{
m_flRadius=pCircle->m_flRadius;
m_flCenterx=pCircle->m_flCenterx;
m_flCentery=pCircle->m_flCentery;
//
m_flRadiusTemp=pCircle->m_flRadiusTemp;
m_flCenterxTemp=pCircle->m_flCenterxTemp;
m_flCenteryTemp=pCircle->m_flCenteryTemp;
}
CCircle::~CCircle()
{
}
//////////////////////////////////////////////////////////////////////////
void CCircle::Serialize( CArchive& ar)
{
CShape::Serialize( ar ) ;
if ( ar.IsLoading() ){
ar>>m_flRadius;
ar>>m_flCenterx;
ar>>m_flCentery;
//temp
m_flRadiusTemp=m_flRadius;
m_flCenterxTemp=m_flCenterx;
m_flCenteryTemp=m_flCentery;
} else {
ar<SelectObject(&pen);
if(m_nFillStyle==_shape_solid_fill){
FillBreCircle(pDC,ptCenter,m_flRadiusTemp,penWidth);
}
pen.DeleteObject();
pen.CreatePen(PS_SOLID,penWidth, color);
pDC->SelectObject(&pen);
//CBrush brush ;
//brush.CreateSolidBrush(::GetSysColor(COLOR_3DFACE)) ;
//CBrush* pOldBrush = (CBrush*) pDC->SelectObject(&brush);
BreCircle(pDC,ptCenter,m_flRadiusTemp,color,penWidth);
if(GetDrawPointsFlag()==1){
DrawPoints(pDC,color);
}
pDC->SelectObject(poldPen);
//pDC->SelectObject(pOldBrush);
}
///////////////////////////////////////////
void CCircle::DrawPointsCutTo(CDC *pDC,COLORREF color,CFlRect m_rectFrom,CRect m_rectTo)
{
if(!IsInRect(m_rectFrom)){
return;
}
//得到移动扩缩后的关键数据
float flCx,flCy,flR;
//移动
float stepx=m_rectTo.left-m_rectFrom.left;
float stepy=m_rectTo.top-m_rectFrom.top;
flCx=m_flCenterxTemp+stepx;
flCy=m_flCenteryTemp+stepy;
flR=m_flRadiusTemp;
//扩缩
float cx,cy,flScale;
cx=m_rectTo.left;
cy=m_rectTo.top;
if(m_rectFrom.Width()<0.01){
m_rectFrom.right=m_rectFrom.left +1;
}
if(m_rectFrom.Height()<0.01){
m_rectFrom.bottom=m_rectFrom.top +1;
}
flScale=(float)m_rectTo.Width()/m_rectFrom.Width();
// flScale=min((float)m_rectTo.Width()/m_rectFrom.Width(),(float)m_rectTo.Height()/m_rectFrom.Height());
flR=flR*flScale;
flCx=(flCx-cx)*flScale+cx;
flCy=(flCy-cy)*flScale+cy;
CPen pen,*poldPen;
pen.CreatePen(PS_SOLID,1, color);
poldPen=pDC->SelectObject(&pen);
{
pDC->MoveTo(flCx,flCy-1-GetPenWidth());
pDC->LineTo(flCx,flCy+2+GetPenWidth());
pDC->MoveTo(flCx-1-GetPenWidth(),flCy);
pDC->LineTo(flCx+2+GetPenWidth(),flCy);
}
pDC->SelectObject(poldPen);
return;
}
void CCircle::DrawPoints(CDC *pDC,COLORREF color)
{
CPen pen,*poldPen;
pen.CreatePen(PS_SOLID,1, color);
poldPen=pDC->SelectObject(&pen);
{
pDC->MoveTo(m_flCenterxTemp,m_flCenteryTemp-1-GetPenWidth());
pDC->LineTo(m_flCenterxTemp,m_flCenteryTemp+2+GetPenWidth());
pDC->MoveTo(m_flCenterxTemp-1-GetPenWidth(),m_flCenteryTemp);
pDC->LineTo(m_flCenterxTemp+2+GetPenWidth(),m_flCenteryTemp);
}
pDC->SelectObject(poldPen);
return;
}
///////////////////////////////
void CCircle::DrawCutToRect(CDC *pDC,COLORREF color,COLORREF fillColor,int penWidth,CFlRect m_rectFrom,CRect m_rectTo)
{
// if(!IsInRect(m_rectFrom)){
// return;
// }
//得到移动扩缩后的关键数据
float flCx,flCy,flR;
//移动
float stepx=m_rectTo.left-m_rectFrom.left;
float stepy=m_rectTo.top-m_rectFrom.top;
flCx=m_flCenterxTemp+stepx;
flCy=m_flCenteryTemp+stepy;
flR=m_flRadiusTemp;
//扩缩
float cx,cy,flScale;
cx=m_rectTo.left;
cy=m_rectTo.top;
if(m_rectFrom.Width()<0.01){
m_rectFrom.right=m_rectFrom.left +1;
}
if(m_rectFrom.Height()<0.01){
m_rectFrom.bottom=m_rectFrom.top +1;
}
flScale=(float)m_rectTo.Width()/m_rectFrom.Width();
// flScale=min((float)m_rectTo.Width()/m_rectFrom.Width(),(float)m_rectTo.Height()/m_rectFrom.Height());
flR=flR*flScale;
flCx=(flCx-cx)*flScale+cx;
flCy=(flCy-cy)*flScale+cy;
//Draw
CPen pen,*poldPen;
CPoint ptCenter(flCx,flCy);
pen.CreatePen(PS_SOLID,1, fillColor);
poldPen=pDC->SelectObject(&pen);
if(m_nFillStyle==_shape_solid_fill){
FillBreCircle(pDC,ptCenter,flR,penWidth);
}
pen.DeleteObject();
pen.CreatePen(PS_SOLID,penWidth, color);
pDC->SelectObject(&pen);
BreCircle(pDC,ptCenter,flR,color,penWidth);
if(GetDrawPointsFlag()==1){
DrawPointsCutTo(pDC,color,m_rectFrom,m_rectTo);
}
pDC->SelectObject(poldPen);
}
//
void CCircle::BreCircle(CDC *pDC,CPoint m_pCenter,int nRadius,COLORREF color,int nPenWidth)
{
int x,y,xc,yc,r,di,i;
xc=m_pCenter.x;
yc=m_pCenter.y;
x=xc+nRadius;
y=yc;
r=nRadius;
x=0;
y=r;
di=3-2*r;
float flX[8],flY[8];
flX[0]=xc+x;
flX[1]=xc+x;
flX[2]=xc-x;
flX[3]=xc-x;
flX[4]=xc+y;
flX[5]=xc+y;
flX[6]=xc-y;
flX[7]=xc-y;
flY[0]=yc+y;
flY[1]=yc-y;
flY[2]=yc+y;
flY[3]=yc-y;
flY[4]=yc+x;
flY[5]=yc-x;
flY[6]=yc+x;
flY[7]=yc-x;
i=0;
while(x<=y)
{
i++;
// for(i=0;iMoveTo(flX[0],flY[0]);
pDC->LineTo(xc+x,yc+y);
pDC->MoveTo(flX[1],flY[1]);
pDC->LineTo(xc+x,yc-y);
pDC->MoveTo(flX[2],flY[2]);
pDC->LineTo(xc-x,yc+y);
pDC->MoveTo(flX[3],flY[3]);
pDC->LineTo(xc-x,yc-y);
pDC->MoveTo(flX[4],flY[4]);
pDC->LineTo(xc+y,yc+x);
pDC->MoveTo(flX[5],flY[5]);
pDC->LineTo(xc+y,yc-x);
pDC->MoveTo(flX[6],flY[6]);
pDC->LineTo(xc-y,yc+x);
pDC->MoveTo(flX[7],flY[7]);
pDC->LineTo(xc-y,yc-x);
flX[0]=xc+x;
flX[1]=xc+x;
flX[2]=xc-x;
flX[3]=xc-x;
flX[4]=xc+y;
flX[5]=xc+y;
flX[6]=xc-y;
flX[7]=xc-y;
flY[0]=yc+y;
flY[1]=yc-y;
flY[2]=yc+y;
flY[3]=yc-y;
flY[4]=yc+x;
flY[5]=yc-x;
flY[6]=yc+x;
flY[7]=yc-x;
i=0;
}
if(di<0)
{
di+=4*x+6;
}
else
{
di+=4*(x-y)+10;
y--;
}
x++;
}
pDC->MoveTo(flX[0],flY[0]);
pDC->LineTo(xc+x,yc+y);
pDC->MoveTo(flX[1],flY[1]);
pDC->LineTo(xc+x,yc-y);
pDC->MoveTo(flX[2],flY[2]);
pDC->LineTo(xc-x,yc+y);
pDC->MoveTo(flX[3],flY[3]);
pDC->LineTo(xc-x,yc-y);
pDC->MoveTo(flX[4],flY[4]);
pDC->LineTo(xc+y,yc+x);
pDC->MoveTo(flX[5],flY[5]);
pDC->LineTo(xc+y,yc-x);
pDC->MoveTo(flX[6],flY[6]);
pDC->LineTo(xc-y,yc+x);
pDC->MoveTo(flX[7],flY[7]);
pDC->LineTo(xc-y,yc-x);
}
///////////
void CCircle::FillBreCircle(CDC *pDC,CPoint ptCenter,int flRadius,int penWidth)
{
int x,y,xc,yc,r,di,i;
xc=ptCenter.x;
yc=ptCenter.y;
x=xc+flRadius;
y=yc;
r=flRadius;
x=0;
y=r;
di=3-2*r;
while(x<=y)
{
pDC->MoveTo(xc+x,yc+y);
pDC->LineTo(xc+x,yc-y);
pDC->MoveTo(xc+y,yc+x);
pDC->LineTo(xc+y,yc-x);
pDC->MoveTo(xc-x,yc+y);
pDC->LineTo(xc-x,yc-y);
pDC->MoveTo(xc-y,yc+x);
pDC->LineTo(xc-y,yc-x);
if(di<0)
{
di+=4*x+6;
}
else
{
di+=4*(x-y)+10;
y-=1;
}
x+=1;
}
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
void CCircle::RefreshData(bool bRefresh)
{
if(bRefresh){
m_flRadius=m_flRadiusTemp;
m_flCenterx=m_flCenterxTemp;
m_flCentery=m_flCenteryTemp;
m_bModified=FALSE;
m_ptMagnifyCenterTemp=CPoint(0,0);
m_flScaleTemp=1;
m_ptRotateCenterTemp=CPoint(0,0);
m_flAngleTemp=0;
}
}
void CCircle::CreatGraph(CArray& flArrayX,CArray& flArrayY,int nPenWidth,COLORREF color,COLORREF fillColor,SHAPE_FILLSTYLE nStyle)
{
if(flArrayX.GetSize()<2){
return;
}
CShape::CreatGraph(flArrayX,flArrayY,nPenWidth,color,fillColor,nStyle);
m_flRadiusTemp=m_flRadius=GetDistance(flArrayX.GetAt(0),flArrayY.GetAt(0),flArrayX.GetAt(1),flArrayY.GetAt(1));
m_flCenterx=m_flCenterxTemp=flArrayX.GetAt(0);
m_flCentery=m_flCenteryTemp=flArrayY.GetAt(0);
TRACE("m_flRadius=%f\n",m_flRadius);
return;
}
void CCircle::CreatGraph(CArray& ptArray,int nPenWidth,COLORREF color,COLORREF fillColor,SHAPE_FILLSTYLE nStyle)
{
if(ptArray.GetSize()<2){
return;
}
CShape::CreatGraph(ptArray,nPenWidth,color,fillColor,nStyle);
m_flRadiusTemp=m_flRadius=GetDistance(ptArray.GetAt(0),ptArray.GetAt(1));
m_flCenterx=m_flCenterxTemp=((CPoint)ptArray.GetAt(0)).x;
m_flCentery=m_flCenteryTemp=((CPoint)ptArray.GetAt(0)).y;
return;
}
// 特殊化处理,第二个点x值保存半径长度
void CCircle::SetPtData(CArray& flArrayX,CArray& flArrayY)
{
m_flCenterx=m_flCenterxTemp=((float)flArrayX.GetAt(0));
m_flCentery=m_flCenteryTemp=((float)flArrayY.GetAt(0));
m_flRadius=m_flRadiusTemp=flArrayX.GetAt(1);
}
// 特殊化处理,第二个点x值保存半径长度
void CCircle::GetPtData(CArray& flArrayX,CArray& flArrayY)
{
flArrayX.RemoveAll();
flArrayY.RemoveAll();
flArrayX.Add(m_flCenterxTemp);
flArrayX.Add(m_flRadiusTemp);
flArrayY.Add(m_flCenteryTemp);
flArrayY.Add(m_flRadiusTemp);
}
CShape* CCircle::GetCopy()
{
CShape* pGraph=new CCircle(this);
return pGraph;
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
void CCircle::Move(CDC *pDC,float stepx,float stepy)
{
RefreshData(m_bModified);
// CShape::Draw(pDC,RGB(255,255,255),RGB(255,255,255));
m_flCenterx+=stepx;
m_flCentery+=stepy;
//temp
m_flCenterxTemp+=stepx;
m_flCenteryTemp+=stepy;
}
void CCircle::PartMove(CDC *pDC,float PrevX,float PrevY,float CurX,float CurY)
{
RefreshData(m_bModified);
if(m_nSelectPtNum==1){
// CShape::Draw(pDC,RGB(255,255,255),RGB(255,255,255));
m_flRadiusTemp=GetDistance(CurX,CurY,m_flCenterxTemp,m_flCenteryTemp);
m_flRadius=m_flRadiusTemp;
m_flRadiusTemp=GetDistance(CurX,CurY,m_flCenterxTemp,m_flCenteryTemp);
m_flRadius=m_flRadiusTemp;
// CShape::Draw(pDC);
}else if(m_nSelectPtNum==0){
// CShape::Draw(pDC,RGB(255,255,255),RGB(255,255,255));
m_flCenterxTemp=CurX;
m_flCenteryTemp=CurY;
m_flCenterx=CurX;
m_flCentery=CurY;
// CShape::Draw(pDC);
}
}
void CCircle::Rotate(CDC *pDC,float CX,float CY,float flAngle)
{
if(m_flScaleTemp!=1){
RefreshData(TRUE);
}
// CShape::Draw(pDC,RGB(255,255,255),RGB(255,255,255));
m_ptRotateCenterTemp=CPoint(CX,CY);
m_flAngleTemp=flAngle;
m_bModified=TRUE;
m_flCenterxTemp=((m_flCenterx-CX)*cos(flAngle)-(m_flCentery-CY)*sin(flAngle))+CX;
m_flCenteryTemp=((m_flCentery-CY)*cos(flAngle)+(m_flCenterx-CX)*sin(flAngle))+CY;
}
void CCircle::Magnify(CDC *pDC,float CX,float CY,float flScale)
{
if(m_flAngleTemp!=0){
RefreshData(TRUE);
}
// CShape::Draw(pDC,RGB(255,255,255),RGB(255,255,255));
m_ptMagnifyCenterTemp=CPoint(CX,CY);
m_flScaleTemp=flScale;
m_bModified=TRUE;
m_flCenterxTemp=(m_flCenterx-CX)*flScale+CX;
m_flCenteryTemp=(m_flCentery-CY)*flScale+CY;
m_flRadiusTemp=m_flRadius*flScale;
}
void CCircle::TopToBottom(CDC* pDC,CRect rect)
{
RefreshData(m_bModified);
// CShape::Draw(pDC,RGB(255,255,255),RGB(255,255,255));
m_flCenteryTemp=rect.top/1000.0+rect.bottom/1000.0-m_flCenteryTemp;
m_flCentery=rect.top/1000.0+rect.bottom/1000.0-m_flCentery;
// CShape::Draw(pDC);
}
void CCircle::LeftToRight(CDC* pDC,CRect rect)
{
RefreshData(m_bModified);
// CShape::Draw(pDC,RGB(255,255,255),RGB(255,255,255));
m_flCenterxTemp=rect.left/1000.0+rect.right/1000.0-m_flCenterxTemp;
m_flCenterx=rect.left/1000.0+rect.right/1000.0-m_flCenterx;
// CShape::Draw(pDC);
}
///
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
int CCircle::IsInRect(CRect rect)
{
int nRltVal=0;
CPoint ptRectLT=rect.TopLeft();
CPoint ptRectRB=rect.BottomRight();
CPoint ptRectLB,ptRectRT;
ptRectLB.x=rect.left;
ptRectLB.y=rect.bottom;
ptRectRT.x=rect.right;
ptRectRT.y=rect.top;
CPoint ptCircleCenter(m_flCenterxTemp,m_flCenteryTemp);
//求四条矩形边是否有和圆相交/在圆内
float flX[4][2],flY[4][2];
flY[0][0]=rect.top;
flY[1][0]=rect.bottom;
flY[0][1]=rect.top;
flY[1][1]=rect.bottom;
if(rect.left>m_flCenterxTemp){
flX[0][0]=rect.left;
flX[1][0]=rect.left;
flX[0][1]=rect.right;
flX[1][1]=rect.right;
}else if(rect.right rect.right-m_flCenterxTemp){
flX[0][1]=rect.left;
flX[1][1]=rect.left;
}else{
flX[0][1]=rect.right;
flX[1][1]=rect.right;
}
}
flX[2][0]=rect.left;
flX[3][0]=rect.right;
flX[2][1]=rect.left;
flX[3][1]=rect.right;
if(rect.top>m_flCenteryTemp){
flY[2][0]=rect.top;
flY[3][0]=rect.top;
flY[2][1]=rect.bottom;
flY[3][1]=rect.bottom;
}else if(rect.bottom rect.bottom-m_flCenteryTemp){
flX[2][1]=rect.top;
flX[3][1]=rect.top;
}else{
flX[2][1]=rect.bottom;
flX[3][1]=rect.bottom;
}
}
int flag=0;
if(GetDistance(flX[0][0],flY[0][0],m_flCenterxTemp,m_flCenteryTemp)<=m_flRadiusTemp){
if(GetDistance(flX[0][1],flY[0][1],m_flCenterxTemp,m_flCenteryTemp)>m_flRadiusTemp){
nRltVal|=1;//cut
}else{
nRltVal|=2;
}
}else{
flag++;
}
if(GetDistance(flX[1][0],flY[1][0],m_flCenterxTemp,m_flCenteryTemp)<=m_flRadiusTemp){
if(GetDistance(flX[1][1],flY[1][1],m_flCenterxTemp,m_flCenteryTemp)>m_flRadiusTemp){
nRltVal|=1;//cut
}else{
nRltVal|=2;
}
}else{
flag++;
}
if(GetDistance(flX[2][0],flY[2][0],m_flCenterxTemp,m_flCenteryTemp)<=m_flRadiusTemp){
if(GetDistance(flX[2][1],flY[2][1],m_flCenterxTemp,m_flCenteryTemp)>m_flRadiusTemp){
nRltVal|=1;//cut
}else{
nRltVal|=2;
}
}else{
flag++;
}
if(GetDistance(flX[3][0],flY[3][0],m_flCenterxTemp,m_flCenteryTemp)<=m_flRadiusTemp){
if(GetDistance(flX[3][1],flY[3][1],m_flCenterxTemp,m_flCenteryTemp)>m_flRadiusTemp){
nRltVal|=1;//cut
}else{
nRltVal|=2;
}
}else{
flag++;
}
if(nRltVal==3){
nRltVal=1;
}
if(nRltVal==2&&m_nFillStyle==_shape_none_fill){
nRltVal=0;
}
if(flag==4&&rect.PtInRect(ptCircleCenter)){
nRltVal=2;
}
return nRltVal;
}
CRect CCircle::GetBoundaryRect()
{
CRect rect;
rect.left=1000*(m_flCenterxTemp-m_flRadiusTemp);
rect.right=1000*(m_flCenterxTemp+m_flRadiusTemp);
rect.top=1000*(m_flCenteryTemp-m_flRadiusTemp);
rect.bottom=1000*(m_flCenteryTemp+m_flRadiusTemp);
return rect;
}
CPoint CCircle::GetCenterPoint()
{
CPoint ptCenter(m_flCenterxTemp,m_flCenteryTemp);
return ptCenter;
}
int CCircle::IsPointinRegion(POINT point)
{
CPoint ptCenter(m_flCenterxTemp,m_flCenteryTemp);
if(GetDistance(ptCenter,point)>m_flRadiusTemp)
return 0;
return 1;
}
//////
int CCircle::GetPtState(float flx,float fly,float flRate)
{
CPoint ptCenter(m_flCenterxTemp,m_flCenteryTemp);
if(fabs(GetDistance(m_flCenterxTemp,m_flCenteryTemp,flx,fly)-m_flRadiusTemp) <= 3.0*flRate)
{
m_nSelectPtNum=1;
return 1;
}
if(IsPtInRect(m_flCenterxTemp-3*flRate,m_flCenteryTemp-3*flRate,m_flCenterxTemp+3*flRate,m_flCenteryTemp+3*flRate,flx,fly)){
m_nSelectPtNum=0;
return 1;
}
m_nSelectPtNum=-1;
return 0;
}
//////////////////////////////////////////////////////////////////////
// MODULE :ExPort
// ABSTRACT :Export to a txt file
// FUNCTION :File->Export...
// NOTE :
// RETURN :
// ARGUMENTS:
// I/O TYPE NAME EXPLANATION
// O FILE* outStream Out put File
// CREATE : FNST)handwolf 2004-4-14
// UPDATE :
// :
//////////////////////////////////////////////////////////////////////
void CCircle::ExPort(FILE* outStream)//增加导出txt功能时用
{
fprintf(outStream, " CCircle \n");
CShape::ExPort(outStream);
fprintf( outStream, " %f %f %f \n",m_flRadius,m_flCenterx,m_flCentery);
}
//////////////////////////////////////////////////////////////////////
// MODULE :ImPort
// ABSTRACT :ImPort from a txt file
// FUNCTION :File->ImPort...
// NOTE :
// RETURN :
// ARGUMENTS:
// I/O TYPE NAME EXPLANATION
// I FILE* inStream in put File
// CREATE : FNST)handwolf 2004-4-14
// UPDATE :
// :
//////////////////////////////////////////////////////////////////////
void CCircle::ImPort(FILE* inStream)
{
CShape::ImPort(inStream);
fscanf(inStream, "%f %f %f",&m_flRadius,&m_flCenterx,&m_flCentery);
m_flRadiusTemp=m_flRadius;
m_flCenterxTemp=m_flCenterx;
m_flCenteryTemp=m_flCentery;
}
CString CCircle::GetNameString()
{
CString str;
str.LoadString(IDS_CIRCLE);
return str;
}
//////////////////////////////////////////////////////////////////////
//End of File////////////////
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////