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);    

 

posted @ 2018-10-18 12:15  一梦、  阅读(1082)  评论(0编辑  收藏  举报