-
-
Save selvypen/d7435e8c3a81244cbb1ddc1bb4995e5c to your computer and use it in GitHub Desktop.
Simple example source of math recognition for Windows using C++
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*! | |
* @brief simple example source of math recognition | |
* @date 2020/01/16 | |
* @file math_simple_example.cpp | |
* @author SELVAS AI | |
* | |
* Copyright 2020. SELVAS AI Inc. All Rights Reserved. | |
*/ | |
#include <stdio.h> | |
#include <locale.h> | |
#include "dhwr.h" | |
#define log(...) printf(__VA_ARGS__) | |
// points of '\frac{2x+4}{5y-2}' | |
// -1, 0 : end of stroke | |
// -1, -1 : end of ink | |
// (x0, y0), (x1, y1), ... (-1, 0) ... (xn, yn) .... (-1, 0), (-1, -1) | |
const int ink_fraction[] = {383, 614, 325, 755, 338, 759, 373, 759, 392, 772, 353, 808, 318, | |
825, 320, 805, -1, 0, 348, 691, 351, 688, 358, 676, 397, 668, 427, 667, 433, 663, -1, 0, | |
528, 642, 533, 647, 524, 654, 506, 696, 503, 729, 515, 726, 528, 711, 561, 671, 586, | |
648, 585, 657, 572, 701, 563, 736, 545, 810, 518, 860, 498, 865, 478, 849, 480, 822, | |
515, 783, 535, 769, 587, 744, 620, 735, 631, 732, 642, 732, 644, 733, -1, 0, 714, 691, | |
712, 685, 750, 684, 771, 679, 778, 678, -1, 0, 880, 665, 891, 660, 926, 655, 938, 659, | |
958, 680, 940, 706, 923, 719, 883, 743, 876, 750, 892, 752, 933, 749, 979, 744, 999, | |
743, 1023, 743, 1003, 744, -1, 0, 193, 531, 206, 526, 258, 529, 316, 528, 384, 524, 418, | |
522, 500, 520, 575, 519, 604, 518, 661, 517, 715, 516, 752, 515, 798, 512, 852, 508, | |
873, 508, 915, 505, 961, 502, 979, 501, 1023, 500, 1055, 500, 1070, 499, 1100, 497, | |
1135, 495, 1146, 493, 1163, 492, 1152, 490, 1131, 487, -1, 0, 302, 341, 340, 342, 365, | |
355, 369, 379, 327, 416, 313, 427, 304, 436, 337, 430, 362, 424, 414, 410, 430, 406, | |
423, 406, -1, 0, 444, 337, 450, 337, 479, 319, 509, 325, 511, 347, 492, 386, 481, 405, | |
465, 428, 472, 414, -1, 0, 537, 292, 534, 292, 512, 303, 498, 337, 500, 378, 520, 419, | |
529, 429, 548, 445, 555, 452, 558, 453, -1, 0, 607, 374, 613, 369, 660, 371, 728, 364, | |
761, 356, 760, 349, -1, 0, 688, 316, 686, 318, 681, 331, 690, 388, 693, 407, 696, 426, | |
697, 423, -1, 0, 842, 292, 851, 296, 849, 311, 830, 354, 821, 376, 827, 391, 861, 398, | |
926, 402, 985, 401, 995, 400, 989, 398, -1, 0, 959, 281, 941, 293, 916, 337, 890, 401, | |
869, 458, 864, 479, 866, 488, -1, 0, -1, -1}; | |
// points of '\sqrt{144}+\sqrt{1728}' | |
const int ink_square_root[] = {376, 665, 375, 659, 383, 680, 394, 704, 405, 717, 410, 691, 411, | |
666, 408, 566, 404, 495, 410, 450, 413, 437, 419, 429, 449, 427, 498, 436, 602, 440, | |
759, 428, 824, 421, 859, 418, 857, 428, -1, 0, 516, 571, 509, 580, 513, 625, 519, 648, | |
526, 644, -1, 0, 624, 545, 627, 545, 627, 553, 594, 582, 562, 604, 567, 609, 606, 605, | |
657, 596, 670, 588, -1, 0, 613, 555, 612, 553, 620, 569, 624, 616, 630, 634, 635, 632, | |
-1, 0, 728, 547, 729, 548, 695, 580, 671, 597, 672, 601, 716, 601, 775, 594, 786, 590, | |
-1, 0, 739, 541, 728, 562, 729, 606, 733, 642, 743, 654, -1, 0, 1063, 519, 1054, 536, | |
1058, 577, 1060, 597, -1, 0, 1023, 563, 1032, 558, 1087, 553, 1117, 552, -1, 0, 1315, | |
620, 1319, 620, 1343, 652, 1360, 672, 1361, 650, 1359, 570, 1363, 484, 1365, 424, 1370, | |
413, 1391, 412, 1454, 415, 1519, 413, 1685, 397, 1816, 382, 1910, 377, 1980, 386, 1963, | |
394, -1, 0, 1506, 512, 1493, 512, 1499, 556, 1504, 592, 1509, 608, 1513, 602, -1, 0, | |
1586, 505, 1586, 511, 1573, 560, 1560, 549, 1564, 534, 1586, 506, 1614, 497, 1635, 525, | |
1637, 554, 1624, 617, 1618, 639, 1617, 641, 1623, 632, -1, 0, 1714, 542, 1731, 516, | |
1778, 519, 1792, 561, 1778, 578, 1735, 595, 1713, 593, 1733, 587, 1753, 584, 1811, 579, | |
1838, 578, -1, 0, 1925, 527, 1925, 520, 1906, 470, 1886, 476, 1877, 525, 1885, 576, | |
1873, 615, 1852, 617, 1862, 561, 1907, 535, 1942, 531, 1959, 542, -1, 0, -1, -1}; | |
const int DHWR_MAX_CANDIDATES = 10; | |
DHWRInkObject ink_obj = NULL; | |
DHWRResultObject result_obj = NULL; | |
DHWRSettingObject setting_obj = NULL; | |
void make_input_event(DHWRInkObject ink, const int* inputs) { | |
DHWRInkClear(ink); | |
int i = 0; | |
while (true) { | |
if (inputs[i + 0] == -1 && inputs[i + 1] == -1) { | |
break; | |
} else if (inputs[i + 0] == -1 && inputs[i + 1] == 0) { | |
DHWREndStroke(ink); | |
} else { | |
DHWRAddPoint(ink, inputs[i + 0], inputs[i + 1]); | |
} | |
i += 2; | |
} | |
} | |
void print_wchar(const wchar_t* result, int size) { | |
int i; | |
for (i = 0; i < size; i++) { | |
log("%C", result[i]); | |
} | |
} | |
void print_candidate(DHWRResultObject result) { | |
bool exit = false; | |
unsigned int length; | |
int size_line = DHWRGetLineSize(result); | |
if (size_line == 0) { | |
log("result empty\n"); | |
return; | |
} | |
for (unsigned int i = 0; i < DHWR_MAX_CANDIDATES; i++) { | |
for (int j = 0; j < size_line; j++) { | |
DHWRResultLine line = DHWRGetLine(result, j); | |
int size_block = DHWRGetBlockSize(line); | |
for (int k = 0; k < size_block; k++) { | |
DHWRResultBlock block = DHWRGetBlock(line, k); | |
if (DHWRGetCandidateSize(block) <= i) { | |
exit = true; | |
break; | |
} | |
log("[%02d] ", i + 1); | |
const wchar_t* current_cand = (const wchar_t*)(DHWRGetCandidate(block, i, &length)); | |
print_wchar(current_cand, length); | |
if (k + 1 < size_block) { | |
log(", "); | |
} | |
} | |
if (exit) { | |
break; | |
} | |
if (j + 1 < size_line) { | |
log("\n"); | |
} | |
} | |
if (exit) { | |
break; | |
} | |
log("\n"); | |
} | |
} | |
void print_result(const char *title, int status) { | |
log("\n%s ", title); | |
if (status == ERR_SUCCESS) { | |
log("...Success\n"); | |
print_candidate(result_obj); | |
} else { | |
log("...Failed (%d)\n", status); | |
} | |
} | |
int initEngine() { | |
char *version; | |
DHWRGetRevision(&version); | |
unsigned long status = ERR_SUCCESS; | |
status = DHWRCreate("./license_key/license.key"); | |
if (ink_obj == NULL) { | |
ink_obj = DHWRCreateInkObject(); | |
} | |
if (result_obj == NULL) { | |
result_obj = DHWRCreateResultObject(); | |
} | |
if (setting_obj == NULL) { | |
setting_obj = DHWRCreateSettingObject(); | |
} | |
DHWRSetExternalResourcePath("./hdb/"); | |
DHWRSetRecognitionMode(setting_obj, MULTICHAR); | |
DHWRSetCandidateSize(setting_obj, DHWR_MAX_CANDIDATES); | |
log("\nSDK Version: %s", version); | |
log("\nInitialize Engine ...%s (%ld)\n", status == ERR_SUCCESS ? "Success" : "Failed", status); | |
return status; | |
} | |
int destroyEngine() { | |
unsigned long status = ERR_SUCCESS; | |
status = DHWRClose(); | |
if (ink_obj != NULL) { | |
DHWRDestroyInkObject(ink_obj); | |
} | |
if (result_obj != NULL) { | |
DHWRDestroyResultObject(result_obj); | |
} | |
if (setting_obj != NULL) { | |
DHWRDestroySettingObject(setting_obj); | |
} | |
log("\nDestroy Engine ...%s (%ld)\n", status == ERR_SUCCESS ? "Success" : "Failed", status); | |
return status; | |
} | |
int testFraction() { | |
unsigned long status = ERR_SUCCESS; | |
DHWRClearLanguage(setting_obj); | |
DHWRAddLanguage(setting_obj, DLANG_MATH_MIDDLE_EXPANSION, DTYPE_MATH_EX); | |
status = DHWRSetAttribute(setting_obj); | |
make_input_event(ink_obj, ink_fraction); | |
status = DHWRecognize(ink_obj, result_obj); | |
print_result("Fraction Test", status); | |
return status; | |
} | |
int testSquareRoot() { | |
unsigned long status = ERR_SUCCESS; | |
DHWRClearLanguage(setting_obj); | |
DHWRAddLanguage(setting_obj, DLANG_MATH_MIDDLE_EXPANSION, DTYPE_MATH_EX); | |
DHWRSetAttribute(setting_obj); | |
make_input_event(ink_obj, ink_square_root); | |
status = DHWRecognize(ink_obj, result_obj); | |
print_result("Square root Test", status); | |
return status; | |
} | |
int main() { | |
setlocale(LC_ALL, ""); | |
initEngine(); | |
testFraction(); | |
testSquareRoot(); | |
destroyEngine(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment