📄 builder.cpp
字号:
/************************************************************************************************************************************************************** **** equal III the graphic builder **** **** Copyright (C) 2003 Oleksiy Pylypenko **** **** This file may be distributed and/or modified under the terms of the **** GNU General Public License version 2 as published by the Free Software **** Foundation and appearing in the file license included in the **** packaging of this file. **** **** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE **** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. **** **** Contact earthman@inbox.ru if any conditions of this licensing are **** not clear to you. **** **** ********************************************************************************* *****************************************************************************/#include "equal_headers.h"#include "builder.h"static void ParseFunctionDefenition(string definition,double &priority,vector<string> &llist,string &name,vector<string> &rlist,string &equals){ char *def = (char *)definition.c_str(); priority = 10; { char *c = def; while((*c >= '0' && *c <= '9') || *c=='.' || *c == '+' || *c == '-')c++; if(*c == ':'){ priority = atof(def); def = c+1; } } char *eqsign = strstr(def,":="); if(eqsign < def) throw GraphicBuilder::errDefineFunction(); if(strstr(eqsign+2,":=") >= eqsign + 2) throw GraphicBuilder::errDefineFunction(); char *start_l_list=0,*end_l_list=0, *start_r_list=0,*end_r_list=0, *start_name=0,*end_name=0; int is_rlist = 0,is_llist = 0; char *c; for(c = def;c < eqsign;c++){ if((*c == ' ') || (*c == '\t') || (*c == '\n')) continue; if(*c == '('){ if(start_l_list == 0 && start_name == 0){ start_l_list = c+1; is_llist = 1; }else if(!is_llist && start_name){ start_r_list = c+1; is_rlist = 1; if(!end_name)end_name=c; }else{ throw GraphicBuilder::errDefineFunction(); } } else if(*c == ')'){ if(end_l_list == 0 && start_l_list){ end_l_list = c; is_llist = 0; }else if(end_r_list == 0 && start_r_list){ end_r_list = c; is_rlist = 0; }else{ throw GraphicBuilder::errDefineFunction(); } } if(*c != ')' && !is_llist && !is_rlist && end_r_list == 0){ if(start_name == 0){ start_name = c; }else{ end_name = c+1; } } } if(!end_name)end_name = eqsign; if(!(start_name && end_name)) throw GraphicBuilder::errDefineFunction(); // vector<string> llist,rlist; string temp; if(start_l_list){ for(c = start_l_list;c <= end_l_list;c++){ if(*c == ',' || c == end_l_list){ if(find(llist.begin(),llist.end(),temp) != llist.end()) throw GraphicBuilder::errDefineFunction(); llist.push_back(temp); temp = ""; }else{ temp += *c; } } } if(start_r_list) { for(c = start_r_list;c <= end_r_list;c++){ if(*c == ',' || c == end_r_list){ if(find(rlist.begin(),rlist.end(),temp) != rlist.end()) throw GraphicBuilder::errDefineFunction(); rlist.push_back(temp); temp = ""; }else{ temp += *c; } } } name = string(start_name,end_name); equals = string(eqsign+2);}enum Sign{Less,Greater,Equals,LessEqual,GreaterEqual,Nothing,Error};/*static Sign GetSign(string sys){ int pos = (int)sys.find("="); if(pos != -1){ if(GetSign(string(sys.begin()+pos+1,sys.end())) == Nothing) return Equals; else return Error; } pos = (int)sys.find(">"); if(pos != -1){ if(GetSign(string(sys.begin()+pos+1,sys.end())) == Nothing) return Greater; else return Error; } pos = (int)sys.find("<"); if(pos != -1){ if(GetSign(string(sys.begin()+pos+1,sys.end())) == Nothing) return Less; else return Error; } return Nothing;}*/static Sign GetSign(bPTI *p){ if(p->myType==bPTI::Function){ PTI_Function *f = (PTI_Function *)p; if(f->declaration.name == "<")return Less; if(f->declaration.name == ">")return Greater; if(f->declaration.name == "<=")return LessEqual; if(f->declaration.name == ">=")return GreaterEqual; if(f->declaration.name == "=")return Equals; } return Error;}void GraphicBuilder::MakeADefinition(string command){ double priority; vector<string> llist,rlist; string equals,name; ParseFunctionDefenition(string(command),priority,llist,name,rlist,equals); calculator.DefineFunction(name,llist,rlist,equals,priority);} void GraphicBuilder::DefineAVariable(string name,double *value){ calculator.DefineVariable(name,value);}void GraphicBuilder::DrawSystem(string system,ImageInfo info){ if(system.size() == 0)return; int i; int w = width,h = height; double *first = new double [w+1]; double *second = new double [w+1]; double *pfirst = first; double *psecond = second; int *flag_first = new int [w+1]; int *flag_second = new int [w+1]; int *flag_pfirst = flag_first; int *flag_psecond = flag_second; for(i = 0;i < w*h;i++)mask[i] = 1; int systemsBuilt = 0; pti_vec tree = calculator.CompileSystem(system);// double *result = calculator.PrepareCalculate(system); int n = tree.size(); for(i = 0;i < n;i++){ double *result = calculator.PrepareCalculate(*tree[i]); systemsBuilt++; switch(GetSign(tree[i])){ case (GreaterEqual): case(LessEqual): { DoubleRect from = {-1,-1,w,h},to = scale; double pa2mc_xc = (to.left - to.right) / (from.left - from.right); double pa2mc_yc = (to.top - to.bottom) / (from.top - from.bottom); mathx = to.left - pa2mc_xc / 2; mathy = to.top - pa2mc_yc / 2; for(int y = -1;y < h;y++){ for(int x = -1;x < w;x++){ int r = calculator.Calculate(); double r1 = *result; if(r)r1 = 0.; double nullconst = 0.; if(r1 > -1E-8 && r1 < -1E-8)r1 = nullconst; pfirst[x+1] = r1; flag_pfirst[x+1]=r; if(y >= 0 && x >= 0){ double r2 = pfirst[x]; double r3 = psecond[x]; double r4 = psecond[x+1]; int s = (r1 > 0) + (r2 > 0) + (r3 > 0) + (r4 > 0); if(r1 < 0.) s=1; if(nullconst == r1) s=1; if(s == 4 || s == 0 || r || flag_pfirst[x] || flag_psecond[x] || flag_psecond[x+1]) mask[x + y * w] = 0; } mathx += pa2mc_xc; } mathx = to.left - pa2mc_xc /2; mathy += pa2mc_yc; double *pswap = pfirst;pfirst = psecond;psecond = pswap; int *flag_pswap = flag_pfirst;flag_pfirst = flag_psecond;flag_psecond = flag_pswap; } } break; case(Greater): //trick with operator x>y <=> y-x //paradigm: less code - less errors... case(Less): { DoubleRect from = {0,0,w,h},to = scale; double pa2mc_xc = (to.left - to.right) / (from.left - from.right); double pa2mc_yc = (to.top - to.bottom) / (from.top - from.bottom); mathx = to.left - pa2mc_xc / 2; mathy = to.top - pa2mc_yc / 2; for(int y = 0;y < h;y++){ for(int x = 0;x < w;x++){ int r = calculator.Calculate(); if(!(*result < 0.) || r) mask[x + y * w] = 0; mathx += pa2mc_xc; } mathx = to.left - pa2mc_xc /2; mathy += pa2mc_yc; } } break; case Equals: { DoubleRect from = {-1,-1,w,h},to = scale; double pa2mc_xc = (to.left - to.right) / (from.left - from.right); double pa2mc_yc = (to.top - to.bottom) / (from.top - from.bottom); mathx = to.left - pa2mc_xc / 2; mathy = to.top - pa2mc_yc / 2; for(int y = -1;y < h;y++){ for(int x = -1;x < w;x++){ int r = calculator.Calculate(); double r1 = *result; if(r)r1 = 0.; double nullconst = 0.; if(r1 > -1E-8 && r1 < -1E-8)r1 = nullconst; pfirst[x+1] = r1; flag_pfirst[x+1]=r; if(y >= 0 && x >= 0){ double r2 = pfirst[x]; double r3 = psecond[x]; double r4 = psecond[x+1]; int s = (r1 > 0) + (r2 > 0) + (r3 > 0) + (r4 > 0); if(nullconst == r1) s=1; if(s == 4 || s == 0 || r || flag_pfirst[x] || flag_psecond[x] || flag_psecond[x+1]) mask[x + y * w] = 0; } mathx += pa2mc_xc; } mathx = to.left - pa2mc_xc /2; mathy += pa2mc_yc; double *pswap = pfirst;pfirst = psecond;psecond = pswap; int *flag_pswap = flag_pfirst;flag_pfirst = flag_psecond;flag_psecond = flag_pswap; } } break; default: throw errSignError(); } } delete first; delete second; delete flag_first; delete flag_second; free_ptree(tree); if(systemsBuilt > 0) for(int x = 0;x < w;x++) for(int y = 0;y < h;y++){ int pos = x + y * w; if(mask[pos]) image[pos] = info; } } void GraphicBuilder::Init(void){ image = new ImageInfo[width * height]; mask = new char[width*height]; for(int i = 0;i < width*height;i++)mask[i] = 0, image[i] = background; calculator.Init(); //vector<string> left,right; //left.push_back("x"); //right.push_back("y"); calculator.DefineVariable("x",&mathx); calculator.DefineVariable("y",&mathy); FunctionDeclaration decl("",1,1,-100.,FunctionDeclaration::LR); decl.skipPreCalcOptimization = true; decl.name = "=";calculator.acontext.func_decl.push_back(decl); decl.name = "<";calculator.acontext.func_decl.push_back(decl); decl.name = ">";calculator.acontext.func_decl.push_back(decl); decl.name = "<=";calculator.acontext.func_decl.push_back(decl); decl.name = ">=";calculator.acontext.func_decl.push_back(decl);// calculator.DefineFunction("<",left,right,"x-y",-100);// calculator.DefineFunction(">",left,right,"y-x",-100);// calculator.DefineFunction("=",left,right,"x-y",-100);}void GraphicBuilder::Free(void){ if(image)delete image;image = 0; if(mask)delete mask;mask = 0; calculator.Free();}GraphicBuilder::GraphicBuilder(void){ image = 0; background.info = 0; mask = 0; scale.top = scale.left = scale.right = scale.bottom = 0; width = height = 0;}GraphicBuilder::~GraphicBuilder(){ Free();}/*void main(void){ try{ GraphicBuilder builder; builder.width = 600; builder.height = 600; builder.scale.left = -10; builder.scale.top = 10; builder.scale.right = 10; builder.scale.bottom = -10; builder.background.info = 0; builder.Init(); vector<string> s; s.push_back("y = {x} ");// s.push_back("y>-3"); GraphicBuilder::ImageInfo color = {1}; builder.DrawSystem(s,color); s.clear();// GraphicBuilder::ImageInfo color2 = {255,0,0,255};// s.push_back("y={x*}");// builder.Graphics(s,color2); FILE *fp = fopen("a.raw","w"); for(int i = 0;i < builder.width*builder.height;i++){ unsigned char rgb[3] = { builder.image[i].info == 0 ? 0 : 255, builder.image[i].info == 0 ? 0 : 255, builder.image[i].info == 0 ? 0 : 255 }; fwrite(rgb,sizeof(unsigned char),3,fp); } fclose(fp); builder.Free(); }catch(...){ printf("error\n"); }}*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -