hrefspace

 找回密码
 立即注册
搜索
热搜: PHP PS 程序设计
查看: 863|回复: 2

原创函数绘图工具fplot.exe

[复制链接]

924

主题

1135

帖子

3580

积分

超级版主

Rank: 8Rank: 8

积分
3580

论坛头条论坛元老谋士数据帝优秀版主超级版主见习版主论坛版主

发表于 2024-4-14 12:56:29 | 显示全部楼层 |阅读模式
FPLOT.EXE函数绘图工具,一直开源,从不保留。
下载:

摘要:
=============================================================================
数学函数绘图工具,支持几乎所有的数学函数表达式绘制,支持标准直角坐标、
极坐标、参数方程、参数极方程的绘制。

采用剪枝算法,具备极高绘制精度、速度,同时自动过滤间断点、无穷点。自动上色、
自动编号、自动筛选有效定义域。这是一个完全媲美GNU PLOT的工具,纯命令行操作,
更少的开关,简约而不简单。
=============================================================================

用法:
-----------------------------------------------------------------------------
fplot  [options] {arguments}...
-----------------------------------------------------------------------------
       /zoom     [x-zoom] [y-zoom]           //设置水平缩放、垂直缩放率
       /move     [x-move] [y-move]           //设置水平偏移、垂直偏移值
       /plo(t|p) [indvar] [expression]       //待绘制自变量、因变量字串
-----------------------------------------------------------------------------

注意: 绘直角坐标用/plot,绘极坐标用/plop。

示例:
-----------------------------------------------------------------------------
fplot /zoom 30  30  /plot x sin(x)           //放大30倍,自变量为x,绘制sin(x)
fplot /zoom 300 300 /plop x sin(x)           //放大300倍,按照极坐标方式绘制
fplot /zoom 0   0                            //清除图像
fplot /zoom 0   1                            //隐藏光标
fplot /zoom 1   0                            //显示光标
-----------------------------------------------------------------------------


备注:
-----------------------------------------------------------------------------
常数类
        pi    3.1415926535897932
        e     2.7182818284590452        

通用类
        rand  随机数
        round 四舍五入
        int   取整
        ceil  向上舍入
        floor 向下舍入
        abs   绝对值
        sqrt  开方
        lg    常用对数,以10为底
        ln    自然对数
        exp   e的次幂
        gamma 伽玛函数
        torad 度转弧度
        +     加
        -     减
        *     乘
        /     除
        %     取余数
        ^     次方
        !     阶乘

三角函数类
        sin、cos、tan   
        arcsin、arccos、arctan

双曲函数类
        sinh、cosh、tanh
        arcsinh、arccosh、arctanh
-----------------------------------------------------------------------------

英译:
-----------------------------------------------------------------------------
CONSOLE FUNCTION DRAWING TOOL, COPYRIGHT@2017~2019 BY HAPPY
-----------------------------------------------------------------------------
fplot  [options] {arguments}...
-----------------------------------------------------------------------------
       /zoom     [x-zoom] [y-zoom]
       /move     [x-move] [y-move]
       /plo(t|p) [indvar] [expression]
-----------------------------------------------------------------------------
2017-02-11 VERSION 1.7"

