Board logo

标题: 控制台函数绘图工具fplot.exe [打印本页]

作者: happy886rr    时间: 2017-2-12 00:22     标题: 控制台函数绘图工具fplot.exe

FPLOT.EXE更新至1.7版,新架构更稳定。
下载链接: https://pan.baidu.com/s/1Mai3MaUQrVLD5Nh_JM2KvQ?pwd=8kvy

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

采用剪枝算法,具备极高绘制精度、速度,同时自动过滤间断点、无穷点。自动上色、
自动编号、自动筛选有效定义域。这是一个完全媲美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. /*
  2. CONSOLE FUNCTION DRAWING TOOL, COPYRIGHT@2017~2019 BY HAPPY, VERSION 1.0
  3. FPLOT.EXE
  4. LINK GDIPLUS.LIB GDI32.LIB
  5. */
  6. #include <math.h>
  7. #include <time.h>
  8. #include <stdio.h>
  9. #include <windows.h>
  10. #include <gdiplus\gdiplus.h>
  11. //使用GDI+
  12. using namespace Gdiplus;
  13. //申明函数
  14. extern "C" HWND WINAPI GetConsoleWindow();
  15. //定义帮助说明
  16. #define HELP_INFORMATION "\
  17. -----------------------------------------------------------------\n\
  18. CONSOLE FUNCTION DRAWING TOOL, COPYRIGHT@2017~2019 BY HAPPY\n\
  19. -----------------------------------------------------------------\n\
  20. fplot  [options] {arguments}...\n\
  21. -----------------------------------------------------------------\n\
  22.        /zoom     [x-zoom] [y-zoom]\n\
  23.        /move     [x-move] [y-move]\n\
  24.        /plo(t|p) [indvar] [expression]\n\
  25. -----------------------------------------------------------------\n\
  26. 2017-02-12 VERSION 1.7"
  27. /***************定义全局变量*************/
  28. //定义开关词目
  29. #define            SENSITIVE_NUM   7
  30. static const char* SENSITIVE_WORDS[]={"/ZOOM", "/MOVE", "/PLOT", "/PLOP", "/HELP", "/H", "/?"};
  31. static const char  SENSITIVE_ARGVS[]={      2,       2,       2,       2,       0,    0,    0};
  32. //数学函数词目
  33. 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};
  34. //堆栈尺寸
  35. #define  STACK_SIZE      1024
  36. //运算符栈
  37. static char   STACK1[STACK_SIZE]={0};
  38. //逆波兰栈
  39. static char   STACK2[STACK_SIZE]={0};
  40. //浮点数栈
  41. static float  STACK3[STACK_SIZE]={0};
  42. //定义绘线属性
  43. static float  xZOOM=50, yZOOM=50, xMOVE=0, yMOVE=0, hCOLOR=0, hPREC=1000, hMARK=12, xOFFSET=0, yOFFSET=0;
  44. //主窗区域
  45. RECT          winRECT={0};
  46. LPRECT        lrRECT;
  47. //字符串存储容器
  48. static WCHAR  Tainer[1024]={0};  
  49. static CHAR   FTainer[32] ={0};  
  50. //定义颜色结构体
  51. typedef struct{
  52. BYTE R;
  53. BYTE G;
  54. BYTE B;
  55. COLORREF VALUE;
  56. }STRGB;
  57. //十六色系数组
  58. static const STRGB PARGB[15]={
  59. {255,  0,  0,RGB(255,  0,  0)}, //红色
  60. { 33,198,239,RGB( 33,198,239)}, //未蓝
  61. {255,255,  0,RGB(255,255,  0)}, //黄色
  62. {238,130,238,RGB(238,130,238)}, //紫兰
  63. {165, 42, 42,RGB(165, 42, 42)}, //棕色
  64. {144,238,144,RGB(144,238,144)}, //浅绿
  65. {  0,  0,255,RGB(  0,  0,255)}, //蓝色
  66. {255,  0,255,RGB(255,  0,255)}, //洋紫
  67. {169,169,169,RGB(169,169,169)}, //深灰
  68. {173,216,230,RGB(173,216,230)}, //淡蓝
  69. {248, 29, 56,RGB(248, 29, 56)}, //亮红
  70. {  0,255,  0,RGB(  0,255,  0)}, //绿色
  71. {224,255,255,RGB(224,255,255)}, //淡青
  72. {  0,255,255,RGB(  0,255,255)}, //青色
  73. {255,255,255,RGB(255,255,255)}  //白色
  74. };
  75. //创建绘图字体
  76. FontFamily* fontFAMILY;
  77. //设置字体属性
  78. Font* tFONT, *nFONT;
  79. //创建字体画刷
  80. SolidBrush* tBRUSH;
  81. /***************逆波兰核心***************/
  82. float RevPolishCore(const char* expression, float varV)
  83. {
  84. char  *op=(char*)expression, *S1=STACK1, *S2=STACK2, **key, *cp, *kp;
  85. float *S3=STACK3, di, ni;
  86. int    brackets=0;
  87. STACK3[0]=0;
  88. //生成逆波兰
  89. while(*op!='\0'){
  90. switch(*op){
  91. case ' ' :
  92. case '\t':
  93. case '\r':
  94. case '\n':
  95. //过滤空字符
  96. op++;
  97. continue;
  98. case '(':
  99. brackets++;
  100. *(++S1)=*op;
  101. if(*(op+1)=='-' || *(op+1)=='+'){
  102. *(S2++)='0', *(S2++)=' ';
  103. }
  104. break;
  105. case ')':
  106. //验证括号是否闭合
  107. if(brackets ==0){
  108. fputs("The brackets or ')' are not need", stderr);
  109. exit(1);
  110. }
  111. brackets--;
  112. while(*S1!='(')
  113. {
  114. *(S2++)=*(S1--);
  115. }
  116. //舍弃'('
  117. S1--;
  118. break;
  119. case '+':
  120. case '-':
  121. while(S1!=STACK1 && *S1!='(')
  122. {
  123. *(S2++)=*(S1--);
  124. }
  125. *(++S1)=*op;
  126. break;
  127. case '^':
  128. //指数符
  129. while( ('A'<=(*S1) && (*S1)<='Z') )
  130. {
  131. *(S2++)=*(S1--);
  132. }
  133. *(++S1)=*op;
  134. break;
  135. case '!':
  136. //阶乘符
  137. *(S2++)=*op;
  138. break;
  139. case '%':
  140. case '*':
  141. case '/':
  142. while(('A'<=(*S1) && (*S1)<='Z') ||*S1=='%' ||*S1=='*' ||*S1=='/' ||*S1=='^'){
  143. *(S2++)=*(S1--);
  144. }
  145. *(++S1)=*op;
  146. break;
  147. default :
  148. if(
  149. ('a'<=*op && *op<='z') ||
  150. ('A'<=*op && *op<='Z')
  151. ){
  152. //识别数学函数关键词
  153. key=(char**)KEY_WORDS;
  154. while(*key !=NULL){
  155. cp=op, kp=*key;
  156. //比对关键词字母
  157. while((*cp==*kp||*cp==*kp+32) && *kp!='\0'){
  158. cp++, kp++;
  159. }
  160. //验证关键词结尾
  161. if( ((*cp<'A')||('Z'<*cp && *cp<'a')||(*cp>'z')) && (*kp=='\0') ){
  162. op=cp;
  163. break;
  164. }
  165. key++;
  166. }
  167. //构建伪双目
  168. *(S2++)='.';
  169. *(S2++)=' ';
  170. //伪双目入栈
  171. while( ('A'<=(*S1) && (*S1)<='Z') ){
  172. *(S2++)=*(S1--);
  173. }
  174. if(*key !=NULL){
  175. *(++S1)=key-(char**)KEY_WORDS+65;
  176. }else{
  177. while(
  178. ('a'<=*op && *op<='z') ||
  179. ('A'<=*op && *op<='Z')
  180. ){op++;}
  181. *(++S1)='Z';
  182. }
  183. continue;
  184. }else if(('0'<=*op && *op<='9') || (*op=='.')){
  185. //浮点数入栈
  186. while(('0'<=*op && *op<='9') || (*op=='.')){
  187. *(S2++)=*(op++);
  188. }
  189. if(
  190. ('a'<=*op && *op<='z') ||
  191. ('A'<=*op && *op<='Z')
  192. ){
  193. //缺少必要的运算符
  194. fputs("Missing required operator\n", stderr);
  195. exit(1);
  196. }
  197. op--;
  198. *(S2++)=' ';
  199. }else{
  200. //无法识别的运算符
  201. fputs("Unrecognized operator\n", stderr);
  202. exit(1);
  203. }
  204. break;
  205. }
  206. op++;
  207. }
  208. //验证括号是否闭合
  209. if(brackets !=0){
  210. fputs("The brackets '(' are not closed", stderr);
  211. exit(1);
  212. }
  213. //收尾逆波兰
  214. while(S1 !=STACK1){*(S2++)=*(S1--);}
  215. *S2=' ';
  216. //计算逆波兰
  217. op=STACK2;
  218. while(*op!=' '){
  219. switch(*op){
  220. case 'A':
  221. *S3=2.7182818284590452;
  222. break;
  223. case 'B':
  224. *S3=3.1415926535897932;
  225. break;
  226. case 'C':
  227. *(S3-1)=sqrtf(*S3);
  228. S3--;
  229. break;
  230. case 'D':
  231. *(S3-1)=log10f(*S3);
  232. S3--;
  233. break;
  234. case 'E':
  235. *(S3-1)=logf(*S3);
  236. S3--;
  237. break;
  238. case 'F':
  239. *(S3-1)=sinf(*S3);
  240. S3--;
  241. break;
  242. case 'G':
  243. *(S3-1)=cosf(*S3);
  244. S3--;
  245. break;
  246. case 'H':
  247. *(S3-1)=tanf(*S3);
  248. S3--;
  249. break;
  250. case 'I':
  251. *(S3-1)=asinf(*S3);
  252. S3--;
  253. break;
  254. case 'J':
  255. *(S3-1)=acosf(*S3);
  256. S3--;
  257. break;
  258. case 'K':
  259. *(S3-1)=atanf(*S3);
  260. S3--;
  261. break;
  262. case 'L':
  263. *(S3-1)=(*S3)*3.1415926535897932/180.0;
  264. S3--;
  265. break;
  266. case 'M':
  267. *(S3-1)=fabsf(*S3);
  268. S3--;
  269. break;
  270. case 'N':
  271. *(S3-1)=roundf(*S3);
  272. S3--;
  273. break;
  274. case 'O':
  275. *(S3-1)=floorf(*S3);
  276. S3--;
  277. break;
  278. case 'P':
  279. *(S3-1)=ceilf(*S3);
  280. S3--;
  281. break;
  282. case 'Q':
  283. *(S3-1)=expf(*S3);
  284. S3--;
  285. break;
  286. case 'R':
  287. *(S3-1)=sinhf(*S3);
  288. S3--;
  289. break;
  290. case 'S':
  291. *(S3-1)=coshf(*S3);
  292. S3--;
  293. break;
  294. case 'T':
  295. *(S3-1)=tanhf(*S3);
  296. S3--;
  297. break;
  298. case 'U':
  299. *(S3-1)=asinhf(*S3);
  300. S3--;
  301. break;
  302. case 'V':
  303. *(S3-1)=acoshf(*S3);
  304. S3--;
  305. break;
  306. case 'W':
  307. *(S3-1)=atanhf(*S3);
  308. S3--;
  309. break;
  310. case 'X':
  311. *(S3-1)=(int)(*S3);
  312. S3--;
  313. break;
  314. case 'Y':
  315. *(S3-1)=tgammaf(*S3);
  316. S3--;
  317. break;
  318. case 'Z':
  319. *S3=varV;
  320. break;
  321. case '+':
  322. *(S3-1)+=*S3;
  323. S3--;
  324. break;
  325. case '-':
  326. *(S3-1)-=*S3;
  327. S3--;
  328. break;
  329. case '*':
  330. *(S3-1)*=*S3;
  331. S3--;
  332. break;
  333. case '%':
  334. case '/':
  335. if(*op=='%'){
  336. //取余数
  337. *(S3-1)=(int)*(S3-1) % (int)*S3;
  338. }else{
  339. *(S3-1)/=*S3;
  340. }
  341. S3--;
  342. break;
  343. case '^':
  344. *(S3-1)=powf(*(S3-1), *S3);
  345. S3--;
  346. break;
  347. case '!':
  348. *S3=tgammaf(*S3+1);
  349. break;
  350. default :
  351. //字符串转浮点
  352. di=0, ni=1;
  353. while('0'<=*op && *op<='9'){
  354. di=10*di+(*op)-'0';
  355. op++;
  356. }
  357. if(*op=='.'){
  358. op++;
  359. while('0'<=*op && *op<='9'){
  360. di=10*di+(*op)-'0';
  361. op++, ni*=10;
  362. }
  363. }
  364. *(++S3)=di/ni;
  365. break;
  366. }
  367. op++;
  368. }
  369. //返回计算结果
  370. return *S3;
  371. }
  372. /***************功能函数群***************/
  373. //光标函数
  374. BOOL DispyCursor(int size,bool mode)
  375. {
  376. CONSOLE_CURSOR_INFO cinfo ={(DWORD)size, mode};
  377. return SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cinfo);
  378. }
  379. //转码函数
  380. WCHAR* L(const CHAR* str)
  381. {
  382. if(!str){return NULL;}
  383. int wLen=MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, str, -1, NULL, 0);
  384. MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, str, -1, Tainer, wLen);
  385. Tainer[wLen]='\0';
  386. return Tainer;
  387. }
  388. //辨关键词
  389. int itifyWORDS(const char* strARGV)
  390. {
  391. int i, SN;
  392. for(SN=0; SN<SENSITIVE_NUM; SN++){
  393. char *op=(char*)strARGV, *kp=(char*)SENSITIVE_WORDS[SN];
  394. while(*kp!='\0'){
  395. if( (('a'<= *op && *op<='z')?*op-32:*op) != (('a'<= *kp && *kp<='z')?*kp-32:*kp) ){break;}
  396. op++;kp++;
  397. }
  398. if( (*kp=='\0') && (*op==' '||*op=='\t'||*op=='\r'||*op=='\n'||*op=='\0') ){return SN;}
  399. }
  400. return -1;
  401. }
  402. //显示数字
  403. void drawNUMS(Graphics *graph, float fnum, float px, float py)
  404. {
  405. sprintf(FTainer, "%.5g", fnum);
  406. graph->DrawString(L(FTainer), -1, tFONT, PointF(px,py), tBRUSH);
  407. }
  408. //绘制刻度
  409. void drawAXY(Graphics *graph)
  410. {
  411. //设置坐标字体
  412. Font fontp(fontFAMILY, 12, FontStyleRegular, UnitPixel);
  413. tFONT=&fontp;
  414. //设置曲线光滑
  415. graph->SetSmoothingMode(SmoothingModeHighQuality);
  416. //创建白色画笔
  417. Pen *pen, pez(Color(160, 255, 255, 255), 1), pep(Color(160, 255, 255, 255), 1);
  418. //设置虚线画笔
  419. pez.SetDashStyle(DashStyleDash);
  420. for(int i=0; i<=lrRECT->right*2; i+=50){
  421. //绘制坐标
  422. if(i==0){
  423. //绘制坐标原点
  424. drawNUMS(graph, 0, xOFFSET, yOFFSET);
  425. }else{
  426. //绘制坐标刻度
  427. drawNUMS(graph,   i/xZOOM, xOFFSET+i,   yOFFSET);
  428. drawNUMS(graph, 0-i/xZOOM, xOFFSET-i,   yOFFSET);
  429. drawNUMS(graph, 0-i/yZOOM,   xOFFSET, yOFFSET+i);
  430. drawNUMS(graph,   i/yZOOM,   xOFFSET, yOFFSET-i);
  431. }
  432. //绘制网格
  433. if(i==0){
  434. pen=&pep;
  435. }else{
  436. pen=&pez;
  437. }
  438. graph->DrawLine(pen, PointF(0,       yOFFSET+i), PointF(lrRECT->right, yOFFSET+i));
  439. graph->DrawLine(pen, PointF(0,       yOFFSET-i), PointF(lrRECT->right, yOFFSET-i));
  440. graph->DrawLine(pen, PointF(xOFFSET+i,       0), PointF(xOFFSET+i,lrRECT->bottom));
  441. graph->DrawLine(pen, PointF(xOFFSET-i,       0), PointF(xOFFSET-i,lrRECT->bottom));
  442. }
  443. //清理对象
  444. DeleteObject(pen);
  445. DeleteObject(&pez);
  446. DeleteObject(&pep);
  447. DeleteObject(&fontp);
  448. }
  449. //绘制曲线
  450. void drawFUN(Graphics *graph, BOOL penMODE, const char* varression, const char* expression)
  451. {
  452. //设置绘图曲线光滑
  453. graph->SetSmoothingMode(SmoothingModeHighQuality);
  454. //创建彩色画笔
  455. STRGB* penRGB=(STRGB*)&PARGB[(int)hCOLOR];
  456. Pen pep(Color(255,penRGB->R,penRGB->G,penRGB->B), 2), *pen=&pep;
  457. //设置注释字体
  458. Font fontp(fontFAMILY, 13, FontStyleBold, UnitPixel);
  459. tFONT=&fontp;
  460. //绘制函数注释
  461. graph->DrawLine(pen, PointF(2, hMARK+6), PointF(20, hMARK+6));
  462. graph->DrawString(L(expression), -1, tFONT, PointF(20,hMARK), tBRUSH);
  463. hMARK+=16;
  464. //绘制函数曲线
  465. 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;
  466. if(penMODE){
  467. //直角坐标
  468. x1=RevPolishCore(varression, t_start), y1=RevPolishCore(expression, t_start);
  469. for(t=t_start; t<=t_end; t+=add){
  470. x2=RevPolishCore(varression, t+add), y2=RevPolishCore(expression, t+add);
  471. if((t!=t_start)  && (y_start<y1 && y1<y_end) && (y_start<y2 && y2<y_end)){
  472. graph->DrawLine(pen, PointF(xZOOM*x1+xOFFSET, -yZOOM*y1+yOFFSET), PointF(xZOOM*x2+xOFFSET, -yZOOM*y2+yOFFSET));
  473. }
  474. x1=x2, y1=y2;
  475. }
  476. }else{
  477. //极轴坐标
  478. x1=RevPolishCore(varression, t_start), y1=RevPolishCore(expression, t_start);
  479. for(t=t_start; t<=t_end*5; t+=add){
  480. x2=RevPolishCore(varression, t+add), y2=RevPolishCore(expression, t+add);
  481. if((t!=t_start) && (y_start<y1 && y1<y_end) && (y_start<y2 && y2<y_end)){
  482. 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));
  483. }
  484. x1=x2, y1=y2;
  485. }
  486. }
  487. //清理对象
  488. DeleteObject(pen);
  489. DeleteObject(&pep);
  490. DeleteObject(&fontp);
  491. }
  492. //开关解析
  493. void OptRE(int argc, char** argv)
  494. {
  495. //计算有效参数数目
  496. int oargc=argc-1, anum;
  497. if(oargc==0){
  498. //无参数,则抛出使用说明
  499. fputs(HELP_INFORMATION, stderr);
  500. exit(1);
  501. }
  502. //获取CMD窗口句柄
  503. HWND hCMD=GetConsoleWindow();
  504. HDC  hDC =GetDC(hCMD);
  505. //获取CMD窗口大小
  506. lrRECT=&winRECT;
  507. GetClientRect(hCMD, lrRECT);
  508. //获取像素坐标基值
  509. xOFFSET=lrRECT->right/2, yOFFSET=lrRECT->bottom/2;
  510. //创建加速内存画布
  511. HWND    hWND2=NULL;
  512. HDC     hDC2=CreateCompatibleDC(hDC);
  513. HBITMAP hBitmap2=CreateCompatibleBitmap(hDC, lrRECT->right, lrRECT->bottom);
  514. SelectObject(hDC2, hBitmap2);
  515. //创建绘图工具
  516. Graphics graphicsp(hDC), *graph=&graphicsp;
  517. //创建绘图字体
  518. FontFamily fontf(L"SimSun");
  519. fontFAMILY=&fontf;
  520. //创建字体画刷
  521. SolidBrush brushp(Color(255, 255, 255, 255));
  522. tBRUSH=&brushp;
  523. //初始化线条颜色
  524. int srCOLOR=0;
  525. //参数接收针
  526. char** oargv=argv;
  527. //参数累加器
  528. int i=0;
  529. //坐标绘制态
  530. BOOL dMARK=FALSE;
  531. //临时变量
  532. float tp1, tp2;
  533. //开启主循环
  534. while((++i)<=oargc){
  535. int SN=itifyWORDS(argv[i]);
  536. if(SN!=-1){
  537. if(i+SENSITIVE_ARGVS[SN]>oargc){
  538. //缺少必要参数
  539. fprintf(stderr, "The option '%s' needs %d parameters\n", argv[i], SENSITIVE_ARGVS[SN]);
  540. exit(1);
  541. }
  542. for(anum=1; anum<=SENSITIVE_ARGVS[SN]; anum++){
  543. if(oargv[i+anum][0]==SENSITIVE_WORDS[0][0]){
  544. //缺少必要参数
  545. fprintf(stderr, "Only %d parameters, the option '%s' needs %d parameters\n", anum-1, argv[i], SENSITIVE_ARGVS[SN]);
  546. exit(1);
  547. }
  548. }
  549. //执行开关命令
  550. switch(SN)
  551. {
  552. case 0:
  553. //ZOOM
  554. tp1=fabsf(atof(argv[i+1])), tp2=fabsf(atof(argv[i+2]));
  555. //解析ZOOM开关的隐藏功能
  556. if(tp1*tp2==0){
  557. if(tp2!=0){
  558. DispyCursor((DWORD)25, FALSE);
  559. }else if(tp1!=0){
  560. DispyCursor((DWORD)25, TRUE );
  561. }else{
  562. InvalidateRect(hCMD,  NULL, FALSE);
  563. dMARK=FALSE;
  564. }
  565. break;
  566. }
  567. InvalidateRect(hCMD,  NULL, FALSE);
  568. dMARK=FALSE, srCOLOR=0, hMARK=12;
  569. xZOOM=tp1, yZOOM=tp2;
  570. break;
  571. case 1:
  572. //MOVE
  573. if(dMARK){
  574. InvalidateRect(hCMD,  NULL, FALSE);
  575. dMARK=FALSE, srCOLOR=0, hMARK=12;
  576. }
  577. xMOVE=atof(argv[i+1]), yMOVE=atof(argv[i+2]);
  578. xOFFSET+=xMOVE, yOFFSET-=yMOVE;
  579. break;
  580. case 2:
  581. case 3:
  582. //PLOP||PLOT
  583. if(!dMARK){
  584. //调用坐标绘制函数
  585. drawAXY(graph);
  586. dMARK=TRUE;
  587. }
  588. hCOLOR=(srCOLOR++)%15;
  589. drawFUN(graph, (SN==2)?TRUE:FALSE, argv[i+1], argv[i+2]);
  590. break;
  591. default:
  592. //HELP
  593. fputs(HELP_INFORMATION, stderr);
  594. exit(1);
  595. }
  596. i+=SENSITIVE_ARGVS[SN];
  597. //无法识别的参数
  598. }else{
  599. fprintf(stderr, "An error occurred near '%s'\n", argv[i]);
  600. exit(1);
  601. }
  602. }
  603. //从内存画布复制到CMD画布
  604. //BitBlt(hDC,0,0,lrRECT->right,lrRECT->bottom, hDC2,0,0,SRCCOPY);
  605. //清理绘图工具
  606. DeleteObject(graph);
  607. DeleteObject(tBRUSH);
  608. DeleteObject(tFONT);
  609. DeleteObject(fontFAMILY);
  610. //释放内存画布
  611. ReleaseDC(NULL, hDC2);
  612. DeleteDC(hDC2);
  613. DeleteObject(hBitmap2);
  614. //释放CMD 画布
  615. ReleaseDC(hCMD, hDC);
  616. DeleteDC(hDC);
  617. }
  618. /*************MAIN主函数入口*************/
  619. int main(int argc, char** argv)
  620. {
  621. //初始化GdiPlus
  622. ULONG_PTR gdipludToken;
  623. GdiplusStartupInput gdiplusInput;
  624. GdiplusStartup(&gdipludToken,&gdiplusInput,NULL);
  625. //解析开关
  626. OptRE(argc, argv);
  627. //关闭Gdiplus
  628. GdiplusShutdown(gdipludToken);
  629. return 0;
  630. }
复制代码

作者: CrLf    时间: 2017-2-12 23:32

产量真高
你知道原创开源版块已经被你霸屏了吗...
作者: happy886rr    时间: 2017-2-13 01:17

回复 2# CrLf
多谢大师,代码很业余,只实现了部分简单功能,还有很多要写却没完成。
作者: codegay    时间: 2017-2-13 03:33

图真好看~~
作者: happy886rr    时间: 2017-2-13 11:38

回复 4# codegay
那些函数本来就长得很美,我只是让它在控制台上展现出来,因为cmd的黑背景很适合绘图。




欢迎光临 批处理之家 (http://bbs.bathome.net/) Powered by Discuz! 7.2