├── Chortke.c ├── Libs ├── Processing.c ├── Processing.h ├── Stack.c ├── Stack.h ├── UI.c ├── UI.h ├── bitmap_ploter.c └── bitmap_ploter.h ├── Makefile ├── README.md ├── configs └── Chortke.config └── plot.bmp /Chortke.c: -------------------------------------------------------------------------------- 1 | #include "./Libs/Processing.h" 2 | #include "./Libs/UI.h" 3 | #include "./Libs/bitmap_ploter.h" 4 | #include 5 | #include 6 | #include 7 | 8 | #define MAX_CHAR_SIZE 100000 9 | #define SIZE 1000 10 | #define ACCURACY 0.01 11 | #define STEP_SIZE 0.01 12 | #define INTERVAL_NUMBER 10000 13 | 14 | #ifdef _WIN32 15 | #define SHOW_PLOT "plot.bmp" 16 | #else 17 | #define SHOW_PLOT "display plot.bmp" 18 | #endif 19 | 20 | int main(){ 21 | char option, buffer[MAX_CHAR_SIZE]; 22 | int is_continue = 1, is_quit = 0, is_end = 0;// radius flag showing if wrong input is inputed or not. 23 | float y, radius, tmp_r; 24 | int axis_color, screen_color, plot_color, tmp_axc, tmp_plc, tmp_scrn; 25 | do{ 26 | //Initial the configs of graph | defined in UI.c 27 | get_graph_configs(&radius, &axis_color, &screen_color, &plot_color); 28 | clear(); 29 | greeting(); 30 | option = Choose();//A UI.c function to let user choose the type he wants to work with. 31 | switch(option){ 32 | case 'e': 33 | do{ 34 | is_continue = 1, is_quit = 0; 35 | printf("= "); 36 | fgets(buffer, MAX_CHAR_SIZE, stdin); 37 | is_quit = to_token(buffer); 38 | if(is_continue && !is_quit) 39 | y = calculate_equation(0, 0, &is_continue);//No need for x. 40 | if(is_continue && is_quit == 0) 41 | printf("%f\n", y); 42 | }while(is_quit != 1); 43 | 44 | break; 45 | case 'g': 46 | do{ 47 | printf("y = "); 48 | fgets(buffer, MAX_CHAR_SIZE, stdin); 49 | is_quit = to_token(buffer); 50 | /*-- Go for different x --*/ 51 | if(is_continue && !is_quit){ 52 | char plot[SIZE][SIZE] = {0}; 53 | float step = 2 * radius / SIZE; 54 | for (float x = -radius; x < radius; x += step) { 55 | is_continue = 1; 56 | y = calculate_equation(x, 0, &is_continue); 57 | if(is_continue){ 58 | int i = (x + radius) / step; 59 | if (i > SIZE - 1) i = SIZE - 1; 60 | if (i < 0) i = 0; 61 | int j = (y + radius) / step; 62 | if (j > SIZE - 1 || j < 0) continue; 63 | plot[i][j] = 1; 64 | } 65 | } 66 | 67 | write_bitmap((char *)plot, SIZE, SIZE, axis_color, screen_color, plot_color, "plot.bmp"); 68 | system(SHOW_PLOT); 69 | } 70 | }while(is_quit != 1); 71 | break; 72 | case 'p': 73 | do{ 74 | printf("0 = "); 75 | fgets(buffer, MAX_CHAR_SIZE, stdin); 76 | is_quit = to_token(buffer); 77 | /*-- Go for different x --*/ 78 | if(is_continue && !is_quit){ 79 | char plot[SIZE][SIZE] = {0}; 80 | float step = 2 * radius / SIZE; 81 | for (float x = -radius; x < radius; x += step) { 82 | for (float y_r = -radius; y_r < radius; y_r += step) { 83 | is_continue = 1; 84 | y = calculate_equation(x, y_r, &is_continue); 85 | if(is_continue){ 86 | if((y > 0 ? y : (-1) * y) < 0.05){ 87 | int i = (x + radius) / step; 88 | if (i > SIZE - 1) i = SIZE - 1; 89 | if (i < 0) i = 0; 90 | int j = (y_r + radius) / step; 91 | if (j > SIZE - 1 || j < 0) continue; 92 | plot[i][j] = 1; 93 | } 94 | } 95 | } 96 | } 97 | 98 | write_bitmap((char *)plot, SIZE, SIZE, axis_color, screen_color, plot_color, "plot.bmp"); 99 | system(SHOW_PLOT); 100 | } 101 | }while(is_quit != 1); 102 | break; 103 | case 's': 104 | do{ 105 | int nthx = 1; 106 | printf("0 = "); 107 | fgets(buffer, MAX_CHAR_SIZE, stdin); 108 | is_quit = to_token(buffer); 109 | /*-- Go for different x --*/ 110 | if(is_continue && !is_quit){ 111 | for (float x = -radius; x < radius; x += STEP_SIZE) { 112 | is_continue = 1; 113 | y = calculate_equation(x, 0, &is_continue); 114 | if(is_continue) 115 | if( (y > 0 ? y : (-1) * y) < ACCURACY){ 116 | printf("X%d: %0.3f\n", nthx, x); 117 | nthx++; 118 | } 119 | } 120 | if(nthx == 1) 121 | printf("No answer for x in the domain with accurecy of %f.\n", ACCURACY); 122 | } 123 | }while(is_quit != 1); 124 | break; 125 | case 'i': 126 | do{ 127 | float a, b, integral = 0; 128 | char main_stream[MAX_CHAR_SIZE]; 129 | printf("y = "); 130 | fgets(buffer, MAX_CHAR_SIZE, stdin); 131 | strcpy(main_stream, buffer); 132 | is_quit = to_token(main_stream); 133 | /*-- Go for different x --*/ 134 | if(is_continue && !is_quit){ 135 | printf("a = "); 136 | fgets(buffer, MAX_CHAR_SIZE, stdin); 137 | to_token(buffer);//Biasing stacks 138 | y = calculate_equation(0, 0, &is_continue); 139 | if(is_continue) 140 | a = y; 141 | printf("b = "); 142 | fgets(buffer, MAX_CHAR_SIZE, stdin); 143 | to_token(buffer);//Biasing stacks 144 | y = calculate_equation(0, 0, &is_continue); 145 | if(is_continue) 146 | b = y; 147 | float step = (b - a) / INTERVAL_NUMBER;//(b - a) / n 148 | to_token(main_stream);//Biasing stacks 149 | for (float x = a; x <=b; x += step) { 150 | is_continue = 1; 151 | y = calculate_equation(x, 0, &is_continue); 152 | if(is_continue) 153 | integral += y * step;//sigma of f(x*)dx 154 | } 155 | if(is_continue){ 156 | main_stream[strlen(main_stream) - 1] = 0; 157 | printf("S(%s)dx = %.4f\n", main_stream, integral); 158 | } 159 | } 160 | }while(is_quit != 1); 161 | break; 162 | case 'c': 163 | if(show_config(radius, axis_color, screen_color, plot_color) == 'y'){ 164 | printf("Enter radius of your plotting(-r < x < r): "); 165 | scanf("%f", &tmp_r); 166 | printf("Enter color of axis(without 0x): "); 167 | scanf("%x", &tmp_axc); 168 | printf("Enter color of screen_color(without 0x): "); 169 | scanf("%x", &tmp_scrn); 170 | printf("Enter color of plot(without 0x): "); 171 | scanf("%x", &tmp_plc); 172 | set_graph_configs(tmp_r, tmp_axc, tmp_scrn, tmp_plc); 173 | } 174 | break; 175 | 176 | case 'q': 177 | is_end = 1; 178 | break; 179 | 180 | } 181 | }while(!is_end); 182 | return 0; 183 | } 184 | -------------------------------------------------------------------------------- /Libs/Processing.c: -------------------------------------------------------------------------------- 1 | /* 2 | Main source code of "Chortke" 3 | */ 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "Stack.h" 9 | 10 | #define MAX_CHAR_SIZE 10000 11 | #define MAX_TOKEN 10000 12 | #define MAX_NUBER_SIZE 20 13 | #define pi_official_num "3.1415926536" 14 | #define e_official_num "2.7182818285" 15 | 16 | char tokens[MAX_TOKEN][MAX_NUBER_SIZE], num_tmp[MAX_TOKEN];//Token array | temporary string for number. 17 | int n; 18 | 19 | int anti_space(char *spaced_one,char *none_spaced_one); 20 | int check(char *str); 21 | int is_ok(int x); 22 | int is_operator(char c); 23 | int is_digit(char c); 24 | char to_forward(char* str, int i); 25 | char to_downward(char* str, int i); 26 | void error(char* buffer); 27 | int calc(); 28 | int is_num(char str[]); 29 | int get_precendence(char op); 30 | int factorial(int num); 31 | int check_function(char *checking_pointer, const char * funtion_to_be_checked, char *tokens, int *pt_n, int *pt_k,char* buffer); 32 | int to_token(char* buffer); 33 | float calculate_equation(float x, float y, int *is_con); 34 | void set_lower(char* spaced_one); 35 | 36 | int to_token(char* buffer){ 37 | char main_stream[MAX_CHAR_SIZE]; 38 | n = 0;// 39 | initial(); 40 | if(anti_space(buffer, main_stream)){ 41 | if(!strcmp(main_stream, "quit")) 42 | return 1; 43 | if(is_ok(check(main_stream))){ 44 | char c; 45 | int i = 0, k = 0; 46 | while( (c = main_stream[k]) != 0){ 47 | if(is_digit(c) || c == '.')//if character is number of dots. 48 | num_tmp[i++] = c; 49 | else{ 50 | switch(c){ 51 | case '-': 52 | if(k == 0 || main_stream[k - 1] == '(') // negetive numbers. 53 | num_tmp[i++] = c; 54 | else{ 55 | if(i != 0){ 56 | num_tmp[i] = 0; 57 | strcpy(tokens[n++], num_tmp); 58 | } 59 | tokens[n][0]= c; 60 | tokens[n++][1] = 0; // To make it string. 61 | i = 0; 62 | } 63 | break; 64 | //All operators: 65 | case '+': 66 | case '*': 67 | case '/': 68 | case '^': 69 | case '!': 70 | case '(': 71 | case ')': 72 | if(i != 0){ 73 | num_tmp[i] = 0; 74 | strcpy(tokens[n++], num_tmp); 75 | } 76 | tokens[n][0]= c; 77 | tokens[n++][1] = 0; // To make it string. 78 | i = 0; 79 | break; 80 | case 'p': 81 | if(!strncmp(main_stream + k, "pi", 2)) 82 | { 83 | strcpy(tokens[n++], pi_official_num); 84 | k = k + 1; 85 | } 86 | else{ 87 | error(buffer); 88 | return 2; 89 | } 90 | break; 91 | 92 | case 's': 93 | //check_function(main_stream + k, "sin", tokens, &n, &k, buffer); 94 | if(!strncmp(main_stream + k, "sin", 3)) 95 | { 96 | strcpy(tokens[n++], "sin"); 97 | k = k + 2; 98 | } 99 | else{ 100 | error(buffer); 101 | return 2; 102 | } 103 | break; 104 | 105 | case 'c': 106 | if(!strncmp(main_stream + k, "cos", 3)) 107 | { 108 | strcpy(tokens[n++], "cos"); 109 | k = k + 2; 110 | } 111 | else{ 112 | error(buffer); 113 | return 2; 114 | } 115 | break; 116 | 117 | case 't': 118 | if(!strncmp(main_stream + k, "tan", 3)) 119 | { 120 | strcpy(tokens[n++], "tan"); 121 | k = k + 2; 122 | } 123 | 124 | else{ 125 | error(buffer); 126 | return 2; 127 | } 128 | break; 129 | 130 | case 'e': 131 | if(!strncmp(main_stream + k, "exp", 3)) 132 | { 133 | strcpy(tokens[n++], "exp"); 134 | k = k + 2; 135 | } 136 | else if (!strncmp(main_stream + k, "e", 1)) 137 | strcpy(tokens[n++], e_official_num); 138 | else{ 139 | error(buffer); 140 | return 2; 141 | } 142 | break; 143 | 144 | case 'l': 145 | if(!strncmp(main_stream + k, "ln", 2)) 146 | { 147 | strcpy(tokens[n++], "ln"); 148 | k = k + 1; 149 | } 150 | else{ 151 | error(buffer); 152 | return 2; 153 | } 154 | break; 155 | 156 | case 'a': 157 | if(!strncmp(main_stream + k, "abs", 3)) 158 | { 159 | strcpy(tokens[n++], "abs"); 160 | k = k + 2; 161 | } 162 | 163 | else{ 164 | error(buffer); 165 | return 2; 166 | } 167 | break; 168 | 169 | case 'x'://Variable 170 | tokens[n][0]= c; 171 | tokens[n++][1] = 0; // To make it string. 172 | break; 173 | case 'y'://Variable 174 | tokens[n][0]= c; 175 | tokens[n++][1] = 0; // To make it string. 176 | break; 177 | default ://For future developments. 178 | error(buffer); 179 | return 2; 180 | break; 181 | 182 | } 183 | } 184 | k++; 185 | } 186 | if(i != 0){ 187 | num_tmp[i] = 0; 188 | strcpy(tokens[n++], num_tmp); 189 | } 190 | /* -- Token process has been completed -- */ 191 | } 192 | else 193 | return 2;//If string isn't ok. 194 | } 195 | 196 | 197 | return 0; 198 | } 199 | 200 | float calculate_equation(float x,float y, int *is_con){ 201 | /* ---- For testing Token part --- 202 | for(int i = 0; i < n; i++) 203 | printf("%s\n", tokens[i]); 204 | */ 205 | /* ---- For testing stack ---- 206 | push_n(3.1415); 207 | push_c('+'); 208 | push_n(1.2); 209 | calc(); 210 | printf("%f", pop_n()); 211 | */ 212 | int index = 0; 213 | char next_token[MAX_NUBER_SIZE]; 214 | while(index < n) 215 | { 216 | strcpy(next_token, tokens[index]); 217 | if(is_num(next_token)) 218 | push_n(atof(next_token)); 219 | else if(next_token[0] == 'x') 220 | push_n(x); 221 | else if(next_token[0] == 'y') 222 | push_n(y); 223 | else if(next_token[0] == '(') 224 | push_c('('); 225 | else if(next_token[0] == ')'){ 226 | while (get_top() != '(') 227 | if(!calc()) 228 | *is_con = 0; 229 | pop_c();//Discarding Left parentheses 230 | } 231 | else{//It should be an operator 232 | while(get_i_c() != -1 && get_precendence(get_top()) >= get_precendence(next_token[0])) 233 | if(!calc()) 234 | *is_con = 0; 235 | push_c(next_token[0]);//s for sin, c for cos 236 | } 237 | index++; 238 | } 239 | while(get_i_c() != -1) 240 | { 241 | if(!calc()){ 242 | *is_con = 0; 243 | } 244 | } 245 | return pop_n(); 246 | } 247 | /* 248 | int check_function(char *checking_pointer, const char * funtion_to_be_checked, char *tokens, int *pt_n, int *pt_k,char* buffer){ 249 | if(!strncmp(checking_pointer, funtion_to_be_checked, strlen(funtion_to_be_checked))) 250 | { 251 | strcpy(tokens[(*pt_n)++], funtion_to_be_checked); 252 | *pt_k += strlen(funtion_to_be_checked); 253 | } 254 | else 255 | error(buffer); 256 | } 257 | */ 258 | int anti_space(char *spaced_one,char *none_spaced_one){ 259 | int i = 0, j = 0; 260 | set_lower(spaced_one); 261 | while(*(spaced_one + i) != '\n'){ 262 | if(*(spaced_one + i) != ' '){ 263 | *(none_spaced_one + j) = *(spaced_one + i); 264 | j++; 265 | } 266 | else if(is_digit(to_forward(spaced_one, i)) && is_digit(to_downward(spaced_one, i))){ 267 | //Just for 5 6 2 = 562 mode 268 | puts("Mistaken numbers!"); 269 | return 0; 270 | } 271 | i++; 272 | } 273 | *(none_spaced_one + j) = 0; 274 | return 1; 275 | } 276 | 277 | /*--- Function for impressing errors ---*/ 278 | int check(char *str){ 279 | int i = 0, paran = 0; 280 | char c = *str; 281 | if(c == 0) 282 | return 6; 283 | if(is_operator(c) && c != '-') 284 | return 5; 285 | while(c != 0){ 286 | if(c == '('){ 287 | if(*(str + i + 1)==')') 288 | return 8; 289 | if (i != 0 && is_digit(*(str + i - 1))) 290 | return 4; 291 | if(is_operator(*(str + i + 1)) && *(str + i + 1) != '-') 292 | return 5; 293 | paran++; 294 | } 295 | else if(c == ')'){ 296 | if (*(str + i + 1) != 0 && is_digit(*(str + i + 1))) 297 | return 4; 298 | paran--; 299 | if (paran < 0) 300 | return 1; 301 | } 302 | else if(c == '.'){ 303 | if(*(str + i + 1) == '.') 304 | return 7; 305 | } 306 | if((is_digit(c) || c == '.') && (*(str + i + 1) == 'x' || *(str + i + 1) == 'y')) 307 | return 4; 308 | if((c == 'x' || c == 'y') && (is_digit(*(str + i + 1)) || *(str + i + 1) == '.')) 309 | return 4; 310 | if(is_operator(c) && is_operator(*(str + i + 1)) && c != '!') 311 | return 2; 312 | c = *(str + ++i); 313 | } 314 | if(is_operator(*(str + i - 1)) && *(str + i - 1) != '!') 315 | return 3; 316 | if(paran != 0) 317 | return 1; 318 | return 0; 319 | } 320 | int is_ok(int x){ 321 | switch(x){ 322 | case 0: 323 | return 1; 324 | break; 325 | case 1: 326 | puts("Parentheses not match!"); 327 | return 0; 328 | break; 329 | case 2: 330 | puts("Operator collision!"); 331 | return 0; 332 | break; 333 | case 3: 334 | puts("Ends with operator!"); 335 | return 0; 336 | break; 337 | case 4: 338 | puts("multiply operator (*) missed!"); 339 | return 0; 340 | break; 341 | case 5: 342 | puts("Starts with operator!"); 343 | return 0; 344 | break; 345 | case 6: 346 | return 0; 347 | case 7: 348 | puts("double dot (..) collision!"); 349 | return 0; 350 | break; 351 | case 8: 352 | puts("empty parentheses!"); 353 | return 0; 354 | break; 355 | } 356 | } 357 | int is_operator(char c){ 358 | if(c == '+' ||c == '-' ||c == '*' ||c == '/' ||c == '^'||c == '!') 359 | return 1; 360 | return 0; 361 | } 362 | int is_digit(char c){ 363 | if(c >= '0' && c <= '9') 364 | return 1; 365 | return 0; 366 | } 367 | char to_forward(char* str, int i){ 368 | int j = i; 369 | while(*(str + j) != 0){ 370 | if(*(str + j) != ' ') 371 | return *(str + j); 372 | j++; 373 | } 374 | } 375 | char to_downward(char* str, int i){ 376 | int j = i; 377 | while(j >= 0) 378 | { 379 | if(*(str + j) != ' ') 380 | return *(str + j); 381 | j--; 382 | } 383 | return 0; 384 | } 385 | void error(char* buffer){ 386 | puts("Wrong input!"); 387 | int i = 0; 388 | while(*(buffer + i) != '\n') 389 | putchar(*(buffer + i++)); 390 | puts(" khodeti :D."); 391 | } 392 | int calc(){ 393 | char operator = pop_c(); 394 | float op1, op2; 395 | switch(operator){ 396 | case '+': 397 | op1 = pop_n(); 398 | op2 = pop_n(); 399 | push_n(op1 + op2); 400 | break; 401 | case '-': 402 | op1 = pop_n(); 403 | op2 = pop_n(); 404 | push_n(op2 - op1); 405 | break; 406 | case '*': 407 | op1 = pop_n(); 408 | op2 = pop_n(); 409 | push_n(op1 * op2); 410 | break; 411 | case '/': 412 | op1 = pop_n(); 413 | op2 = pop_n(); 414 | if(op1 == 0) 415 | { 416 | puts("Divided by 0! :D"); 417 | return 0; 418 | } 419 | push_n(op2 / op1); 420 | break; 421 | case '^': 422 | op1 = pop_n(); 423 | op2 = pop_n(); 424 | push_n(pow(op2, op1)); 425 | break; 426 | 427 | case 's': // Sin () 428 | op1 = pop_n(); 429 | push_n(sin(op1)); 430 | break; 431 | case 'c': // Cos () 432 | op1 = pop_n(); 433 | push_n(cos(op1)); 434 | break; 435 | case 't': // Tan () 436 | op1 = pop_n(); 437 | push_n(tan(op1)); 438 | break; 439 | case 'e': // exp () 440 | op1 = pop_n(); 441 | push_n(exp(op1)); 442 | break; 443 | case 'l':// ln() 444 | op1 = pop_n(); 445 | if(op1 <= 0) 446 | { 447 | puts("Out of Ln's domain."); 448 | return 0; 449 | } 450 | push_n(log(op1)); 451 | break; 452 | case 'a':// abs () 453 | op1 = pop_n(); 454 | if (op1 >= 0) 455 | push_n(op1); 456 | else 457 | push_n(-op1); 458 | break; 459 | case '!': //factorial () 460 | op1 = pop_n(); 461 | op2 = (int)op1; 462 | if(op1 == op2) 463 | push_n(factorial(op2)); 464 | else { 465 | puts("Can't calculate the factorial of a decimal number."); 466 | return 0; 467 | } 468 | break; 469 | return 1; 470 | } 471 | } 472 | int is_num(char str[]){ 473 | if(is_digit(str[0])) 474 | return 1; 475 | else if(str[0] == '-' && is_digit(str[1])) 476 | return 1; 477 | else 478 | return 0; 479 | } 480 | int get_precendence(char op){ 481 | switch(op) 482 | { 483 | case '-': 484 | case '+': 485 | return 0; 486 | break; 487 | case '*': 488 | case '/': 489 | return 1; 490 | break; 491 | case '^': 492 | case '!': 493 | return 2; 494 | break; 495 | case '(': 496 | return -2; 497 | break; 498 | default ://sin cos tan exp ln abs 499 | return -1; 500 | break; 501 | } 502 | } 503 | int factorial(int num) { 504 | int result = 1; 505 | for(int i = num; i >= 1; i--) { 506 | result *= i; 507 | } 508 | return result; 509 | } 510 | void set_lower(char* spaced_one){ 511 | int i = 0; 512 | while(spaced_one[i] != 0){ 513 | if(spaced_one[i] >= 'A' && spaced_one[i] <= 'Z') 514 | spaced_one[i] = spaced_one[i] - ('A' - 'a'); 515 | i++; 516 | } 517 | } -------------------------------------------------------------------------------- /Libs/Processing.h: -------------------------------------------------------------------------------- 1 | #ifndef CHORTKE_H_ 2 | #define CHORTKE_H_ 3 | 4 | int anti_space(char *spaced_one,char *none_spaced_one); 5 | int check(char *str); 6 | int is_ok(int x); 7 | int is_operator(char c); 8 | int is_digit(char c); 9 | char to_forward(char* str, int i); 10 | char to_downward(char* str, int i); 11 | void error(char* buffer); 12 | int calc(); 13 | int is_num(char str[]); 14 | int get_precendence(char op); 15 | int factorial(int num); 16 | int check_function(char *checking_pointer, const char * funtion_to_be_checked, char *tokens, int *pt_n, int *pt_k,char* buffer); 17 | int to_token(char* buffer); 18 | float calculate_equation(float x,float y, int *is_con); 19 | void set_lower(char* spaced_one); 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /Libs/Stack.c: -------------------------------------------------------------------------------- 1 | /* 2 | Stack code 3 | */ 4 | 5 | #include "Stack.h" 6 | 7 | #define SIZE 50 8 | 9 | struct oprand_stacks { 10 | int i; 11 | float stack[SIZE]; 12 | } numbers;//Stack for float numbers. 13 | 14 | struct operator_stacks { 15 | int i; 16 | char stack[SIZE]; 17 | } chars;//Stack for characters. 18 | void initial(); 19 | float pop_n(); 20 | void push_n(float x);// x : the number wanted to be pushed. 21 | int get_i_n(); 22 | 23 | char pop_c(); 24 | char get_top(); 25 | void push_c(char x);// x : the character wanted to be pushed. 26 | char show_last_c(); 27 | int get_i_c(); 28 | 29 | 30 | int get_i_n(){ 31 | return numbers.i; 32 | } 33 | int get_i_c(){ 34 | return chars.i; 35 | } 36 | 37 | 38 | 39 | float pop_n(){ 40 | if (numbers.i >= 0) // Stack isn't empty! 41 | return numbers.stack[numbers.i--];//pop the late added number to numbers and move pointer one block back. 42 | } 43 | void push_n(float x){ 44 | numbers.stack[++numbers.i] = x;//set the (i+1)th block to x and then move pointer one block forward. 45 | } 46 | 47 | 48 | 49 | char pop_c(){ 50 | if (chars.i >= 0) // Stack isn't empty! 51 | return chars.stack[chars.i--];//pop the late added number to numbers and move pointer one block back. 52 | } 53 | char get_top(){ 54 | if (chars.i >= 0) // Stack isn't empty! 55 | return chars.stack[chars.i];//pop the late added number to numbers. 56 | } 57 | void push_c(char x){ 58 | chars.stack[++chars.i] = x;//set the (i+1)th block to x and then move pointer one block forward. 59 | } 60 | 61 | char show_last_c(){ 62 | if (chars.i >= 0) // Stack isn't empty! 63 | return chars.stack[chars.i];//get back the last one. 64 | else 65 | return -1; 66 | } 67 | void initial(){ 68 | numbers.i = -1; 69 | chars.i = -1; 70 | } 71 | 72 | /* 73 | --- For testing stack.h --- 74 | int main(){ 75 | push_c('+'); 76 | push_c('-'); 77 | push_c('*'); 78 | push_c('/'); 79 | 80 | push_n(1.22); 81 | push_n(1.254); 82 | push_n(455.1); 83 | push_n(2.4); 84 | printf("%f %c\n", pop_n(), pop_c()); 85 | 86 | printf("%f %c\n", pop_n(), pop_c()); 87 | 88 | printf("%f %c\n", pop_n(), pop_c()); 89 | 90 | printf("%f %c\n", pop_n(), pop_c()); 91 | return 0; 92 | } 93 | */ 94 | -------------------------------------------------------------------------------- /Libs/Stack.h: -------------------------------------------------------------------------------- 1 | #ifndef STACK_H_ 2 | #define STACK_H_ 3 | 4 | void initial(); 5 | float pop_n(); 6 | void push_n(float x);// x : the number wanted to be pushed. 7 | int get_i_n(); 8 | 9 | char pop_c(); 10 | void push_c(char x);//x : the number wanted to be pushed. 11 | char get_top(); 12 | int get_i_c(); 13 | char show_last_c(); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /Libs/UI.c: -------------------------------------------------------------------------------- 1 | /* 2 | Our library for interacting with user: 3 | */ 4 | #include 5 | #include 6 | #include 7 | 8 | #include "UI.h" 9 | #include "Processing.h" 10 | 11 | #define CONFIG_DIR "./configs/Chortke.config" 12 | 13 | #ifdef _WIN32 14 | #define CLEAR_SCREEN "cls" 15 | #else 16 | #define CLEAR_SCREEN "clear" 17 | #endif 18 | //Prototypes : 19 | char Choose(); 20 | void clear(); 21 | void greeting(); 22 | void bye(); 23 | int input(); 24 | void output(char output_str[10000]); 25 | char show_config(float radius, int axis_color,int screen_color, int plot_color); 26 | void get_graph_configs(float *radius, int *axis_color, int *screen_color, int *plot_color); 27 | void set_graph_configs(float radius, int axis_color, int screen_color, int plot_color); 28 | 29 | void clear(){ 30 | system(CLEAR_SCREEN); 31 | } 32 | 33 | void greeting() 34 | { 35 | 36 | #ifdef _WIN32 37 | system("title Chortke"); 38 | #endif 39 | puts("\x1b[31m""Welcome to \"Chortke\"! :D""\x1b[0m"); 40 | } 41 | 42 | char Choose() 43 | { 44 | char str[10]; 45 | puts("Choose a character to surf into different parts of Chortke:"); 46 | puts("e : for entering numerical equation"); 47 | puts("g : for graphing function(y = f(x))"); 48 | puts("p : for plotting equation(0 = f(x,y))"); 49 | puts("s : for solving equation for x"); 50 | puts("c : for see/change configure your plot"); 51 | puts("i : for evaluating integral of y = f(x) from a to b"); 52 | puts("q : for quiting from Chortke :("); 53 | fgets(str, 10, stdin); 54 | return str[0]; 55 | } 56 | int input() 57 | { 58 | } 59 | 60 | void output(char output_str[10000]) 61 | { 62 | puts(output_str); 63 | } 64 | 65 | void bye() 66 | { 67 | char str[] = "Bye!\nCome back Soon ;)"; // Add description! 68 | puts(str); 69 | } 70 | void get_graph_configs(float *radius, int *axis_color, int *screen_color, int *plot_color){ 71 | FILE *file_pointer; 72 | file_pointer = fopen(CONFIG_DIR, "r"); 73 | if(file_pointer != NULL){ 74 | fread(radius, sizeof(float), 1, file_pointer); 75 | fread(axis_color, sizeof(float), 1, file_pointer); 76 | fread(plot_color, sizeof(float), 1, file_pointer); 77 | fread(screen_color, sizeof(float), 1, file_pointer); 78 | fclose(file_pointer); 79 | } 80 | } 81 | void set_graph_configs(float radius, int axis_color,int screen_color, int plot_color){ 82 | FILE *file_pointer; 83 | file_pointer = fopen(CONFIG_DIR, "w"); 84 | fwrite(&radius, sizeof(float), 1, file_pointer); 85 | fwrite(&axis_color, sizeof(float), 1, file_pointer); 86 | fwrite(&plot_color, sizeof(float), 1, file_pointer); 87 | fwrite(&screen_color, sizeof(float), 1, file_pointer); 88 | fclose(file_pointer); 89 | } 90 | 91 | char show_config(float radius, int axis_color,int screen_color, int plot_color){ 92 | char choice; 93 | puts("---------------------Configuration---------------------"); 94 | printf("x Domain : -%.2f < x < %.2f\naxis color: 0x%06x\nscreen color:0x%06x\nplot color: 0x%06x\n", radius, radius, axis_color, screen_color, plot_color); 95 | puts("-------------------------------------------------------"); 96 | printf("Do you want to change it?(y/n):"); 97 | scanf(" %c", &choice); 98 | return choice; 99 | } 100 | /* 101 | Sharif university of technology 102 | Fall 2018 103 | Bubble Team! 104 | */ 105 | -------------------------------------------------------------------------------- /Libs/UI.h: -------------------------------------------------------------------------------- 1 | #ifndef UI_H_ 2 | #define UI_H_ 3 | 4 | char Choose(); 5 | void clear(); 6 | void greeting(); 7 | void bye(); 8 | int input(); 9 | void output(char output_str[10000]); 10 | char show_config(float radius, int axis_color,int screen_color, int plot_color); 11 | void get_graph_configs(float *radius, int *axis_color, int *screen_color, int *plot_color); 12 | void set_graph_configs(float radius, int axis_color, int screen_color, int plot_color); 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /Libs/bitmap_ploter.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "bitmap_ploter.h" 6 | 7 | void write_bitmap(char *plot, int width, int height, int axis_color,int screen_color, int plot_color, const char *filename) { 8 | FILE *f; 9 | unsigned char *img = NULL; 10 | int filesize = 54 + 3 * width * height, is_on; 11 | int axis_colors[3]; 12 | axis_colors[2] = axis_color % 0x100; 13 | axis_color /= 0x100; 14 | axis_colors[1] = axis_color % 0x100; 15 | axis_color /= 0x100; 16 | axis_colors[0] = axis_color % 0x100; 17 | 18 | int plot_colors[3]; 19 | plot_colors[2] = plot_color % 0x100; 20 | plot_color /= 0x100; 21 | plot_colors[1] = plot_color % 0x100; 22 | plot_color /= 0x100; 23 | plot_colors[0] = plot_color % 0x100; 24 | 25 | int screen_colors[3]; 26 | 27 | screen_colors[2] = screen_color % 0x100; 28 | screen_color /= 0x100; 29 | screen_colors[1] = screen_color % 0x100; 30 | screen_color /= 0x100; 31 | screen_colors[0] = screen_color % 0x100; 32 | 33 | img = (unsigned char *) malloc(3 * width * height);//Reserve 3*width*height bytes from memory. 34 | memset(img, 0, 3 * width * height);//set all reserved memory with 0. 35 | 36 | int r, g, b; 37 | for(int i = 0; i < width; i++) { 38 | for(int j = 0; j < height; j++) { 39 | int x = i, y = j; 40 | is_on = plot[i * width + j]; 41 | // simply plot[i][j]*255 | if r is plot[i][j] = 0 r is zero else if plot[i][j] = 1 r is 255. 42 | if(is_on == 1){ 43 | r = plot_colors[0]; 44 | g = plot_colors[1]; 45 | b = plot_colors[2]; 46 | } 47 | else{ 48 | r = screen_colors[0]; 49 | g = screen_colors[1]; 50 | b = screen_colors[2]; 51 | } 52 | if (x == height / 2 || y == width / 2){//axis lines 53 | r = axis_colors[0]; 54 | g = axis_colors[1]; 55 | b = axis_colors[2]; 56 | } 57 | if (r > 255) r = 255; 58 | if (g > 255) g = 255; 59 | if (b > 255) b = 255; 60 | img[(x + y * width) * 3 + 2] = (unsigned char)(r); 61 | img[(x + y * width) * 3 + 1] = (unsigned char)(g); 62 | img[(x + y * width) * 3 + 0] = (unsigned char)(b); 63 | } 64 | } 65 | 66 | unsigned char bmpfileheader[14] = {'B','M', 0,0,0,0, 0,0, 0,0, 54,0,0,0}; 67 | unsigned char bmpinfoheader[40] = {40,0,0,0, 0,0,0,0, 0,0,0,0, 1,0, 24,0}; 68 | unsigned char bmppad[3] = {0,0,0}; 69 | 70 | bmpfileheader[ 2] = (unsigned char)(filesize ); 71 | bmpfileheader[ 3] = (unsigned char)(filesize>> 8); 72 | bmpfileheader[ 4] = (unsigned char)(filesize>>16); 73 | bmpfileheader[ 5] = (unsigned char)(filesize>>24); 74 | 75 | bmpinfoheader[ 4] = (unsigned char)( width ); 76 | bmpinfoheader[ 5] = (unsigned char)( width>> 8); 77 | bmpinfoheader[ 6] = (unsigned char)( width>>16); 78 | bmpinfoheader[ 7] = (unsigned char)( width>>24); 79 | bmpinfoheader[ 8] = (unsigned char)( height ); 80 | bmpinfoheader[ 9] = (unsigned char)( height>> 8); 81 | bmpinfoheader[10] = (unsigned char)( height>>16); 82 | bmpinfoheader[11] = (unsigned char)( height>>24); 83 | 84 | f = fopen(filename, "wb"); 85 | fwrite(bmpfileheader, 1, 14, f); 86 | fwrite(bmpinfoheader, 1, 40, f); 87 | for(int i = 0; i < height; i++) { 88 | fwrite(img + (width * i * 3), 3, width, f); 89 | fwrite(bmppad, 1, (4 - (width * 3) % 4) % 4, f); 90 | } 91 | 92 | free(img); 93 | fclose(f); 94 | 95 | } 96 | -------------------------------------------------------------------------------- /Libs/bitmap_ploter.h: -------------------------------------------------------------------------------- 1 | #ifndef BITMAP_PLOTER_H_ 2 | #define BITMAP_PLOTER_H_ 3 | 4 | void write_bitmap(char *plot, int width, int height, int axis_color,int screen_color, int plot_color, const char *filename); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | FILES = Chortke.c Libs/Processing.c Libs/Processing.h Libs/Stack.c Libs/Stack.h Libs/UI.c Libs/UI.h Libs/bitmap_ploter.c Libs/bitmap_ploter.h 3 | 4 | Chortke: Makefile $(FILES) 5 | $(CC) -o $@ $(FILES) -lm 6 | 7 | clean: 8 | rm -f Chortke *~ 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Chortke 2 | Chortke is a scientific calculator giving you the opportunity to facilitate your calculations and studies. 3 | 4 | This is a project done by three undergraduate students at Sharif University of Technology. 5 | ## Run 6 | Simply : 7 | ``` 8 | make 9 | ``` 10 | ## How to wotk with :sunglasses: 11 | You can surf in program so easily. 12 | For the very first step you should choose your favorite mode in bellow-like menu. 13 | ``` 14 | Welcome to "Chortke"! :D 15 | Choose a character to surf into different parts of Chortke: 16 | e : for entering numerical equation 17 | g : for graphing function(y = f(x)) 18 | p : for plotting equation(0 = f(x,y)) 19 | s : for solving equation for x 20 | c : for see/change configure your plot 21 | i : for evaluating integral of y = f(x) from a to b 22 | q : for quiting from Chortke :( 23 | ``` 24 | * you can escape from each part with simply entering "quit". 25 | * feel free from using ( , ) , + , - , ! , ^ , * , / , exp , ln , sin , cos , tan , abs and so on in all parts of program. 26 | * Note using parentheses while using functions(ex: 2*(sin(pi)) instead of 2*sin(pi)). 27 | 28 | **Numerical equation mode :** 29 | This mode allows you to see the numerical answer of your numerical equation. 30 | Follow the samples bellow and you'll catch everything about this mode. 31 | ``` 32 | = 2 + 2 33 | ``` 34 | Result is : 4.000000 35 | ``` 36 | = (5 + 3) / 5.6 37 | ``` 38 | Result is : 1.428571 39 | ``` 40 | = (5*(9.2/2-(5+6)))/(-6) 41 | ``` 42 | Result is : 5.333333 43 | ``` 44 | = sin(pi/2) 45 | ``` 46 | Result is : 1.000000 47 | ``` 48 | = sin(ln(sin(pi/4))) 49 | ``` 50 | Result is : -0.339677 51 | ``` 52 | = (sin(pi/4))^2 + (cos(pi/4))^2 53 | ``` 54 | Result is : 1.000000 55 | 56 | **Graphing functions :** 57 | Enter a function equals to y (like the example bellow) and you'll see it's plot in Domain of -r < x < r (where r is defined as a configuration in 'c' mode) 58 | ``` 59 | y = ln(x^2) 60 | ``` 61 | also it's .bmp plot picture will save here in Chortke directory till you decide to plot newer function. 62 | 63 | **Graphing none-functions :** 64 | This time you should enter a function of x and y equals to 0 and Da Daaa :smile: here you are, testing example bellow will help you find how it's work. 65 | ``` 66 | 0 = sin(x*y) 67 | ``` 68 | 69 | **Graphing equation for x :** 70 | enter your x desired equation and makes it in a shape that is f(x) = 0 then you'll have it's Real answer(s) in determined x domain in mode 'c'. 71 | ``` 72 | 0 = x^2 - 1 73 | ``` 74 | Result is : 75 | ``` 76 | X1 = -1.000 77 | X2 = 1.000 78 | ``` 79 | ``` 80 | 0 = x^2 + 1 81 | ``` 82 | Result is : 83 | ``` 84 | No answer for x in the domain with accurecy of 0.010000. 85 | ``` 86 | 87 | **Integrating from function :** 88 | First you enter your function of x then you can enter your first and end points of integration domain then you will have the amount of function's integration. 89 | ``` 90 | y = x 91 | a = 0 92 | b = 1 93 | ``` 94 | Result is : 95 | ``` 96 | S(x)dx = 0.5000 97 | ``` 98 | Or in a more complex way : 99 | ``` 100 | y = x^2 + (sin(x)) 101 | a = (2^2 - 4*2)*(-2) 102 | b = pi ^ e 103 | ``` 104 | Result is : 105 | ``` 106 | S(x^2 + (sin(x)))dx = 3607.0842 107 | ``` 108 | 109 | **Configuration menu :** 110 | This menu will show your plotting configuration and ask you if you want to change any of them. 111 | ``` 112 | ---------------------Configuration--------------------- 113 | x Domain : -10.00 < x < 10.00 114 | axis color: 0xa000a0 115 | screen color:0xffffff 116 | plot color: 0x00ff00 117 | ------------------------------------------------------- 118 | ``` 119 | * Note that colors should be entered in HexaDecimal #RGB for example #ff0000 is fully red while #00ff00 is fully Green. 120 | ## Developers 121 | 122 | * **Sadra Sabouri** [Sadra Sabouri](https://github.com/sadrasabouri) 123 | * **Haniyeh Tajer** [Haniyeh Tajer](https://github.com/haniyehtajer) 124 | * **Amirali Ekhteraee** [Amirali Ekhteraee](https://github.com/AmiraliEkhteraee) 125 | 126 | -------------------------------------------------------------------------------- /configs/Chortke.config: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sadrasabouri/Chortke/2c69fbead1e954a56df11ad928c7de6b4c138578/configs/Chortke.config -------------------------------------------------------------------------------- /plot.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sadrasabouri/Chortke/2c69fbead1e954a56df11ad928c7de6b4c138578/plot.bmp --------------------------------------------------------------------------------