原创代码:(仅支持g++编译器)
  1. /*        CONSOLE FUNCTION DRAWING TOOL, COPYRIGHT@2017~2019 BY HAPPY, VERSION 1.0        FPLOT.EXE        LINK GDIPLUS.LIB GDI32.LIB*/#include <math.h>#include <time.h>#include <stdio.h>#include <windows.h>#include <gdiplus\gdiplus.h>//使用GDI+using namespace Gdiplus;//申明函数extern "C" HWND WINAPI GetConsoleWindow();//定义帮助说明#define HELP_INFORMATION "\-----------------------------------------------------------------\n\CONSOLE FUNCTION DRAWING TOOL, COPYRIGHT@2017~2019 BY HAPPY\n\-----------------------------------------------------------------\n\fplot  [options] {arguments}...\n\-----------------------------------------------------------------\n\       /zoom     [x-zoom] [y-zoom]\n\       /move     [x-move] [y-move]\n\       /plo(t|p) [indvar] [expression]\n\-----------------------------------------------------------------\n\2017-02-12 VERSION 1.7"/***************定义全局变量*************///定义开关词目#define            SENSITIVE_NUM   7static const char* SENSITIVE_WORDS[]={"/ZOOM", "/MOVE", "/PLOT", "/PLOP", "/HELP", "/H", "/?"};static const char  SENSITIVE_ARGVS[]={      2,       2,       2,       2,       0,    0,    0};//数学函数词目static const char* KEY_WORDS[]={"E", "PI", "SQRT", "LG", "LN", "SIN", "COS", "TAN", "ARCSIN", "ARCCOS", "ARCTAN", "TORAD", "ABS", "ROUND", "FLOOR", "CEIL", "EXP", "SINH", "COSH", "TANH", "ARCSINH", "ARCCOSH", "ARCTANH", "INT", "GAMMA", "X", NULL};//堆栈尺寸#define  STACK_SIZE      1024//运算符栈static char   STACK1[STACK_SIZE]={0};//逆波兰栈 static char   STACK2[STACK_SIZE]={0};//浮点数栈static float  STACK3[STACK_SIZE]={0};//定义绘线属性static float  xZOOM=50, yZOOM=50, xMOVE=0, yMOVE=0, hCOLOR=0, hPREC=1000, hMARK=12, xOFFSET=0, yOFFSET=0;//主窗区域RECT          winRECT={0};LPRECT        lrRECT;//字符串存储容器static WCHAR  Tainer[1024]={0};  static CHAR   FTainer[32] ={0};  //定义颜色结构体typedef struct{        BYTE R;        BYTE G;        BYTE B;        COLORREF VALUE;}STRGB;//十六色系数组static const STRGB PARGB[15]={        {255,  0,  0,RGB(255,  0,  0)}, //红色        { 33,198,239,RGB( 33,198,239)}, //未蓝        {255,255,  0,RGB(255,255,  0)}, //黄色        {238,130,238,RGB(238,130,238)}, //紫兰        {165, 42, 42,RGB(165, 42, 42)}, //棕色        {144,238,144,RGB(144,238,144)}, //浅绿        {  0,  0,255,RGB(  0,  0,255)}, //蓝色        {255,  0,255,RGB(255,  0,255)}, //洋紫        {169,169,169,RGB(169,169,169)}, //深灰        {173,216,230,RGB(173,216,230)}, //淡蓝        {248, 29, 56,RGB(248, 29, 56)}, //亮红        {  0,255,  0,RGB(  0,255,  0)}, //绿色        {224,255,255,RGB(224,255,255)}, //淡青        {  0,255,255,RGB(  0,255,255)}, //青色        {255,255,255,RGB(255,255,255)}  //白色};//创建绘图字体 FontFamily* fontFAMILY;//设置字体属性 Font* tFONT, *nFONT;//创建字体画刷 SolidBrush* tBRUSH;        /***************逆波兰核心***************/ float RevPolishCore(const char* expression, float varV){        char  *op=(char*)expression, *S1=STACK1, *S2=STACK2, **key, *cp, *kp;        float *S3=STACK3, di, ni;        int    brackets=0;        STACK3[0]=0;                //生成逆波兰                while(*op!='\0'){                                switch(*op){                case ' ' :                case '\t':                case '\r':                case '\n':                        //过滤空字符                        op++;                        continue;                                case '(':                        brackets++;                        *(++S1)=*op;                        if(*(op+1)=='-' || *(op+1)=='+'){                                *(S2++)='0', *(S2++)=' ';                        }                        break;                case ')':                        //验证括号是否闭合                        if(brackets ==0){                                fputs("The brackets or ')' are not need", stderr);                                exit(1);                        }                        brackets--;                        while(*S1!='(')                        {                                *(S2++)=*(S1--);                        }                                        //舍弃'('                         S1--;                                        break;                case '+':                case '-':                        while(S1!=STACK1 && *S1!='(')                        {                                *(S2++)=*(S1--);                        }                        *(++S1)=*op;                        break;                case '^':                        //指数符                        while( ('A'<=(*S1) && (*S1)<='Z') )                        {                                *(S2++)=*(S1--);                        }                        *(++S1)=*op;                        break;                case '!':                        //阶乘符                        *(S2++)=*op;                        break;                case '%':                case '*':                case '/':                        while(('A'<=(*S1) && (*S1)<='Z') ||*S1=='%' ||*S1=='*' ||*S1=='/' ||*S1=='^'){                                *(S2++)=*(S1--);                        }                        *(++S1)=*op;                        break;                default :                        if(                                ('a'<=*op && *op<='z') ||                                ('A'<=*op && *op<='Z')                        ){                                //识别数学函数关键词                                key=(char**)KEY_WORDS;                                while(*key !=NULL){                                                cp=op, kp=*key;                                        //比对关键词字母                                         while((*cp==*kp||*cp==*kp+32) && *kp!='\0'){                                                cp++, kp++;                                        }                                        //验证关键词结尾                                          if( ((*cp<'A')||('Z'<*cp && *cp<'a')||(*cp>'z')) && (*kp=='\0') ){                                                 op=cp;                                                break;                                        }                                        key++;                                }                                //构建伪双目                                                         *(S2++)='.';                                *(S2++)=' ';                                //伪双目入栈                                 while( ('A'<=(*S1) && (*S1)<='Z') ){                                        *(S2++)=*(S1--);                                }                                if(*key !=NULL){                                        *(++S1)=key-(char**)KEY_WORDS+65;                                }else{                                        while(                                                ('a'<=*op && *op<='z') ||                                                ('A'<=*op && *op<='Z')                                        ){op++;}                                        *(++S1)='Z';                                }                                continue;                        }else if(('0'<=*op && *op<='9') || (*op=='.')){                                //浮点数入栈                                 while(('0'<=*op && *op<='9') || (*op=='.')){                                        *(S2++)=*(op++);                                }                                if(                                        ('a'<=*op && *op<='z') ||                                        ('A'<=*op && *op<='Z')                                ){                                        //缺少必要的运算符                                        fputs("Missing required operator\n", stderr);                                        exit(1);                                        }                                op--;                                *(S2++)=' ';                        }else{                                //无法识别的运算符                                fputs("Unrecognized operator\n", stderr);                                exit(1);                        }                        break;                }                op++;        }        //验证括号是否闭合        if(brackets !=0){                fputs("The brackets '(' are not closed", stderr);                exit(1);        }        //收尾逆波兰        while(S1 !=STACK1){*(S2++)=*(S1--);}        *S2=' ';        //计算逆波兰        op=STACK2;        while(*op!=' '){                switch(*op){                case 'A':                        *S3=2.7182818284590452;                        break;                case 'B':                        *S3=3.1415926535897932;                        break;                case 'C':                        *(S3-1)=sqrtf(*S3);                        S3--;                        break;                case 'D':                        *(S3-1)=log10f(*S3);                        S3--;                        break;                case 'E':                        *(S3-1)=logf(*S3);                        S3--;                        break;                case 'F':                        *(S3-1)=sinf(*S3);                        S3--;                        break;                case 'G':                        *(S3-1)=cosf(*S3);                        S3--;                        break;                case 'H':                        *(S3-1)=tanf(*S3);                        S3--;                        break;                case 'I':                        *(S3-1)=asinf(*S3);                        S3--;                        break;                case 'J':                        *(S3-1)=acosf(*S3);                        S3--;                        break;                case 'K':                        *(S3-1)=atanf(*S3);                        S3--;                        break;                case 'L':                        *(S3-1)=(*S3)*3.1415926535897932/180.0;                        S3--;                        break;                case 'M':                        *(S3-1)=fabsf(*S3);                        S3--;                        break;                case 'N':                        *(S3-1)=roundf(*S3);                        S3--;                        break;                case 'O':                        *(S3-1)=floorf(*S3);                        S3--;                        break;                case 'P':                        *(S3-1)=ceilf(*S3);                        S3--;                        break;                case 'Q':                        *(S3-1)=expf(*S3);                        S3--;                        break;                case 'R':                        *(S3-1)=sinhf(*S3);                        S3--;                        break;                case 'S':                        *(S3-1)=coshf(*S3);                        S3--;                        break;                case 'T':                        *(S3-1)=tanhf(*S3);                        S3--;                        break;                case 'U':                        *(S3-1)=asinhf(*S3);                        S3--;                        break;                case 'V':                        *(S3-1)=acoshf(*S3);                        S3--;                        break;                case 'W':                        *(S3-1)=atanhf(*S3);                        S3--;                        break;                case 'X':                        *(S3-1)=(int)(*S3);                        S3--;                        break;                case 'Y':                        *(S3-1)=tgammaf(*S3);                        S3--;                        break;                case 'Z':                        *S3=varV;                        break;                case '+':                        *(S3-1)+=*S3;                        S3--;                        break;                case '-':                        *(S3-1)-=*S3;                        S3--;                        break;                case '*':                        *(S3-1)*=*S3;                        S3--;                        break;                case '%':                case '/':                        if(*op=='%'){                                //取余数                                *(S3-1)=(int)*(S3-1) % (int)*S3;                        }else{                                *(S3-1)/=*S3;                        }                                                S3--;                        break;                case '^':                        *(S3-1)=powf(*(S3-1), *S3);                        S3--;                        break;                case '!':                        *S3=tgammaf(*S3+1);                        break;                default :                        //字符串转浮点                        di=0, ni=1;                        while('0'<=*op && *op<='9'){                                di=10*di+(*op)-'0';                                op++;                        }                                if(*op=='.'){                                op++;                                while('0'<=*op && *op<='9'){                                        di=10*di+(*op)-'0';                                        op++, ni*=10;                                }                                }                        *(++S3)=di/ni;                        break;                }                op++;        }        //返回计算结果         return *S3;}/***************功能函数群***************///光标函数 BOOL DispyCursor(int size,bool mode){        CONSOLE_CURSOR_INFO cinfo ={(DWORD)size, mode};        return SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cinfo);         }//转码函数WCHAR* L(const CHAR* str){        if(!str){return NULL;}        int wLen=MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, str, -1, NULL, 0);        MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, str, -1, Tainer, wLen);        Tainer[wLen]='\0';        return Tainer;}//辨关键词int itifyWORDS(const char* strARGV){        int i, SN;        for(SN=0; SN<SENSITIVE_NUM; SN++){                char *op=(char*)strARGV, *kp=(char*)SENSITIVE_WORDS[SN];                while(*kp!='\0'){                        if( (('a'<= *op && *op<='z')?*op-32:*op) != (('a'<= *kp && *kp<='z')?*kp-32:*kp) ){break;}                        op++;kp++;                }                 if( (*kp=='\0') && (*op==' '||*op=='\t'||*op=='\r'||*op=='\n'||*op=='\0') ){return SN;}        }                                        return -1;}//显示数字void drawNUMS(Graphics *graph, float fnum, float px, float py){        sprintf(FTainer, "%.5g", fnum);        graph->DrawString(L(FTainer), -1, tFONT, PointF(px,py), tBRUSH);}//绘制刻度void drawAXY(Graphics *graph){        //设置坐标字体         Font fontp(fontFAMILY, 12, FontStyleRegular, UnitPixel);        tFONT=&fontp;        //设置曲线光滑        graph->SetSmoothingMode(SmoothingModeHighQuality);        //创建白色画笔        Pen *pen, pez(Color(160, 255, 255, 255), 1), pep(Color(160, 255, 255, 255), 1);        //设置虚线画笔        pez.SetDashStyle(DashStyleDash);        for(int i=0; i<=lrRECT->right*2; i+=50){                //绘制坐标                if(i==0){                        //绘制坐标原点                        drawNUMS(graph, 0, xOFFSET, yOFFSET);                }else{                        //绘制坐标刻度                        drawNUMS(graph,   i/xZOOM, xOFFSET+i,   yOFFSET);                        drawNUMS(graph, 0-i/xZOOM, xOFFSET-i,   yOFFSET);                        drawNUMS(graph, 0-i/yZOOM,   xOFFSET, yOFFSET+i);                        drawNUMS(graph,   i/yZOOM,   xOFFSET, yOFFSET-i);                }                //绘制网格                if(i==0){                        pen=&pep;                }else{                        pen=&pez;                }                graph->DrawLine(pen, PointF(0,       yOFFSET+i), PointF(lrRECT->right, yOFFSET+i));                graph->DrawLine(pen, PointF(0,       yOFFSET-i), PointF(lrRECT->right, yOFFSET-i));                graph->DrawLine(pen, PointF(xOFFSET+i,       0), PointF(xOFFSET+i,lrRECT->bottom));                graph->DrawLine(pen, PointF(xOFFSET-i,       0), PointF(xOFFSET-i,lrRECT->bottom));        }        //清理对象        DeleteObject(pen);        DeleteObject(&pez);        DeleteObject(&pep);        DeleteObject(&fontp);}//绘制曲线void drawFUN(Graphics *graph, BOOL penMODE, const char* varression, const char* expression){        //设置绘图曲线光滑        graph->SetSmoothingMode(SmoothingModeHighQuality);        //创建彩色画笔        STRGB* penRGB=(STRGB*)&PARGB[(int)hCOLOR];        Pen pep(Color(255,penRGB->R,penRGB->G,penRGB->B), 2), *pen=&pep;        //设置注释字体         Font fontp(fontFAMILY, 13, FontStyleBold, UnitPixel);        tFONT=&fontp;        //绘制函数注释        graph->DrawLine(pen, PointF(2, hMARK+6), PointF(20, hMARK+6));        graph->DrawString(L(expression), -1, tFONT, PointF(20,hMARK), tBRUSH);        hMARK+=16;        //绘制函数曲线        float t, x1, y1, x2, y2, t_start=(-lrRECT->right/2.0-xMOVE)/xZOOM, t_end=(lrRECT->right/2.0-xMOVE)/xZOOM, add=lrRECT->right/xZOOM/hPREC, y_start=2*(-lrRECT->bottom/2.0-yMOVE)/yZOOM, y_end=2*(lrRECT->bottom/2.0-yMOVE)/yZOOM;        if(penMODE){                //直角坐标                x1=RevPolishCore(varression, t_start), y1=RevPolishCore(expression, t_start);                for(t=t_start; t<=t_end; t+=add){                        x2=RevPolishCore(varression, t+add), y2=RevPolishCore(expression, t+add);                        if((t!=t_start)  && (y_start<y1 && y1<y_end) && (y_start<y2 && y2<y_end)){                                graph->DrawLine(pen, PointF(xZOOM*x1+xOFFSET, -yZOOM*y1+yOFFSET), PointF(xZOOM*x2+xOFFSET, -yZOOM*y2+yOFFSET));                        }                        x1=x2, y1=y2;                }        }else{                //极轴坐标                x1=RevPolishCore(varression, t_start), y1=RevPolishCore(expression, t_start);                for(t=t_start; t<=t_end*5; t+=add){                        x2=RevPolishCore(varression, t+add), y2=RevPolishCore(expression, t+add);                        if((t!=t_start) && (y_start<y1 && y1<y_end) && (y_start<y2 && y2<y_end)){                                graph->DrawLine(pen, PointF(xZOOM*y1*cos(x1)+xOFFSET, -yZOOM*y1*sin(x1)+yOFFSET), PointF(xZOOM*y2*cos(x2)+xOFFSET, -yZOOM*y2*sin(x2)+yOFFSET));                        }                        x1=x2, y1=y2;                }                }                //清理对象        DeleteObject(pen);        DeleteObject(&pep);        DeleteObject(&fontp);}//开关解析void OptRE(int argc, char** argv){         //计算有效参数数目         int oargc=argc-1, anum;        if(oargc==0){                //无参数,则抛出使用说明                fputs(HELP_INFORMATION, stderr);                exit(1);        }        //获取CMD窗口句柄         HWND hCMD=GetConsoleWindow();        HDC  hDC =GetDC(hCMD);        //获取CMD窗口大小        lrRECT=&winRECT;        GetClientRect(hCMD, lrRECT);        //获取像素坐标基值         xOFFSET=lrRECT->right/2, yOFFSET=lrRECT->bottom/2;        //创建加速内存画布        HWND    hWND2=NULL;        HDC     hDC2=CreateCompatibleDC(hDC);        HBITMAP hBitmap2=CreateCompatibleBitmap(hDC, lrRECT->right, lrRECT->bottom);        SelectObject(hDC2, hBitmap2);                //创建绘图工具        Graphics graphicsp(hDC), *graph=&graphicsp;        //创建绘图字体         FontFamily fontf(L"SimSun");        fontFAMILY=&fontf;        //创建字体画刷         SolidBrush brushp(Color(255, 255, 255, 255));        tBRUSH=&brushp;                //初始化线条颜色        int srCOLOR=0;                //参数接收针        char** oargv=argv;                //参数累加器        int i=0;                //坐标绘制态        BOOL dMARK=FALSE;        //临时变量        float tp1, tp2;        //开启主循环         while((++i)<=oargc){                int SN=itifyWORDS(argv[i]);                if(SN!=-1){                        if(i+SENSITIVE_ARGVS[SN]>oargc){                                        //缺少必要参数                                        fprintf(stderr, "The option '%s' needs %d parameters\n", argv[i], SENSITIVE_ARGVS[SN]);                                        exit(1);                        }                        for(anum=1; anum<=SENSITIVE_ARGVS[SN]; anum++){                                if(oargv[i+anum][0]==SENSITIVE_WORDS[0][0]){                                        //缺少必要参数                                        fprintf(stderr, "Only %d parameters, the option '%s' needs %d parameters\n", anum-1, argv[i], SENSITIVE_ARGVS[SN]);                                        exit(1);                                                        }                        }                                        //执行开关命令                        switch(SN)                        {                        case 0:                                //ZOOM                                tp1=fabsf(atof(argv[i+1])), tp2=fabsf(atof(argv[i+2]));                                //解析ZOOM开关的隐藏功能                                if(tp1*tp2==0){                                        if(tp2!=0){                                                DispyCursor((DWORD)25, FALSE);                                        }else if(tp1!=0){                                                DispyCursor((DWORD)25, TRUE );                                        }else{                                                InvalidateRect(hCMD,  NULL, FALSE);                                                dMARK=FALSE;                                        }                                        break;                                }                                InvalidateRect(hCMD,  NULL, FALSE);                                dMARK=FALSE, srCOLOR=0, hMARK=12;                                xZOOM=tp1, yZOOM=tp2;                                break;                        case 1:                                //MOVE                                if(dMARK){                                        InvalidateRect(hCMD,  NULL, FALSE);                                        dMARK=FALSE, srCOLOR=0, hMARK=12;                                }                                xMOVE=atof(argv[i+1]), yMOVE=atof(argv[i+2]);                                xOFFSET+=xMOVE, yOFFSET-=yMOVE;                                break;                        case 2:                        case 3:                                //PLOP||PLOT                                if(!dMARK){                                        //调用坐标绘制函数                                         drawAXY(graph);                                        dMARK=TRUE;                                }                                hCOLOR=(srCOLOR++)%15;                                drawFUN(graph, (SN==2)?TRUE:FALSE, argv[i+1], argv[i+2]);                                break;                        default:                                //HELP                                fputs(HELP_INFORMATION, stderr);                                exit(1);                        }                        i+=SENSITIVE_ARGVS[SN];                                        //无法识别的参数                }else{                        fprintf(stderr, "An error occurred near '%s'\n", argv[i]);                        exit(1);                }        }        //从内存画布复制到CMD画布        //BitBlt(hDC,0,0,lrRECT->right,lrRECT->bottom, hDC2,0,0,SRCCOPY);        //清理绘图工具         DeleteObject(graph);                DeleteObject(tBRUSH);        DeleteObject(tFONT);        DeleteObject(fontFAMILY);        //释放内存画布        ReleaseDC(NULL, hDC2);        DeleteDC(hDC2);        DeleteObject(hBitmap2);        //释放CMD 画布        ReleaseDC(hCMD, hDC);        DeleteDC(hDC);}/*************MAIN主函数入口*************/int main(int argc, char** argv){        //初始化GdiPlus        ULONG_PTR gdipludToken;        GdiplusStartupInput gdiplusInput;        GdiplusStartup(&gdipludToken,&gdiplusInput,NULL);                //解析开关        OptRE(argc, argv);        //关闭Gdiplus        GdiplusShutdown(gdipludToken);        return 0;}
复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
世界上最遥远的距离,不是生与死的距离,而是我站在你面前,你却不知道我爱你
回复

使用道具 举报

0

主题

189

帖子

47

积分

新手上路

Rank: 1

积分
47
发表于 2024-4-14 12:56:56 | 显示全部楼层
厉害呀。没想到可以在 CMD 下画出 这个细腻的 图来。

好神奇的gdiplus
回复

使用道具 举报

0

主题

157

帖子

2

积分

新手上路

Rank: 1

积分
2
发表于 2024-4-14 12:57:20 | 显示全部楼层
感谢点赞,代码已预留了接口,可在任何窗口绘制,同时也预留了双缓存。gdiplus并不好用,主要是为了少些代码才用gdiplus,以至于绘图速度很低下。本来是打算用虚拟画笔实现,但是我不想再增加1000行代码了,所以图了省事,就牺牲了速度。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|hrefspace

GMT+8, 2024-5-2 04:10 , Processed in 0.077832 second(s), 23 queries .

Powered by hrefspace X3.4 Licensed

Copyright © 2022, hrefspace.

快速回复 返回顶部 返回列表