MFC按指定的数据绘制极坐标,高中的三角函数放大招呢~
void CDrawPoleCoordinateDlg::OnBnClickedButton1() { /**************************可调整的数值******************************/ float angle = 30;//每个扇形的角度 int radius = 300;//半径 int step = 30;//每一环的相隔距离 CPoint center(radius+200,radius+50);//圆心 int radiusScale = 100;//半径的刻度 /*********************************************************************/ /*************************测试数据*********************************/ std::list<PoparValue> list ; PoparValue p(40,27); list.push_back(p); PoparValue p2(70,60); list.push_back(p2); PoparValue p3(80,90); list.push_back(p3); PoparValue p4(66,200); list.push_back(p4); PoparValue p5(30,255); list.push_back(p5); /*************************测试数据*********************************/ CDC *pDC = GetDC(); //绘制同心圆 int myRadius = 0; int num = 0; for(int i = 0;i<radius;i+=step){ myRadius = radius - i; if(num%2==0){ CPen myPen5; myPen5.CreatePen(PS_SOLID,1,RGB(180,180,180)); pDC->SelectObject(myPen5); pDC->Ellipse(center.x-myRadius,center.y-myRadius,center.x+myRadius,center.y+myRadius); }else{ CPen myPen6; myPen6.CreatePen(PS_DOT,1,RGB(220,220,220)); pDC->SelectObject(myPen6); pDC->Ellipse(center.x-myRadius,center.y-myRadius,center.x+myRadius,center.y+myRadius); } if(i==0){ CPen myPen5; myPen5.CreatePen(PS_SOLID,1,RGB(0,0,0)); pDC->SelectObject(myPen5); pDC->Ellipse(center.x-myRadius,center.y-myRadius,center.x+myRadius,center.y+myRadius); } num++; } CPen myPen2; myPen2.CreatePen(PS_SOLID,1,RGB(180,180,180)); pDC->SelectObject(myPen2); //绘制分格 for(float i = 0;i<360;){ pDC->MoveTo(center); float x = (float)(radius*cos(i*PI/180))+center.x; float y = (float)(radius*sin(i*PI/180))+center.y; pDC->LineTo(CPoint((int)x,(int)y)); //调整度数的位置 CString str; str.Format(_T("%0.0f"),i); str = str + L"°"; if(i>=0 && i<=45) pDC->TextOutW(x,y,str); else if(i>45 && i<=90) pDC->TextOutW(x-(5+sin(i*PI/180)),y,str); else if(i>90 && i<=135) pDC->TextOutW(x-(35-sin(i*PI/180)),y+(4-sin(i*PI/180)),str); else if(i>135 && i<=180) pDC->TextOutW(x-(40-sin(i*PI/180)),y,str); else if(i>180 && i<=225) pDC->TextOutW(x-(40-sin(i*PI/180)),y-(10-sin(i*PI/180)),str); else if(i>225 && i<=270) pDC->TextOutW(x-(20+sin(i*PI/80)),y-(20+cos(i*PI/180)),str); else if(i>270 && i<=315) pDC->TextOutW(x-(5+cos(i*PI/180)),y-(15+cos(i*PI/180)),str); else if(i>315 && i<=360) pDC->TextOutW(x+(5+sin(i*PI/180)),y-(10+sin(i*PI/180)),str); i +=angle; } CString CRadiusScale; CRadiusScale.Format(_T("%d"),radiusScale); //显示半径刻度 pDC->TextOutW(center.x-radius-50,center.y-radius+90,L"半径长度值: "+CRadiusScale); //每环相隔距离 CString CStep; CStep.Format(_T("%d"),step); pDC->TextOutW(center.x-radius-50,center.y-radius+40,L"每环相隔距离: "+CStep); //显示圆心位置 CString Cx; Cx.Format(_T("%ld"),center.x); CString Cy; Cy.Format(_T("%ld"),center.y); pDC->TextOutW(center.x-radius-50,center.y-radius-10,L"圆心:("+Cx+L","+Cy+L")"); CString CAangle; CAangle.Format(_T("%0.0f"),angle); //扇形角度 pDC->TextOutW(center.x-radius-50,center.y-radius+65,L"扇形角度: "+CAangle); //显示半径 CString CRadius; CRadius.Format(_T("%d"),radius); pDC->TextOutW(center.x-radius-50,center.y-radius+15,L"半径: "+CRadius); std::list<PoparValue>::iterator ite; CPen myPen3; myPen3.CreatePen(PS_SOLID,2,RGB(255,0,0)); pDC->SelectObject(myPen3); //绘制点 for(ite = list.begin();ite!=list.end();ite++){ Point myPoint = getPointPosition(ite->ang*radius/radiusScale,ite->val,center); pDC->Ellipse(int(myPoint.x-2),int(myPoint.y-2),int(myPoint.x+2),int(myPoint.y+2)); } std::list<PoparValue>::iterator current = list.begin(); std::list<PoparValue>::iterator previous = list.begin(); //连线 CPen myPen4; myPen4.CreatePen(PS_SOLID,1,RGB(255,97,10)); pDC->SelectObject(myPen4); while(current!=list.end()){ Point bPoint = getPointPosition(previous->ang*radius/radiusScale,previous->val,center); CPoint begin; begin.x = bPoint.x; begin.y = bPoint.y; pDC->MoveTo(begin); current++; if(current!=list.end()){ Point bPoint = getPointPosition(current->ang*radius/radiusScale,current->val,center); CPoint begin; begin.x = bPoint.x; begin.y = bPoint.y; pDC->LineTo(begin); } previous = current; } ReleaseDC(pDC); }
绘制效果:
改进版:(增加了刻度并封装成了c++对象,并所有的成员变量可get、set)
效果图:
.h文件代码:
#include "stdafx.h" #include <math.h> #include <map> #include <stdio.h> #include <stdlib.h> #define PI 3.1415926 class PoleCoordinate { public: PoleCoordinate(){ this->scaleModel = 1; this->infoModel = 1; this->pointColour.rgbtRed = 255; this->pointColour.rgbtGreen = 0; this->pointColour.rgbtBlue = 0; this->lineColour.rgbtRed = 255; this->lineColour.rgbtGreen = 97; this->lineColour.rgbtBlue = 10; this->spokeColour.rgbtRed = 180; this->spokeColour.rgbtGreen = 180; this->spokeColour.rgbtBlue = 180; this->ringSolidColour.rgbtRed = 180; this->ringSolidColour.rgbtGreen = 180; this->ringSolidColour.rgbtBlue = 180; this->ringDotColour.rgbtRed = 220; this->ringDotColour.rgbtGreen = 220; this->ringDotColour.rgbtBlue = 220; this->ringOuterColour.rgbtRed = 0; this->ringOuterColour.rgbtGreen = 0; this->ringOuterColour.rgbtBlue = 0; this->coordinateRadius = 250; this->center = CPoint(500,300); this->step = 50; this->fanAngle = 30; this->radiusScale = 100; this->pointMap.insert(std::pair<float,int>(0.0f,60)); this->pointMap.insert(std::pair<float,int>(180.0f,60)); this->pointMap.insert(std::pair<float,int>(270.0f,80)); this->pointMap.insert(std::pair<float,int>(360.0f,60)); this->pointMap.insert(std::pair<float,int>(90.0f,0)); this->lineWidth = 2; } private: short scaleModel;// 1 = 只显示实线环刻度,2 = 只显示虚线环刻度, 3 = 显示全部刻度,,0 = 不显示刻度 默认1 short infoModel;// 1 = 显示图形参数信息,0 = 不显示图形参数信息 默认1 CPoint infoPosition;// 图形参数信息显示位置,默认 (center.x-coordinateRadius-100,center.y-coordinateRadius-25) RGBTRIPLE pointColour ;// 数据点颜色 默认(255,0,0) RGBTRIPLE lineColour; // 绘制线条的颜色 默认(255,97,10) byte lineWidth;//绘制线条的粗细 默认 2 RGBTRIPLE spokeColour; // 辐条颜色 默认(180,180,180) RGBTRIPLE ringSolidColour;// 实线圆环颜色 默认(180,180,180) RGBTRIPLE ringDotColour;// 虚线圆环颜色 默认(220,220,220) RGBTRIPLE ringOuterColour;//外圈圆环颜色 默认(0,0,0) int coordinateRadius; //半径 默认250 CPoint center;//中心点 默认(coordinateRadius+300,coordinateRadius+100) int step ;// 每环相隔距离 默认50 float fanAngle; //扇形角度 默认30 int radiusScale; // 半径长度值 默认100 std::map<float,int> pointMap; //点数据 map<角度,值> void setPositionOffset(CDC *pDC,int j); public: int toDraw(CDC *pDC); CPoint getPointPosition(int value,float angle,CPoint center); void setScaleModel(short); short getScaleModel(); void setInfoModel(short); short getInfoModel(); void setInfoPosition(int x,int y); CPoint getInfoPosition(); void setPointColour(byte,byte,byte); RGBTRIPLE getPointColour(); void setLineColour(byte,byte,byte); RGBTRIPLE getLineColour(); void setSpokeColour(byte,byte,byte); RGBTRIPLE getSpokeColour(); void setRingSolidColour(byte,byte,byte); RGBTRIPLE getRingSolidColour(); void setRingDotColour(byte,byte,byte); RGBTRIPLE getRingDotColour(); void setRingOuterColour(byte,byte,byte); RGBTRIPLE getRingOuterColour(); void setCoordinateRadius(int); int getCoordinateRadius(); void setCenter(CPoint); CPoint getCenter(); void setStep(int); int getStep(); void setFanAngle(float); float getFanAngle(); void setRadiusScale(int); int getRadiusScale(); void setPointMap(std::map<float,int>); std::map<float,int> getPointMap(); void setLineWidth(byte); byte getLineWidth(); };
.cpp文件代码:
#include "stdafx.h" #include "PoleCoordinate.h" /************************************************************************/ /* 功能:>通过给定的参数,绘制极坐标。 参数:>pDC CDC* 作者:>一梦 创建时间:2018-10-18 14:53:03 修改时间:2018-10-18 15:45:34 修改内容:>新增。 */ /************************************************************************/ int PoleCoordinate::toDraw(CDC *pDC){ pDC->SetBkMode(TRANSPARENT); //绘制同心圆 int tempRadius = 0; int num = 0; for(int i = 0;i<coordinateRadius;i+=step){ tempRadius = coordinateRadius - i; if(i==0){//最外环 CPen myPen5; myPen5.CreatePen(PS_SOLID,1,RGB(ringOuterColour.rgbtRed,ringOuterColour.rgbtGreen,ringOuterColour.rgbtBlue)); pDC->SelectObject(myPen5); pDC->Ellipse(center.x-tempRadius,center.y-tempRadius,center.x+tempRadius,center.y+tempRadius); }else{ if(num%2==0){//实线环 CPen myPen5; myPen5.CreatePen(PS_SOLID,1,RGB(ringSolidColour.rgbtRed,ringSolidColour.rgbtGreen,ringSolidColour.rgbtBlue)); pDC->SelectObject(myPen5); pDC->Ellipse(center.x-tempRadius,center.y-tempRadius,center.x+tempRadius,center.y+tempRadius); }else{//虚线环 CPen myPen6; myPen6.CreatePen(PS_DOT,1,RGB(ringDotColour.rgbtRed,ringDotColour.rgbtGreen,ringDotColour.rgbtBlue)); pDC->SelectObject(myPen6); pDC->Ellipse(center.x-tempRadius,center.y-tempRadius,center.x+tempRadius,center.y+tempRadius); } } num++; } CPen myPen2; myPen2.CreatePen(PS_SOLID,1,RGB(spokeColour.rgbtRed,spokeColour.rgbtGreen,spokeColour.rgbtBlue)); pDC->SelectObject(myPen2); //绘制辐条 for(float i = 0;i<360;){ pDC->MoveTo(center); int x = (int)(coordinateRadius*cos(i*PI/180))+center.x; int y = (int)(coordinateRadius*sin(i*PI/180))+center.y; pDC->LineTo(CPoint((int)x,(int)y)); //调整度数的位置 CString str; str.Format(_T("%0.0f"),i); str = str + L"°"; if(i>=0 && i<=45) pDC->TextOutW(x,y,str); else if(i>45 && i<=90) pDC->TextOutW(x-(int)(5+sin(i*PI/180)),y,str); else if(i>90 && i<=135) pDC->TextOutW(x-(int)(35-sin(i*PI/180)),y+(int)(4-sin(i*PI/180)),str); else if(i>135 && i<=180) pDC->TextOutW(x-(int)(40-sin(i*PI/180)),y,str); else if(i>180 && i<=225) pDC->TextOutW(x-(int)(40-sin(i*PI/180)),y-(int)(10-sin(i*PI/180)),str); else if(i>225 && i<=270) pDC->TextOutW(x-(int)(20+sin(i*PI/80)),y-(int)(20+cos(i*PI/180)),str); else if(i>270 && i<=315) pDC->TextOutW(x-(int)(5+cos(i*PI/180)),y-(int)(15+cos(i*PI/180)),str); else if(i>315 && i<=360) pDC->TextOutW(x+(int)(5+sin(i*PI/180)),y-(int)(10+sin(i*PI/180)),str); i +=fanAngle; } CString CRadiusScale; CRadiusScale.Format(_T("%d"),radiusScale); CString CStep; CStep.Format(_T("%d"),step); CString Cx; Cx.Format(_T("%ld"),center.x); CString Cy; Cy.Format(_T("%ld"),center.y); CString CAangle; CAangle.Format(_T("%0.0f"),fanAngle); CString CRadius; CRadius.Format(_T("%d"),coordinateRadius); switch(infoModel){ case 0: break; case 1: //显示圆心位置 pDC->TextOutW(center.x-coordinateRadius-100,center.y-coordinateRadius-25,L"圆心:("+Cx+L","+Cy+L")"); //显示半径 pDC->TextOutW(center.x-coordinateRadius-100,center.y-coordinateRadius-0,L"半径: "+CRadius); //每环相隔距离 pDC->TextOutW(center.x-coordinateRadius-100,center.y-coordinateRadius+25,L"每环相隔距离: "+CStep); //扇形角度 pDC->TextOutW(center.x-coordinateRadius-100,center.y-coordinateRadius+50,L"扇形角度: "+CAangle); //显示半径刻度 pDC->TextOutW(center.x-coordinateRadius-100,center.y-coordinateRadius+75,L"半径长度值: "+CRadiusScale); break; } CPen myPen6; myPen6.CreatePen(PS_SOLID,2,RGB(0,0,0)); pDC->SelectObject(myPen6); //绘制刻度 pDC->SetTextColor(RGB(200,200,200)); int conut = 0; switch(scaleModel){ case 0: break; case 1: for(int j = coordinateRadius;j>0;){ if(conut%2==0){ setPositionOffset(pDC,j); } j -= step; conut++; } break; case 2: for(int j = coordinateRadius;j>0;){ if(conut%2==1){ setPositionOffset(pDC,j); } j -= step; conut++; } break; case 3: for(int j = coordinateRadius;j>0;){ setPositionOffset(pDC,j); j -= step; conut++; } break; } std::map<float,int>::iterator ite; CPen myPen3; myPen3.CreatePen(PS_SOLID,2,RGB(pointColour.rgbtRed,pointColour.rgbtGreen,pointColour.rgbtBlue)); pDC->SelectObject(myPen3); //绘制点 for(ite = pointMap.begin();ite!=pointMap.end();ite++){ CPoint myPoint = getPointPosition(ite->second*coordinateRadius/radiusScale,ite->first,center); pDC->Ellipse(int(myPoint.x-2),int(myPoint.y-2),int(myPoint.x+2),int(myPoint.y+2)); } std::map<float,int>::iterator current = pointMap.begin(); std::map<float,int>::iterator previous = pointMap.begin(); //连线 CPen myPen4; myPen4.CreatePen(PS_SOLID,lineWidth,RGB(lineColour.rgbtRed,lineColour.rgbtGreen,lineColour.rgbtBlue)); pDC->SelectObject(myPen4); while(current!=pointMap.end()){ CPoint bPoint = getPointPosition(previous->second*coordinateRadius/radiusScale,previous->first,center); CPoint begin; begin.x = bPoint.x; begin.y = bPoint.y; pDC->MoveTo(begin); current++; if(current!=pointMap.end()){ CPoint bPoint = getPointPosition(current->second*coordinateRadius/radiusScale,current->first,center); CPoint begin; begin.x = bPoint.x; begin.y = bPoint.y; pDC->LineTo(begin); } previous = current; } return 0; } void PoleCoordinate::setPositionOffset(CDC *pDC,int j){ for(float i = 0;i<360;){ int m = (int)(j*cos(i*PI/180))+center.x; int n = (int)(j*sin(i*PI/180))+center.y; pDC->Ellipse(m-1,n-1,m+1,n+1); CString Cj; Cj.Format(_T("%0.0f"),j*(1.0*radiusScale/coordinateRadius)); if(j!=coordinateRadius){ if(i>90&&i<=135){ pDC->TextOutW(m+(int)(18*cos(i*PI/180)),n-(int)(5*cos(i*PI/180)),Cj); }else if(i>135&&i<=180){ pDC->TextOutW(m-(int)(18-5*sin(i*PI/180)),n,Cj); }else if(i>180&&i<=225){ pDC->TextOutW(m-(15-(int)(5*cos(i*PI/180))),n+(int)(10*sin(i*PI/180)),Cj); }else if(i>225&&i<=270){ pDC->TextOutW(m-(int)(10+cos(i*PI/180)),n-(int)(15-cos(i*PI/180)),Cj); }else if(i>270&&i<=315){ pDC->TextOutW(m+(int)(5*cos(i*PI/180)),n-(int)(15-10*cos(i*PI/180)),Cj); }else if(i>315&&i<=360){ pDC->TextOutW(m+(int)(5+cos(i*PI/180)),n-(int)(5+cos(i*PI/180)),Cj); }else{ pDC->TextOutW(m,n,Cj); } } i +=fanAngle; } return ; } CPoint PoleCoordinate::getPointPosition(int value,float angle,CPoint center){ CPoint myPoint; myPoint.x =(LONG)(value*cos(angle*PI/180))+center.x; myPoint.y =(LONG)(value*sin(angle*PI/180))+center.y; return myPoint; } void PoleCoordinate::setScaleModel(short scaleModel){ this->scaleModel = scaleModel; return ; } short PoleCoordinate::getScaleModel(){ return this->scaleModel; } void PoleCoordinate::setInfoModel(short infoModel){ this->infoModel = infoModel; return ; } short PoleCoordinate::getInfoModel(){ return this->infoModel; } void PoleCoordinate::setInfoPosition(int x,int y){ this->infoPosition.x = x; this->infoPosition.y = y; return ; } CPoint PoleCoordinate::getInfoPosition(){ return this->infoPosition; } void PoleCoordinate::setPointColour(byte r,byte g,byte b){ this->pointColour.rgbtRed = r; this->pointColour.rgbtGreen = g; this->pointColour.rgbtBlue = b; return ; } RGBTRIPLE PoleCoordinate::getPointColour(){ return this->pointColour; } void PoleCoordinate::setLineColour(byte r,byte g,byte b){ this->lineColour.rgbtRed = r; this->lineColour.rgbtGreen = g; this->lineColour.rgbtBlue = b; return ; } RGBTRIPLE PoleCoordinate::getLineColour(){ return this->lineColour; } void PoleCoordinate::setSpokeColour(byte r,byte g,byte b){ this->spokeColour.rgbtRed = r; this->spokeColour.rgbtGreen = g; this->spokeColour.rgbtBlue = b; return ; } RGBTRIPLE PoleCoordinate::getSpokeColour(){ return this->spokeColour; } void PoleCoordinate::setRingSolidColour(byte r,byte g,byte b){ this->ringSolidColour.rgbtRed = r; this->ringSolidColour.rgbtGreen = g; this->ringSolidColour.rgbtBlue = b; return ; } RGBTRIPLE PoleCoordinate::getRingSolidColour(){ return this->ringSolidColour; } void PoleCoordinate::setRingDotColour(byte r,byte g,byte b){ this->ringDotColour.rgbtRed = r; this->ringDotColour.rgbtGreen = g; this->ringDotColour.rgbtBlue = b; return ; } RGBTRIPLE PoleCoordinate::getRingDotColour(){ return this->ringDotColour; } void PoleCoordinate::setRingOuterColour(byte r,byte g,byte b){ this->ringOuterColour.rgbtRed = r; this->ringOuterColour.rgbtGreen = g; this->ringOuterColour.rgbtBlue = b; return ; } RGBTRIPLE PoleCoordinate::getRingOuterColour(){ return this->ringOuterColour; } void PoleCoordinate::setCoordinateRadius(int radius){ this->coordinateRadius = radius; return ; } int PoleCoordinate::getCoordinateRadius(){ return this->coordinateRadius; } void PoleCoordinate::setCenter(CPoint center){ this->center = center; return ; } CPoint PoleCoordinate::getCenter(){ return this->center; } void PoleCoordinate::setStep(int step){ this->step = step; return ; } int PoleCoordinate::getStep(){ return this->step; } void PoleCoordinate::setFanAngle(float fanAngle){ this->fanAngle = fanAngle; return ; } float PoleCoordinate::getFanAngle(){ return this->fanAngle; } void PoleCoordinate::setRadiusScale(int radiusScale){ this->radiusScale = radiusScale; return ; } int PoleCoordinate::getRadiusScale(){ return this->radiusScale; } void PoleCoordinate::setPointMap(std::map<float,int> pointMap){ this->pointMap = pointMap; return ; } std::map<float,int> PoleCoordinate::getPointMap(){ return this->pointMap; } void PoleCoordinate::setLineWidth(byte width){ this->lineWidth = width; return ; } byte PoleCoordinate::getLineWidth(){ return this->lineWidth; }
主要调用代码:
CDC *pDC = GetDC(); PoleCoordinate *pc = new PoleCoordinate(); pc->toDraw(pDC); ReleaseDC(pDC);
.