#include "stdafx.h" #include"CEllipse.h" #include"EastDrawView.h" IMPLEMENT_SERIAL(CEllipse,CUnit,1) void CEllipse::DrawStatic(CDC*pDC) { CPen m_pen; CBrush m_brush; int oldDrawingMode=pDC->SetROP2(this->m_DrawingMode); m_pen.CreatePen(m_PenStyle,m_PenWidth,m_PenColor); CPen* pen=(CPen*)pDC->SelectObject(&m_pen); LOGBRUSH brushlog; brushlog.lbColor=m_BrushColor; brushlog.lbHatch=m_BrushHatch; brushlog.lbStyle=m_BrushStyle; m_brush.CreateBrushIndirect(&brushlog); SetBrushOrg(pDC,&m_brush); CBrush*brush=(CBrush*)pDC->SelectObject(&m_brush); int OldBkMode=pDC->SetBkMode(m_BkMode); COLORREF OldColor=pDC->SetBkColor(m_BackgroundColor); ellipseMidpoint(pDC,m_CenterPoint.x,m_CenterPoint.y,this->m_Xr,this->m_Yr); pDC->SelectObject(brush); pDC->SelectObject(pen); pDC->SetBkMode(OldBkMode); pDC->SetBkColor(OldColor); pDC->SetROP2(oldDrawingMode); } void CEllipse::Serialize(CArchive &ar) { CUnit::Serialize(ar); if(ar.IsStoring()) { ar<>m_BrushStyle>>m_BkMode>>m_BrushHatch>>m_BrushColor; ar>>m_Sin>>m_Cos; ar>>m_Xr>>m_Yr; ar>>m_CenterPoint; } } BOOL CEllipse::IsInRgn(CPoint point) { double vh[3][3]={m_Cos,-m_Sin,m_CenterPoint.x*(1-m_Cos)+m_CenterPoint.y*m_Sin, m_Sin, m_Cos,m_CenterPoint.y*(1-m_Cos)-m_CenterPoint.x*m_Sin, 0,0,1 }; double xy[3]; CPoint point1=CPoint(m_CenterPoint.x-m_Xr,m_CenterPoint.y+m_Yr); CPoint point2=CPoint(m_CenterPoint.x+m_Xr,m_CenterPoint.y+m_Yr); CPoint point3=CPoint(m_CenterPoint.x+m_Xr,m_CenterPoint.y-m_Yr); CPoint point4=CPoint(m_CenterPoint.x-m_Xr,m_CenterPoint.y-m_Yr); CPoint point11=CPoint(m_CenterPoint.x-m_Xr/1.2,m_CenterPoint.y+m_Yr/1.2); CPoint point22=CPoint(m_CenterPoint.x+m_Xr/1.2,m_CenterPoint.y+m_Yr/1.2); CPoint point33=CPoint(m_CenterPoint.x+m_Xr/1.2,m_CenterPoint.y-m_Yr/1.2); CPoint point44=CPoint(m_CenterPoint.x-m_Xr/1.2,m_CenterPoint.y-m_Yr/1.2); CPoint pointList1[]={point1,point2,point3,point4}; CPoint pointList2[]={point11,point22,point33,point44}; for(int i=0;i<4;i++) { xy[0]=pointList1[i].x; xy[1]=pointList1[i].y; xy[2]=1; pointList1[i].x=vh[0][0]*xy[0]+vh[0][1]*xy[1]+vh[0][2]*xy[2]; pointList1[i].y=vh[1][0]*xy[0]+vh[1][1]*xy[1]+vh[1][2]*xy[2]; xy[0]=pointList2[i].x; xy[1]=pointList2[i].y; xy[2]=1; pointList2[i].x=vh[0][0]*xy[0]+vh[0][1]*xy[1]+vh[0][2]*xy[2]; pointList2[i].y=vh[1][0]*xy[0]+vh[1][1]*xy[1]+vh[1][2]*xy[2]; } CRgn rgn1; rgn1.CreatePolygonRgn(pointList1,4,ALTERNATE); CRgn rgn2; rgn2.CreatePolygonRgn(pointList2,4,ALTERNATE); if(rgn1.PtInRegion(point)&&!rgn2.PtInRegion(point)) return true; return false; } int CEllipse::IsOnMarginPoint(CPoint point) { CRect rect; for(int i=0;i<5;i++) { rect=CRect(this->m_MarginPoint[i],this->m_MarginPoint[i]); rect.InflateRect(4,4); if(rect.PtInRect(point)) { m_FoundPoint=this->m_MarginPoint[i]; return i+1; } } return 0; } void CEllipse::ellipseMidpoint(CDC*pDC,int xCenter, int yCenter, int Rx, int Ry) { int Rx2=Rx*Rx; int Ry2=Ry*Ry; int twoRx2=2*Rx2; int twoRy2=2*Ry2; int p; int x=0; int y=Ry; int px=0; int py=twoRx2*y; ellipsePlotPoints(pDC,xCenter,yCenter,x,y); p=ROUND(Ry2-(Rx2*Ry)+(0.25*Rx2)); while(px0) { y--; py-=twoRx2; if(p>0) p+=Rx2-py; else { x++; px+=twoRy2; p+=Rx2-py+px; } ellipsePlotPoints(pDC,xCenter,yCenter,x,y); } } void CEllipse::ellipsePlotPoints(CDC*pDC,int xCenter, int yCenter, int x, int y) { /* CPen m_pen; CBrush m_brush; int oldDrawingMode=pDC->SetROP2(this->m_DrawingMode); m_pen.CreatePen(m_PenStyle,m_PenWidth,m_PenColor); CPen* pen=(CPen*)pDC->SelectObject(&m_pen); LOGBRUSH brushlog; brushlog.lbColor=m_BrushColor; brushlog.lbHatch=m_BrushHatch; brushlog.lbStyle=m_BrushStyle; m_brush.CreateBrushIndirect(&brushlog); CBrush*brush=(CBrush*)pDC->SelectObject(&m_brush); int OldBkMode=pDC->SetBkMode(m_BkMode); COLORREF OldColor=pDC->SetBkColor(m_BackgroundColor); */ PdcSetPixel(pDC,xCenter+x,yCenter+y,m_PenColor); PdcSetPixel(pDC,xCenter-x,yCenter+y,m_PenColor); PdcSetPixel(pDC,xCenter+x,yCenter-y,m_PenColor); PdcSetPixel(pDC,xCenter-x,yCenter-y,m_PenColor); /* pDC->SelectObject(brush); pDC->SelectObject(pen); pDC->SetBkMode(OldBkMode); pDC->SetBkColor(OldColor); pDC->SetROP2(oldDrawingMode); */ } float CEllipse::ComputSloap(CPoint firstPoint, CPoint secondPoint) { m_SecondPoint=secondPoint; double sloap; if(firstPoint.x==secondPoint.x) { sloap=9999999999999.0; } else { sloap=double((firstPoint.y-secondPoint.y))/double((firstPoint.x-secondPoint.x)); } if(sloap<0) { m_Cos=fabs(sloap/sqrt(sloap*sloap+1.0)); m_Sin=1.0/sqrt(sloap*sloap+1.0); } else { m_Cos=fabs(sloap/sqrt(sloap*sloap+1.0)); m_Sin=-1.0/sqrt(sloap*sloap+1.0); } return 0; } void CEllipse::PdcSetPixel(CDC *pDC, int xCenter, int yCenter, COLORREF m_PenColor) { //xCenter+x,yCenter+y double vh[3][3]={m_Cos,-m_Sin,m_CenterPoint.x*(1-m_Cos)+m_CenterPoint.y*m_Sin, m_Sin, m_Cos,m_CenterPoint.y*(1-m_Cos)-m_CenterPoint.x*m_Sin, 0,0,1 }; double xy[3]={xCenter,yCenter,1}; double x[3]={0,0,0}; x[0]=vh[0][0]*xy[0]+vh[0][1]*xy[1]+vh[0][2]*xy[2]; x[1]=vh[1][0]*xy[0]+vh[1][1]*xy[1]+vh[1][2]*xy[2]; if(x[0]-int(x[0])>=0.5) x[0]+=1; if(x[1]-int(x[1])>=0.5) x[1]+=1; for(int i=0;im_PenWidth;i++) pDC->SetPixel(x[0]+i,x[1]-i,m_PenColor); //pDC->LineTo(x[0],x[1]); // pDC->LineTo(x[0]+1,x[1]-1); } int CEllipse::ComputRadiusX(CPoint firstPoint,CPoint secondPoint) { m_Xr=sqrt((firstPoint.x-secondPoint.x)*(firstPoint.x-secondPoint.x)+(firstPoint.y-secondPoint.y)*(firstPoint.y-secondPoint.y)); return 0; } int CEllipse::ComputRadiusY(CPoint firstPoint,CPoint secondPoint) { m_Yr=sqrt((firstPoint.x-secondPoint.x)*(firstPoint.x-secondPoint.x)+(firstPoint.y-secondPoint.y)*(firstPoint.y-secondPoint.y)); return 0; } void CEllipse::ShowMovingLine(CDC*pDC,CPoint firstPoint, CPoint secondPoint) { CPen m_pen; m_pen.CreatePen(PS_SOLID,1,RGB(0,0,255)); CPen *OldPen=pDC->SelectObject(&m_pen); pDC->MoveTo(firstPoint); pDC->LineTo(secondPoint); pDC->SelectObject(OldPen); } void CEllipse::ComputeOffSet() { double vh[3][3]={m_Cos,-m_Sin,m_CenterPoint.x*(1-m_Cos)+m_CenterPoint.y*m_Sin, m_Sin, m_Cos,m_CenterPoint.y*(1-m_Cos)-m_CenterPoint.x*m_Sin, 0,0,1 }; double xy1[3]={m_CenterPoint.x,m_CenterPoint.y,1}; m_OffSetX=vh[0][0]*xy1[0]+vh[0][1]*xy1[1]+vh[0][2]*xy1[2]; m_OffSetY=vh[1][0]*xy1[0]+vh[1][1]*xy1[1]+vh[1][2]*xy1[2]; } void CEllipse::ShowSelectPoint(CDC *pDC) { double vh[3][3]={m_Cos,-m_Sin,m_CenterPoint.x*(1-m_Cos)+m_CenterPoint.y*m_Sin, m_Sin, m_Cos,m_CenterPoint.y*(1-m_Cos)-m_CenterPoint.x*m_Sin, 0,0,1 }; double xy1[3]={-m_Xr+this->m_CenterPoint.x,this->m_CenterPoint.y,1}; this->m_MarginPoint[0].x=vh[0][0]*xy1[0]+vh[0][1]*xy1[1]+vh[0][2]*xy1[2]; this->m_MarginPoint[0].y=vh[1][0]*xy1[0]+vh[1][1]*xy1[1]+vh[1][2]*xy1[2]; double xy2[3]={this->m_CenterPoint.x,this->m_CenterPoint.y-m_Yr,1}; this->m_MarginPoint[1].x=vh[0][0]*xy2[0]+vh[0][1]*xy2[1]+vh[0][2]*xy2[2]; this->m_MarginPoint[1].y=vh[1][0]*xy2[0]+vh[1][1]*xy2[1]+vh[1][2]*xy2[2]; double xy3[3]={this->m_CenterPoint.x+m_Xr,this->m_CenterPoint.y,1}; this->m_MarginPoint[2].x=vh[0][0]*xy3[0]+vh[0][1]*xy3[1]+vh[0][2]*xy3[2]; this->m_MarginPoint[2].y=vh[1][0]*xy3[0]+vh[1][1]*xy3[1]+vh[1][2]*xy3[2]; double xy4[3]={this->m_CenterPoint.x,m_Yr+this->m_CenterPoint.y,1}; this->m_MarginPoint[3].x=vh[0][0]*xy4[0]+vh[0][1]*xy4[1]+vh[0][2]*xy4[2]; this->m_MarginPoint[3].y=vh[1][0]*xy4[0]+vh[1][1]*xy4[1]+vh[1][2]*xy4[2]; double xy5[3]={this->m_CenterPoint.x,this->m_CenterPoint.y,1}; this->m_MarginPoint[4].x=vh[0][0]*xy5[0]+vh[0][1]*xy5[1]+vh[0][2]*xy5[2]; this->m_MarginPoint[4].y=vh[1][0]*xy5[0]+vh[1][1]*xy5[1]+vh[1][2]*xy5[2]; CBrush brush; brush.CreateSolidBrush(RGB(0,0,255)); CPen m_pen; m_pen.CreatePen(PS_SOLID,1,RGB(0,0,255)); CPen *OldPen=pDC->SelectObject(&m_pen); int oldBkMode=pDC->SetBkMode(OPAQUE); CBrush *OldBrush=pDC->SelectObject(&brush); int oldDrawingMode=pDC->SetROP2(R2_NOTXORPEN); CRect rect; for(int i=0;i<4;i++) { rect.SetRect(this->m_MarginPoint[i],this->m_MarginPoint[i]); rect.InflateRect(3,3); pDC->Rectangle(rect); } pDC->SelectObject(OldBrush); brush.DeleteObject(); brush.CreateSolidBrush(RGB(255,0,0)); pDC->SelectObject(&brush); rect.SetRect(this->m_MarginPoint[4],this->m_MarginPoint[4]); rect.InflateRect(3,3); pDC->Rectangle(rect); pDC->SelectObject(OldPen); pDC->SetBkMode(oldBkMode); pDC->SelectObject(OldBrush); pDC->SetROP2(oldDrawingMode); } CRect CEllipse::GetBoundingRect() { double vh[3][3]={m_Cos,-m_Sin,m_CenterPoint.x*(1-m_Cos)+m_CenterPoint.y*m_Sin, m_Sin, m_Cos,m_CenterPoint.y*(1-m_Cos)-m_CenterPoint.x*m_Sin, 0,0,1 }; double xy1[3]={-m_Xr+this->m_CenterPoint.x,this->m_CenterPoint.y-m_Yr,1}; int left=vh[0][0]*xy1[0]+vh[0][1]*xy1[1]+vh[0][2]*xy1[2]; int top=vh[1][0]*xy1[0]+vh[1][1]*xy1[1]+vh[1][2]*xy1[2]; double xy2[3]={this->m_CenterPoint.x+m_Xr,this->m_CenterPoint.y-m_Yr,1}; int left2=vh[0][0]*xy2[0]+vh[0][1]*xy2[1]+vh[0][2]*xy2[2]; int top2=vh[1][0]*xy2[0]+vh[1][1]*xy2[1]+vh[1][2]*xy2[2]; double xy3[3]={this->m_CenterPoint.x+m_Xr,this->m_CenterPoint.y+m_Yr,1}; int right=vh[0][0]*xy3[0]+vh[0][1]*xy3[1]+vh[0][2]*xy3[2]; int bottom=vh[1][0]*xy3[0]+vh[1][1]*xy3[1]+vh[1][2]*xy3[2]; double xy4[3]={this->m_CenterPoint.x-m_Xr,m_Yr+this->m_CenterPoint.y,1}; int right2=vh[0][0]*xy4[0]+vh[0][1]*xy4[1]+vh[0][2]*xy4[2]; int bottom2=vh[1][0]*xy4[0]+vh[1][1]*xy4[1]+vh[1][2]*xy4[2]; int miny=min(min(top,top2),min(bottom,bottom2)); int minx=min(min(right,right2),min(left,left2)); int maxy=max(max(top,top2),max(bottom,bottom2)); int maxx=max(max(right,right2),max(left,left2)); m_BoundingRect.left=minx; m_BoundingRect.top=miny; m_BoundingRect.right=maxx; m_BoundingRect.bottom=maxy; return this->m_BoundingRect; } void CEllipse::DrawActive(CDC *pDC,CPoint point) { CPen m_pen; CBrush m_brush; m_pen.CreatePen(m_PenStyle,m_PenWidth,m_PenColor); CPen* pen=(CPen*)pDC->SelectObject(&m_pen); LOGBRUSH brushlog; brushlog.lbColor=m_BrushColor; brushlog.lbHatch=m_BrushHatch; brushlog.lbStyle=m_BrushStyle; m_brush.CreateBrushIndirect(&brushlog); SetBrushOrg(pDC,&m_brush); CBrush*brush=(CBrush*)pDC->SelectObject(&m_brush); int OldBkMode=pDC->SetBkMode(m_BkMode); COLORREF OldColor=pDC->SetBkColor(m_BackgroundColor); ellipseMidpoint(pDC,m_CenterPoint.x,m_CenterPoint.y,this->m_Xr,this->m_Yr); pDC->SelectObject(brush); pDC->SelectObject(pen); pDC->SetBkMode(OldBkMode); pDC->SetBkColor(OldColor); } void CEllipse::OnLButtonDown(CDC *pDC, CEastDrawView *pView, CPoint point) { if(m_HaveFindFirst) { pView->L_iPointCount=IsOnMarginPoint(point); if(pView->L_iPointCount!=0) { pView->m_bHaveFindSecond=true; pView->m_CurrentDrawTool=Ellipse_Tool; pView->m_CurrentDrawStatus=Change_Status; switch(pView->L_iPointCount) { case 1: pView->m_FirstPoint=m_SecondPoint; pView->m_SecondPoint=m_FirstPoint; break; case 2: pView->m_FirstPoint=m_FirstPoint; pView->m_SecondPoint=m_SecondPoint; break; case 3: pView->m_FirstPoint=m_FirstPoint; pView->m_SecondPoint=m_SecondPoint; break; case 4: pView->m_FirstPoint=m_SecondPoint; pView->m_SecondPoint=m_FirstPoint; break; case 5: pView->m_FirstPoint=m_FirstPoint; pView->m_SecondPoint=m_SecondPoint; pView->m_CurrentDrawTool=Ellipse_Tool; pView->m_CurrentDrawStatus=Drag_Status; break; } }//******if(L_iPointCount!=0) }//**********if(L_pEllipse->m_HaveFindFirst) if(!pView->m_bHaveFindSecond&&IsInRgn(point)) { if(!m_HaveFindFirst) { m_HaveFindFirst=true; pView->m_bHaveFindFirst=true; ShowSelectPoint(pDC); } else { m_HaveFindFirst=false; pView->m_bHaveFindFirst=true; ShowSelectPoint(pDC); } } if(pView->m_bHaveFindSecond) { pView->m_pCurrentUnit=this; m_DrawingMode=pDC->GetROP2(); DrawStatic(pDC); DrawOldReferencePoint(pDC,m_FoundPoint); ShowSelectPoint(pDC); } } void CEllipse::OnMouseMove(CDC *pDC, CEastDrawView *pView, CPoint point) { if(pView->m_CurrentDrawStatus==Drag_Status) { if(!m_IsCirCu) m_CenterPoint.Offset((pView->m_SecondPoint.x-pView->m_FirstPoint.x),(pView->m_SecondPoint.y-pView->m_FirstPoint.y)); if(m_IsCirCu) ComputSloap(m_CenterPoint,point); } else { //pDC->SetROP2(R2_NOTXORPEN); if(pView->m_LBDownTimes==2&&pView->m_CurrentDrawStatus!=Change_Status) { ShowMovingLine(pDC,m_CenterPoint,point); ellipseMidpoint(pDC,m_CenterPoint.x,m_CenterPoint.y,m_Xr,m_Yr); ComputRadiusX(m_CenterPoint,point); //m_DrawingMode=pDC->GetROP2(); pView->m_SecondPoint=point; ellipseMidpoint(pDC,m_CenterPoint.x,m_CenterPoint.y,m_Xr,m_Yr); ShowMovingLine(pDC,m_CenterPoint,point); } if(pView->m_CurrentDrawStatus==Change_Status) { ellipseMidpoint(pDC,m_CenterPoint.x,m_CenterPoint.y,m_Xr,m_Yr); ShowMovingLine(pDC,m_CenterPoint,pView->m_SecondPoint); pView->m_SecondPoint=point; if(pView->L_iPointCount==1||pView->L_iPointCount==3) ComputRadiusX(m_CenterPoint,point); if(pView->L_iPointCount==2||pView->L_iPointCount==4) ComputRadiusY(m_CenterPoint,point); //m_DrawingMode=pDC->GetROP2(); ShowMovingLine(pDC,m_CenterPoint,point); ellipseMidpoint(pDC,m_CenterPoint.x,m_CenterPoint.y,m_Xr,m_Yr); } if(pView->m_LBDownTimes==1&&pView->m_CurrentDrawStatus!=Change_Status) { ShowMovingLine(pDC,pView->m_FirstPoint,pView->m_SecondPoint); pView->m_SecondPoint=point; ShowMovingLine(pDC,pView->m_FirstPoint,point); } } } void CEllipse::OnMenuitemCirCu(CDC *pDC, CEastDrawView *pView) { m_IsCirCu=!m_IsCirCu; } CEllipse::CEllipse() { CUnit::Initial(); m_IsCirCu=false; } void CEllipse::OnContextMenu(CWnd *pWnd, CPoint point) { CEastDrawView*pView=(CEastDrawView*)pWnd; if(pView->m_CurrentDrawStatus==Drag_Status) { CMenu menuTextEdit; menuTextEdit.LoadMenu(IDR_MENU_Canvas_Edit); menuTextEdit.CheckMenuItem(ID_CirCu,m_IsCirCu?MF_CHECKED:MF_UNCHECKED); menuTextEdit.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN,point.x,point.y,pWnd); } }