|
|
2ed0d1 |
|
|
|
2ed0d1 |
#include <ctype.h></ctype.h>
|
|
|
2ed0d1 |
#include <math.h></math.h>
|
|
|
2ed0d1 |
#include <string.h></string.h>
|
|
|
2ed0d1 |
#include <stdio.h></stdio.h>
|
|
|
2ed0d1 |
#include <stdlib.h></stdlib.h>
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
#include <helianthus.h></helianthus.h>
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
#define SPLITPOINTS 17
|
|
|
2ed0d1 |
double pointsArc[SPLITPOINTS][3];
|
|
|
2ed0d1 |
double pointsQua[SPLITPOINTS][3];
|
|
|
2ed0d1 |
double pointsCub[SPLITPOINTS][4];
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
double ax = 0;
|
|
|
2ed0d1 |
double ay = 10;
|
|
|
2ed0d1 |
double mx, my;
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
int randomAngle = 1;
|
|
|
2ed0d1 |
int rnd = 0;
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
typedef struct {
|
|
|
2ed0d1 |
double mat[9];
|
|
|
2ed0d1 |
double ox, oy;
|
|
|
2ed0d1 |
double curr[3];
|
|
|
2ed0d1 |
} Painter;
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
const char *letters[][2] = {
|
|
|
2ed0d1 |
{ "box", "L000-800-880-080-000-008-808-888-088-008 800-808 880-888 080-088"
|
|
|
2ed0d1 |
" 004-804-884-084z 040-840-848-048z 400-480-488-408z" },
|
|
|
2ed0d1 |
{ "star", "L440-533-844-535-448-335-044-333-440-553-844-555-448-355-044-353z"
|
|
|
2ed0d1 |
" 333-404-535 335-404-533 353-484-555 355-484-553" },
|
|
|
2ed0d1 |
//{ "cube", "L000-800-880-080-000-008-808-888-088-008 800-808 880-888 080-088" },
|
|
|
2ed0d1 |
//{ "cub", "L000-800-880-080-000-008-808-888-088-008 800-808 880-888 080-088" },
|
|
|
2ed0d1 |
{ "a", "L000-448-800 080-448-880 224-624-664-264z" },
|
|
|
2ed0d1 |
{ "b", "L000-008-608-A808-806-804-604-L004-064-A084-086-088-068-L008 A806-886-086 608-668-068 604-664-064 600-660-060 802-882-082 604-804-802-800-600-L000-060-A080-082-084-064-L004" },
|
|
|
2ed0d1 |
{ "c", "L800-400-A000-004-008-408-L808-848-A888-884-880-840-L800 A004-084-884 400-440-840 408-448-848" },
|
|
|
2ed0d1 |
{ "d", "L008-000-400-A800-804-808-408-L008-048-A088-084-080-040-L000 A804-884-084 400-440-040 408-448-048" },
|
|
|
2ed0d1 |
{ "e", "L000-800-880-080-000-008-808-888-088-008 004-804-884-084z" },
|
|
|
2ed0d1 |
{ "f", "L000-008-808-888-088-008 004-804-884-084z" },
|
|
|
2ed0d1 |
{ "g", "L800-804-404-A444-844-L804-A800-400-000-004-008-408-L808-848-A888-884-880-840-800-804 A004-084-884 400-440-840 408-448-848" },
|
|
|
2ed0d1 |
{ "h", "L004-804-884-084z 000-008 800-808 880-888 080-088" },
|
|
|
2ed0d1 |
{ "i", "L440-448 220-260-660-620z 228-268-668-628z" },
|
|
|
2ed0d1 |
{ "j", "A848-888-488-088-048-008-408-808-848-L844-A840-440-040-044-004-404-804-844-884-484-084-044 404-400-440-480-484" },
|
|
|
2ed0d1 |
{ "k", "L000-008 800-004-808 080-004-088 880-004-888" },
|
|
|
2ed0d1 |
{ "l", "L008-000-800-880-080-000" },
|
|
|
2ed0d1 |
{ "m", "L000-228-400-628-800 080-268-480-668-880 040-268-440-668-840-628-440-228z" },
|
|
|
2ed0d1 |
{ "n", "L000-008-800-808 008-080-088 008-880-888" },
|
|
|
2ed0d1 |
{ "o", "A044-040-440-840-844-848-448-048-044-004-404-804-844-884-484-084-044 404-400-440-480-484-488-448-408-404" },
|
|
|
2ed0d1 |
{ "p", "L000-008-608-A808-806-804-604-L004-064-A084-086-088-068-L008 A806-886-086 608-668-068 604-664-064" },
|
|
|
2ed0d1 |
{ "q", "A044-040-440-840-844-848-448-048-044-004-404-804-844-884-484-084-044 404-400-440-480-484-488-448-408-404 L444-840-A880-480z" },
|
|
|
2ed0d1 |
{ "r", "L000-008-608-A808-806-804-604-L004-064-A084-086-088-068-L008 A806-886-086 608-668-068 604-664-064 604-804-802-L800-A880-080-L082-A084-064 802-882-082" },
|
|
|
2ed0d1 |
{ "s", "A424-404-204-004-006-008-208-L808-868-A888-886-884-864-844-644 L208-248-A268-468-L868 006-046-A086-486-L886 A248-048-046-044-244 468-488-486-484-464"
|
|
|
2ed0d1 |
" 464-484-684-884-882-880-680-L080-020-A000-002-004-024-L044-244 680-640-A620-420-L020 882-842-A802-402-L002 A640-840-842-844-644 420-400-402-404-424"
|
|
|
2ed0d1 |
" 244-224-424-624-644-664-464-264-244" },
|
|
|
2ed0d1 |
{ "t", "L008-808-888-088z 440-448" },
|
|
|
2ed0d1 |
{ "u", "A848-888-488-088-048-008-408-808-848-L844-A840-440-040-044-L048 408-404-A400-440-480-484-L488 A044-004-404-804-844-884-484-084-044" },
|
|
|
2ed0d1 |
{ "v", "L008-440-808 088-440-888" },
|
|
|
2ed0d1 |
{ "w", "L008-220-408-620-808 088-260-488-660-888 048-260-448-660-848-620-448-220z" },
|
|
|
2ed0d1 |
{ "x", "L000-888 800-088 880-008 080-808" },
|
|
|
2ed0d1 |
{ "y", "L000-888 444-088 444-008 444-808" },
|
|
|
2ed0d1 |
{ "z", "L000-800-880-080-000-888-088-008-808-888" },
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
{ "0", "A044-040-440-840-844-848-448-048-044-004-404-804-844-884-484-084-044 404-400-440-480-484-488-448-408-404 L040-848" },
|
|
|
2ed0d1 |
{ "1", "L440-448-226 220-260-660-620z" },
|
|
|
2ed0d1 |
{ "2", "L000-002-A004-204-404-604-804-806-808-608-L008-068-A088-086-084-064-044-024-004-002-L000-800-880-080-000"
|
|
|
2ed0d1 |
" 608-648-A668-468-L068 604-644-A664-464-L064 806-846-A886-486-L086 "
|
|
|
2ed0d1 |
" A648-848-846-844-644 468-488-486-484-464 " },
|
|
|
2ed0d1 |
{ "3", "L008-608-A808-806-804-604-L004-064-A084-086-088-068-L008 A806-886-086 608-668-068 604-664-064 600-660-060 802-882-082 604-804-802-800-600-L000-060-A080-082-084-064-L004" },
|
|
|
2ed0d1 |
{ "4", "L004-804-884-084z 004-008 800-808 884-888 084-088" },
|
|
|
2ed0d1 |
{ "5", "L008-006-A004-204-404-604-804-802-800-600-L000-060-A080-082-084-064-044-024-004-006-L008-808-888-088-008"
|
|
|
2ed0d1 |
" 600-640-A660-460-L060 604-644-A664-464-L064 802-842-A882-482-L082 "
|
|
|
2ed0d1 |
" A640-840-842-844-644 460-480-482-484-464 " },
|
|
|
2ed0d1 |
{ "6", "L042-044-C048-088-488-A888-848-808-408-C008-048-044-048-048-448-L848 408-488"
|
|
|
2ed0d1 |
" A042-040-240-L640-A840-842-844-644-L244-A044-042-002-402-802-842-882-482-082-042"
|
|
|
2ed0d1 |
" 402-400-420-L460-A480-482-484-464-L424-A404-402 244-224-424-624-644-664-464-264-244 240-220-420-620-640-660-460-260-240 "},
|
|
|
2ed0d1 |
{ "7", "L000-888-088-008-808-888 224-264-664-624z" },
|
|
|
2ed0d1 |
{ "8", "A244-044-042-040-240-L640-A840-842-844-644-L244-A044-046-048-248-L648-A848-846-844-644"
|
|
|
2ed0d1 |
" 424-404-402-400-420-L460-A480-482-484-464-L424-A404-406-408-428-L468-A488-486-484-464"
|
|
|
2ed0d1 |
" 042-002-402-802-842-882-482-082-042 046-006-406-806-846-886-486-086-046"
|
|
|
2ed0d1 |
" 240-220-420-620-640-660-460-260-240 244-224-424-624-644-664-464-264-244 248-228-428-628-648-668-468-268-248" },
|
|
|
2ed0d1 |
{ "9", "L846-844-C840-880-480-A080-040-000-400-C800-840-844-840-840-440-L040 400-480"
|
|
|
2ed0d1 |
" A046-048-248-L648-A848-846-844-644-L244-A044-046-006-406-806-846-886-486-086-046"
|
|
|
2ed0d1 |
" 406-408-428-L468-A488-486-484-464-L424-A404-406 244-224-424-624-644-664-464-264-244 248-228-428-628-648-668-468-268-248 "},
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
{ ",", "P442 L442-220" },
|
|
|
2ed0d1 |
{ "...", "P002 402 802 042 442 842 882 482 082" },
|
|
|
2ed0d1 |
{ "..", "P222 622 662 262" },
|
|
|
2ed0d1 |
{ ".", "L331-531-551-351-331-333-533-553-353-333 531-533 551-553 351-353 " },
|
|
|
2ed0d1 |
//{ ".", "P442" },
|
|
|
2ed0d1 |
{ "?", "A442-444-424-404-604-804-806-808-608-L008-068-A088-086-084-064-044-244-444-442"
|
|
|
2ed0d1 |
" L608-648-A668-468-L068 806-846-A886-486-L086"
|
|
|
2ed0d1 |
" A648-848-846-844-644-444-442 468-488-486-484-464-444-442 424-624-644-664-464-264-244 P440" },
|
|
|
2ed0d1 |
{ "!", "A442-244-246-248-448-648-646-644-442 A442-424-426-428-448-468-466-464-442 246-226-426-626-646-666-466-266-246 P440" },
|
|
|
2ed0d1 |
{ ":", "P222 622 662 262 226 626 666 266" },
|
|
|
2ed0d1 |
{ ";", "P222 622 662 262 226 626 666 266 L222-240 L622-420 L662-640 L262-460" },
|
|
|
2ed0d1 |
{ "\"","P226 626 666 266 L226-244 L626-424 L666-644 L266-464" },
|
|
|
2ed0d1 |
{ "\'","P446 L446-224" },
|
|
|
2ed0d1 |
{ "`", "P446 L446-664" },
|
|
|
2ed0d1 |
{ "<", "L800-044-880 808-044-888" },
|
|
|
2ed0d1 |
{ ">", "L000-844-080 008-844-088" },
|
|
|
2ed0d1 |
{ "=", "L222-262-662-622z 226-266-666-626z" },
|
|
|
2ed0d1 |
{ "-", "L224-264-664-624z" },
|
|
|
2ed0d1 |
{ "+", "L244-644 424-464 442-446" },
|
|
|
2ed0d1 |
{ "*", "L244-644 424-464 442-446 222-666 622-266 662-226 262-626" },
|
|
|
2ed0d1 |
{ "/", "L000-888" },
|
|
|
2ed0d1 |
{ "\\","L800-088" },
|
|
|
2ed0d1 |
{ "^", "L226-448-666 626-448-266" },
|
|
|
2ed0d1 |
{ "(", "A640-680-684-688-648-608-604-600-640-240-244-248-648 604-204-244-284-684" },
|
|
|
2ed0d1 |
{ ")", "A240-280-284-288-248-208-204-200-240-640-644-648-248 204-604-644-684-284" },
|
|
|
2ed0d1 |
{ "[", "L640-680-684-688-648-608-604-600-640-240-244-248-648 604-204-244-284-684" },
|
|
|
2ed0d1 |
{ "]", "L240-280-284-288-248-208-204-200-240-640-644-648-248 204-604-644-684-284" },
|
|
|
2ed0d1 |
{ "{", "A640-440-442-444-244-444-446-448-648 604-404-424-444-244-444-464-484-684"
|
|
|
2ed0d1 |
" 464-466-446-426-424-422-442-462-464 L684-688-648-608-604-600-640-680-684 " },
|
|
|
2ed0d1 |
{ "}", "A240-440-442-444-644-444-446-448-248 204-404-424-444-644-444-464-484-284"
|
|
|
2ed0d1 |
" 464-466-446-426-424-422-442-462-464 L284-288-248-208-204-200-240-280-284 " },
|
|
|
2ed0d1 |
{ "_", "L000-800-880-080z" },
|
|
|
2ed0d1 |
{ "||","L220-228 620-628 660-668 260-268" },
|
|
|
2ed0d1 |
{ "|", "L440-448" },
|
|
|
2ed0d1 |
{ "#", "L220-228 620-628 660-668 260-268 202-282 206-286 606-686 602-682 022-822 062-862 066-866 026-826" },
|
|
|
2ed0d1 |
{ "@", "A244-242-442-642-644-646-446-246-244-224-424-624-644-664-464-264-244 424-422-442-462-464-466-446-426-424"
|
|
|
2ed0d1 |
" 440-480-484-084-044-040-440-L840-800-400-440"
|
|
|
2ed0d1 |
" C[8.00][4.00][0.00]-[8.00][6.31][0.00]-[4.52][8.33][1.78]-[4.00][8.00][4.00]"
|
|
|
2ed0d1 |
"-[3.83][7.89][4.73]-[3.89][7.53][5.53]-[4.12][7.03][6.06]"
|
|
|
2ed0d1 |
"-[4.36][6.53][6.59]-[4.78][5.83][6.91]-[5.18][5.18][6.89]"
|
|
|
2ed0d1 |
"-[5.57][4.55][6.86]-[5.98][3.88][6.51]-[6.20][3.43][5.96]"
|
|
|
2ed0d1 |
"-[6.41][3.00][5.44]-[6.47][2.71][4.68]-[6.31][2.67][4.00]"
|
|
|
2ed0d1 |
"-[6.17][2.62][3.38]-[5.82][2.78][2.73]-[5.37][3.06][2.36]"
|
|
|
2ed0d1 |
"-[4.98][3.30][2.04]-[4.45][3.68][1.88]-[4.00][4.00][2.00]"
|
|
|
2ed0d1 |
"-[4.32][3.55][1.88]-[4.70][3.02][2.04]-[4.94][2.63][2.36]"
|
|
|
2ed0d1 |
"-[5.22][2.18][2.73]-[5.38][1.83][3.38]-[5.33][1.69][4.00]"
|
|
|
2ed0d1 |
"-[5.29][1.53][4.68]-[5.00][1.59][5.44]-[4.57][1.80][5.96]"
|
|
|
2ed0d1 |
"-[4.12][2.02][6.51]-[3.45][2.43][6.86]-[2.82][2.82][6.89]"
|
|
|
2ed0d1 |
"-[2.17][3.22][6.91]-[1.47][3.64][6.59]-[0.97][3.88][6.06]"
|
|
|
2ed0d1 |
"-[0.47][4.11][5.53]-[0.11][4.17][4.73]-[0.00][4.00][4.00]"
|
|
|
2ed0d1 |
"-[-0.33][3.48][1.78]-[1.69][0.00][0.00]-[4.00][0.00][0.00]"
|
|
|
2ed0d1 |
" [5.18][5.18][6.89]-[4.50][4.50][7.44]-[3.50][3.50][7.44]-[2.82][2.82][6.89]" },
|
|
|
2ed0d1 |
{ "&", " A046-048-248-L648-A848-846-844-644-L244-A044-046-006-406-806-846-886-486-086-046"
|
|
|
2ed0d1 |
" 406-408-428-L468-A488-486-484-464-L424-A404-406 244-224-424-624-644-664-464-264-244 248-228-428-628-648-668-468-268-248"
|
|
|
2ed0d1 |
" A424-404-204-004-002-000-200-L800-860-A880-882-884-864-844-644"
|
|
|
2ed0d1 |
" L200-240-A260-460-L860 002-042-A082-482-L882 A240-040-042-044-244 460-480-482-484-464" },
|
|
|
2ed0d1 |
{ "%", "A066-064-264-464-466-468-268-068-066-046-246-446-466-486-286-086-066 246-244-264-284-286-288-268-248-246"
|
|
|
2ed0d1 |
" 422-420-620-820-822-824-624-424-422-402-602-802-822-842-642-442-422 602-600-620-640-642-644-624-604-602"
|
|
|
2ed0d1 |
" L000-888" },
|
|
|
2ed0d1 |
{ "~", "C244-254-255-355-A455-444-433-533-C633-634-644 A244-224-424-624-644-664-464-264-244" },
|
|
|
2ed0d1 |
{ "$", "A424-404-204-004-006-008-208-L808-868-A888-886-884-864-844-644 L208-248-A268-468-L868 006-046-A086-486-L886 A248-048-046-044-244 468-488-486-484-464"
|
|
|
2ed0d1 |
" 464-484-684-884-882-880-680-L080-020-A000-002-004-024-L044-244 680-640-A620-420-L020 882-842-A802-402-L002 A640-840-842-844-644 420-400-402-404-424"
|
|
|
2ed0d1 |
" 244-224-424-624-644-664-464-264-244 L24[-2]-24[10] L64[-2]-64[10] L42[-2]-42[10] L46[-2]-46[10] " },
|
|
|
2ed0d1 |
};
|
|
|
2ed0d1 |
int lettersCount = sizeof(letters)/sizeof(letters[0]);
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
const char *textToDraw = NULL;
|
|
|
2ed0d1 |
double boxStep = 64;
|
|
|
2ed0d1 |
double boxSize = 0.5;
|
|
|
2ed0d1 |
int renderToFiles = 0;
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
void vec3set(double *v, double x, double y, double z)
|
|
|
2ed0d1 |
{ v[0] = x, v[1] = y, v[2] = z; }
|
|
|
2ed0d1 |
void vec3cpy(double *v, const double *vv)
|
|
|
2ed0d1 |
{ memcpy(v, vv, sizeof(*v)*3); }
|
|
|
2ed0d1 |
void vec3add(double *v, const double *vv)
|
|
|
2ed0d1 |
{ v[0] += vv[0]; v[1] += vv[1]; v[2] += vv[2]; }
|
|
|
2ed0d1 |
void vec3trans(double *v, const double *m) {
|
|
|
2ed0d1 |
vec3set(v, v[0]*m[0] + v[1]*m[3] + v[2]*m[6],
|
|
|
2ed0d1 |
v[0]*m[1] + v[1]*m[4] + v[2]*m[7],
|
|
|
2ed0d1 |
v[0]*m[2] + v[1]*m[5] + v[2]*m[8] );
|
|
|
2ed0d1 |
}
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
void mat3cpy(double *m, double *mm)
|
|
|
2ed0d1 |
{ memcpy(m, mm, sizeof(*m)*9); }
|
|
|
2ed0d1 |
void mat3one(double *m) {
|
|
|
2ed0d1 |
m[1] = m[2] = m[3] = m[5] = m[6] = m[7] = 0;
|
|
|
2ed0d1 |
m[0] = m[4] = m[8] = 1;
|
|
|
2ed0d1 |
}
|
|
|
2ed0d1 |
void mat3trans(double *m, const double *mm) {
|
|
|
2ed0d1 |
vec3trans(m+0, mm);
|
|
|
2ed0d1 |
vec3trans(m+3, mm);
|
|
|
2ed0d1 |
vec3trans(m+6, mm);
|
|
|
2ed0d1 |
}
|
|
|
2ed0d1 |
void mat3rotX(double *m, double a) {
|
|
|
2ed0d1 |
rotateVector(&m[1], &m[2], a);
|
|
|
2ed0d1 |
rotateVector(&m[4], &m[5], a);
|
|
|
2ed0d1 |
rotateVector(&m[7], &m[8], a);
|
|
|
2ed0d1 |
}
|
|
|
2ed0d1 |
void mat3rotY(double *m, double a) {
|
|
|
2ed0d1 |
rotateVector(&m[2], &m[0], a);
|
|
|
2ed0d1 |
rotateVector(&m[5], &m[3], a);
|
|
|
2ed0d1 |
rotateVector(&m[8], &m[6], a);
|
|
|
2ed0d1 |
}
|
|
|
2ed0d1 |
void mat3rotZ(double *m, double a) {
|
|
|
2ed0d1 |
rotateVector(&m[0], &m[1], a);
|
|
|
2ed0d1 |
rotateVector(&m[3], &m[4], a);
|
|
|
2ed0d1 |
rotateVector(&m[6], &m[7], a);
|
|
|
2ed0d1 |
}
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
void painterInternalMoveTo(Painter *p, double x, double y, double z) {
|
|
|
2ed0d1 |
double xx = p->mat[0]*x + p->mat[3]*y + p->mat[6]*z + p->ox;
|
|
|
2ed0d1 |
double yy = p->mat[1]*x + p->mat[4]*y + p->mat[7]*z + p->oy;
|
|
|
2ed0d1 |
moveTo(xx, yy);
|
|
|
2ed0d1 |
}
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
void painterInternalLineTo(Painter *p, double x, double y, double z) {
|
|
|
2ed0d1 |
double xx = p->mat[0]*x + p->mat[3]*y + p->mat[6]*z + p->ox;
|
|
|
2ed0d1 |
double yy = p->mat[1]*x + p->mat[4]*y + p->mat[7]*z + p->oy;
|
|
|
2ed0d1 |
lineTo(xx, yy);
|
|
|
2ed0d1 |
}
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
void painterInternalPointTo(Painter *p, double x, double y, double z) {
|
|
|
2ed0d1 |
double xx = p->mat[0]*x + p->mat[3]*y + p->mat[6]*z + p->ox;
|
|
|
2ed0d1 |
double yy = p->mat[1]*x + p->mat[4]*y + p->mat[7]*z + p->oy;
|
|
|
2ed0d1 |
saveState();
|
|
|
2ed0d1 |
translate(xx, yy);
|
|
|
2ed0d1 |
zoom(3);
|
|
|
2ed0d1 |
point(0, 0);
|
|
|
2ed0d1 |
restoreState();
|
|
|
2ed0d1 |
}
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
void painterFinish(Painter *p)
|
|
|
2ed0d1 |
{ strokePath(); }
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
void painterMoveTo(Painter *p, double *pos) {
|
|
|
2ed0d1 |
painterFinish(p);
|
|
|
2ed0d1 |
painterInternalMoveTo(p, pos[0], pos[1], pos[2]);
|
|
|
2ed0d1 |
vec3cpy(p->curr, pos);
|
|
|
2ed0d1 |
}
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
void painterLineTo(Painter *p, double *pos) {
|
|
|
2ed0d1 |
painterInternalLineTo(p, pos[0], pos[1], pos[2]);
|
|
|
2ed0d1 |
vec3cpy(p->curr, pos);
|
|
|
2ed0d1 |
}
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
void painterPointTo(Painter *p, double *pos) {
|
|
|
2ed0d1 |
painterFinish(p);
|
|
|
2ed0d1 |
painterInternalPointTo(p, pos[0], pos[1], pos[2]);
|
|
|
2ed0d1 |
vec3cpy(p->curr, pos);
|
|
|
2ed0d1 |
}
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
void painterArcTo(Painter *p, double *pos1, double *pos2) {
|
|
|
2ed0d1 |
double *pos0 = p->curr;
|
|
|
2ed0d1 |
for(int i = 1; i < SPLITPOINTS; ++i)
|
|
|
2ed0d1 |
painterInternalLineTo( p,
|
|
|
2ed0d1 |
pointsArc[i][0]*pos0[0] + pointsArc[i][1]*pos1[0] + pointsArc[i][2]*pos2[0],
|
|
|
2ed0d1 |
pointsArc[i][0]*pos0[1] + pointsArc[i][1]*pos1[1] + pointsArc[i][2]*pos2[1],
|
|
|
2ed0d1 |
pointsArc[i][0]*pos0[2] + pointsArc[i][1]*pos1[2] + pointsArc[i][2]*pos2[2] );
|
|
|
2ed0d1 |
vec3cpy(p->curr, pos2);
|
|
|
2ed0d1 |
}
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
void painterQuadraticTo(Painter *p, double *pos1, double *pos2) {
|
|
|
2ed0d1 |
double *pos0 = p->curr;
|
|
|
2ed0d1 |
for(int i = 1; i < SPLITPOINTS; ++i)
|
|
|
2ed0d1 |
painterInternalLineTo( p,
|
|
|
2ed0d1 |
pointsQua[i][0]*pos0[0] + pointsQua[i][1]*pos1[0] + pointsQua[i][2]*pos2[0],
|
|
|
2ed0d1 |
pointsQua[i][0]*pos0[1] + pointsQua[i][1]*pos1[1] + pointsQua[i][2]*pos2[1],
|
|
|
2ed0d1 |
pointsQua[i][0]*pos0[2] + pointsQua[i][1]*pos1[2] + pointsQua[i][2]*pos2[2] );
|
|
|
2ed0d1 |
vec3cpy(p->curr, pos2);
|
|
|
2ed0d1 |
}
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
void painterCubicTo(Painter *p, double *pos1, double *pos2, double *pos3) {
|
|
|
2ed0d1 |
double *pos0 = p->curr;
|
|
|
2ed0d1 |
for(int i = 1; i < SPLITPOINTS; ++i)
|
|
|
2ed0d1 |
painterInternalLineTo( p,
|
|
|
2ed0d1 |
pointsCub[i][0]*pos0[0] + pointsCub[i][1]*pos1[0] + pointsCub[i][2]*pos2[0] + pointsCub[i][3]*pos3[0],
|
|
|
2ed0d1 |
pointsCub[i][0]*pos0[1] + pointsCub[i][1]*pos1[1] + pointsCub[i][2]*pos2[1] + pointsCub[i][3]*pos3[1],
|
|
|
2ed0d1 |
pointsCub[i][0]*pos0[2] + pointsCub[i][1]*pos1[2] + pointsCub[i][2]*pos2[2] + pointsCub[i][3]*pos3[2] );
|
|
|
2ed0d1 |
vec3cpy(p->curr, pos3);
|
|
|
2ed0d1 |
}
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
void painterClose(Painter *p)
|
|
|
2ed0d1 |
{ closePath(); }
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
void drawLetter(Painter *p, const char *cmd) {
|
|
|
2ed0d1 |
saveState();
|
|
|
2ed0d1 |
noFill();
|
|
|
2ed0d1 |
double mat[11];
|
|
|
2ed0d1 |
mat3cpy(mat, p->mat);
|
|
|
2ed0d1 |
mat[9] = p->ox; mat[10] = p->oy;
|
|
|
2ed0d1 |
if (randomAngle) {
|
|
|
2ed0d1 |
double m[9], v[3];
|
|
|
2ed0d1 |
vec3set(v, -4, -4, -4);
|
|
|
2ed0d1 |
vec3trans(v, p->mat);
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
mat3one(m);
|
|
|
2ed0d1 |
mat3rotZ(m, randomFloat()*360);
|
|
|
2ed0d1 |
mat3trans(m, p->mat);
|
|
|
2ed0d1 |
mat3cpy(p->mat, m);
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
vec3set(m, -4, -4, -4);
|
|
|
2ed0d1 |
vec3trans(m, p->mat);
|
|
|
2ed0d1 |
p->ox += m[0] - v[0], p->oy += m[1] - v[1];
|
|
|
2ed0d1 |
}
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
char mode = 'L';
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
int begin = 1;
|
|
|
2ed0d1 |
int relative = 0;
|
|
|
2ed0d1 |
int cnt = 0;
|
|
|
2ed0d1 |
double coords[3][3] = {};
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
for(const char *c = cmd; 1; ++c) {
|
|
|
2ed0d1 |
switch(*c) {
|
|
|
2ed0d1 |
case 'L':
|
|
|
2ed0d1 |
case 'A':
|
|
|
2ed0d1 |
case 'Q':
|
|
|
2ed0d1 |
case 'C':
|
|
|
2ed0d1 |
case 'P':
|
|
|
2ed0d1 |
mode = *c;
|
|
|
2ed0d1 |
relative = 0;
|
|
|
2ed0d1 |
cnt = 0;
|
|
|
2ed0d1 |
break;
|
|
|
2ed0d1 |
case 'l':
|
|
|
2ed0d1 |
case 'a':
|
|
|
2ed0d1 |
case 'q':
|
|
|
2ed0d1 |
case 'c':
|
|
|
2ed0d1 |
case 'p':
|
|
|
2ed0d1 |
mode = toupper(*c);
|
|
|
2ed0d1 |
relative = 1;
|
|
|
2ed0d1 |
cnt = 0;
|
|
|
2ed0d1 |
break;
|
|
|
2ed0d1 |
case '0':
|
|
|
2ed0d1 |
case '1':
|
|
|
2ed0d1 |
case '2':
|
|
|
2ed0d1 |
case '3':
|
|
|
2ed0d1 |
case '4':
|
|
|
2ed0d1 |
case '5':
|
|
|
2ed0d1 |
case '6':
|
|
|
2ed0d1 |
case '7':
|
|
|
2ed0d1 |
case '8':
|
|
|
2ed0d1 |
case '9':
|
|
|
2ed0d1 |
coords[0][0] = coords[0][1];
|
|
|
2ed0d1 |
coords[0][1] = coords[0][2];
|
|
|
2ed0d1 |
coords[0][2] = *c - '0';
|
|
|
2ed0d1 |
break;
|
|
|
2ed0d1 |
case '[':
|
|
|
2ed0d1 |
coords[0][0] = coords[0][1];
|
|
|
2ed0d1 |
coords[0][1] = coords[0][2];
|
|
|
2ed0d1 |
coords[0][2] = atof(c+1);
|
|
|
2ed0d1 |
while(*c != ']' && c[1]) ++c;
|
|
|
2ed0d1 |
break;
|
|
|
2ed0d1 |
case '-':
|
|
|
2ed0d1 |
case ' ':
|
|
|
2ed0d1 |
case 'z':
|
|
|
2ed0d1 |
case 'Z':
|
|
|
2ed0d1 |
case 0:
|
|
|
2ed0d1 |
if (relative) vec3add(coords[0], coords[cnt+1]);
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
if (mode == 'P') {
|
|
|
2ed0d1 |
painterPointTo(p, coords[0]);
|
|
|
2ed0d1 |
begin = 1; cnt = 0;
|
|
|
2ed0d1 |
} else
|
|
|
2ed0d1 |
if (begin) {
|
|
|
2ed0d1 |
painterMoveTo(p, coords[0]);
|
|
|
2ed0d1 |
begin = 0;
|
|
|
2ed0d1 |
} else
|
|
|
2ed0d1 |
if (mode == 'L') {
|
|
|
2ed0d1 |
painterLineTo(p, coords[0]);
|
|
|
2ed0d1 |
} else
|
|
|
2ed0d1 |
if (mode == 'A') {
|
|
|
2ed0d1 |
if (cnt) { painterArcTo(p, coords[1], coords[0]); cnt = 0; }
|
|
|
2ed0d1 |
else { vec3cpy(coords[1], coords[0]); ++cnt; }
|
|
|
2ed0d1 |
} else
|
|
|
2ed0d1 |
if (mode == 'Q') {
|
|
|
2ed0d1 |
if (cnt) { painterQuadraticTo(p, coords[1], coords[0]); cnt = 0; }
|
|
|
2ed0d1 |
else { vec3cpy(coords[1], coords[0]); ++cnt; }
|
|
|
2ed0d1 |
} else
|
|
|
2ed0d1 |
if (mode == 'C') {
|
|
|
2ed0d1 |
if (cnt > 1) { painterCubicTo(p, coords[2], coords[1], coords[0]); cnt = 0; }
|
|
|
2ed0d1 |
else { vec3cpy(coords[2], coords[1]); vec3cpy(coords[1], coords[0]); ++cnt; }
|
|
|
2ed0d1 |
}
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
if (*c == ' ' || *c == 0) {
|
|
|
2ed0d1 |
painterFinish(p);
|
|
|
2ed0d1 |
begin = 1; cnt = 0;
|
|
|
2ed0d1 |
} else
|
|
|
2ed0d1 |
if (*c == 'z' || *c == 'Z') {
|
|
|
2ed0d1 |
painterClose(p);
|
|
|
2ed0d1 |
begin = 1; cnt = 0;
|
|
|
2ed0d1 |
}
|
|
|
2ed0d1 |
break;
|
|
|
2ed0d1 |
}
|
|
|
2ed0d1 |
if (!*c) break;
|
|
|
2ed0d1 |
}
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
mat3cpy(p->mat, mat);
|
|
|
2ed0d1 |
p->ox = mat[9]; p->oy = mat[10];
|
|
|
2ed0d1 |
restoreState();
|
|
|
2ed0d1 |
}
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
void drawStr(
|
|
|
2ed0d1 |
Painter *p, double dx, double dy,
|
|
|
2ed0d1 |
const char *str, char stopChar,
|
|
|
2ed0d1 |
int *rows, int *cols )
|
|
|
2ed0d1 |
{
|
|
|
2ed0d1 |
if (randomAngle) srand(rnd);
|
|
|
2ed0d1 |
double ox, oy;
|
|
|
2ed0d1 |
if (p) { ox = p->ox; oy = p->oy; }
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
int row = 0, col = 0, maxRow = -1, maxCol = -1;
|
|
|
2ed0d1 |
for(const char *c = str; *c && *c != stopChar; ++c) {
|
|
|
2ed0d1 |
if (*c == '\n')
|
|
|
2ed0d1 |
{ ++row; col = 0; continue; }
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
for(int i = 0; i < lettersCount; ++i) {
|
|
|
2ed0d1 |
int equals = 0;
|
|
|
2ed0d1 |
for(const char *ca = c, *cb = letters[i][0]; 1; ++ca, ++cb) {
|
|
|
2ed0d1 |
if (!*cb) { equals = 1; c += cb-letters[i][0]-1; break; }
|
|
|
2ed0d1 |
if (!*ca || *ca == stopChar || tolower(*ca) != tolower(*cb)) break;
|
|
|
2ed0d1 |
}
|
|
|
2ed0d1 |
if (equals) {
|
|
|
2ed0d1 |
if (maxCol < col) maxCol = col;
|
|
|
2ed0d1 |
if (maxRow < row) maxRow = row;
|
|
|
2ed0d1 |
if (p) {
|
|
|
2ed0d1 |
p->ox = ox + col*dx;
|
|
|
2ed0d1 |
p->oy = oy + row*dy;
|
|
|
2ed0d1 |
drawLetter(p, letters[i][1]);
|
|
|
2ed0d1 |
}
|
|
|
2ed0d1 |
break;
|
|
|
2ed0d1 |
}
|
|
|
2ed0d1 |
}
|
|
|
2ed0d1 |
++col;
|
|
|
2ed0d1 |
}
|
|
|
2ed0d1 |
if (p) { p->ox = ox; p->oy = oy; }
|
|
|
2ed0d1 |
if (rows) *rows = maxRow + 1;
|
|
|
2ed0d1 |
if (cols) *cols = maxCol + 1;
|
|
|
2ed0d1 |
}
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
void drawAllLetters(Painter *p) {
|
|
|
2ed0d1 |
if (randomAngle) srand(rnd);
|
|
|
2ed0d1 |
double ox = p->ox, oy = p->oy;
|
|
|
2ed0d1 |
int lcnt = (int)ceil(sqrt(lettersCount) - 1e-6);
|
|
|
2ed0d1 |
for(int i = 0; i < lettersCount; ++i) {
|
|
|
2ed0d1 |
int r = i/lcnt, c = i%lcnt;
|
|
|
2ed0d1 |
p->ox = (c - 0.5*(lcnt - 1))*boxStep + ox;
|
|
|
2ed0d1 |
p->oy = (r - 0.5*(lcnt - 1))*boxStep + oy;
|
|
|
2ed0d1 |
drawLetter(p, letters[i][1]);
|
|
|
2ed0d1 |
}
|
|
|
2ed0d1 |
p->ox = ox; p->oy = oy;
|
|
|
2ed0d1 |
}
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
void initCurvePoints() {
|
|
|
2ed0d1 |
for(int i = 0; i < SPLITPOINTS; ++i) {
|
|
|
2ed0d1 |
double l = i/(SPLITPOINTS-1.0), k = 1-l;
|
|
|
2ed0d1 |
double a = l*PI/2, s = sin(a), c = cos(a);
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
pointsQua[i][0] = k*k;
|
|
|
2ed0d1 |
pointsQua[i][1] = 2*k*l;
|
|
|
2ed0d1 |
pointsQua[i][2] = l*l;
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
pointsCub[i][0] = k*k*k;
|
|
|
2ed0d1 |
pointsCub[i][1] = 3*k*k*l;
|
|
|
2ed0d1 |
pointsCub[i][2] = 3*l*l*k;
|
|
|
2ed0d1 |
pointsCub[i][3] = l*l*l;
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
pointsArc[i][0] = 1-s;
|
|
|
2ed0d1 |
pointsArc[i][1] = s+c-1;
|
|
|
2ed0d1 |
pointsArc[i][2] = 1-c;
|
|
|
2ed0d1 |
}
|
|
|
2ed0d1 |
}
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
void render(int framesCount) {
|
|
|
2ed0d1 |
saveState();
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
int rows, cols;
|
|
|
2ed0d1 |
drawStr(NULL, 0, 0, textToDraw, 0, &rows, &cols);
|
|
|
2ed0d1 |
int w = (int)ceil(cols*boxStep - 1e-5);
|
|
|
2ed0d1 |
int h = (int)ceil(rows*boxStep - 1e-5);
|
|
|
2ed0d1 |
Framebuffer fb = createFramebuffer(w, h);
|
|
|
2ed0d1 |
target(fb);
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
for(int i = 0; i < framesCount; ++i) {
|
|
|
2ed0d1 |
clear();
|
|
|
2ed0d1 |
double step = boxStep*boxSize/8.0;
|
|
|
2ed0d1 |
double mat[9] = {step, 0, 0, 0, 0, step, 0, -step, 0};
|
|
|
2ed0d1 |
mat3rotY(mat, 360.0*i/framesCount);
|
|
|
2ed0d1 |
mat3rotX(mat, 10);
|
|
|
2ed0d1 |
double vec[3] = {-4, -4, -4};
|
|
|
2ed0d1 |
vec3trans(vec, mat);
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
Painter p = {};
|
|
|
2ed0d1 |
mat3cpy(p.mat, mat);
|
|
|
2ed0d1 |
p.ox = vec[0] + boxStep/2; p.oy = vec[1] + boxStep/2;
|
|
|
2ed0d1 |
drawStr(&p, boxStep, boxStep, textToDraw, 0, &rows, &cols);
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
char buf[1024] = {};
|
|
|
2ed0d1 |
sprintf(buf, "data/output/message3d/msg%04d.png", i);
|
|
|
2ed0d1 |
printf("save file: %s\n", buf);
|
|
|
2ed0d1 |
viewportSave(buf);
|
|
|
2ed0d1 |
}
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
noTarget();
|
|
|
2ed0d1 |
framebufferDestroy(fb);
|
|
|
2ed0d1 |
restoreState();
|
|
|
2ed0d1 |
}
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
void init() {
|
|
|
2ed0d1 |
rnd = rand();
|
|
|
2ed0d1 |
if (renderToFiles)
|
|
|
2ed0d1 |
render(64);
|
|
|
2ed0d1 |
}
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
void draw() {
|
|
|
2ed0d1 |
double pmx = mx, pmy = my;
|
|
|
2ed0d1 |
mx = mouseX(), my = mouseY();
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
double w = windowGetWidth();
|
|
|
2ed0d1 |
double h = windowGetHeight();
|
|
|
2ed0d1 |
saveState();
|
|
|
2ed0d1 |
translate(w/2, h/2);
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
int ml = mouseDown("left");
|
|
|
2ed0d1 |
int mr = mouseDown("right");
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
ax += ml ? pmx - mx : windowGetFrameTime()*360/2;
|
|
|
2ed0d1 |
if (ml || mr) ay += my - pmy;
|
|
|
2ed0d1 |
ax = fmod(ax, 360);
|
|
|
2ed0d1 |
ay = fmod(ay, 360);
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
double step = boxStep*boxSize/8.0;
|
|
|
2ed0d1 |
double mat[9] = {step, 0, 0, 0, 0, step, 0, -step, 0};
|
|
|
2ed0d1 |
mat3rotY(mat, ax);
|
|
|
2ed0d1 |
mat3rotX(mat, ay);
|
|
|
2ed0d1 |
double vec[3] = {-4, -4, -4};
|
|
|
2ed0d1 |
vec3trans(vec, mat);
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
Painter p = {};
|
|
|
2ed0d1 |
mat3cpy(p.mat, mat);
|
|
|
2ed0d1 |
p.ox = vec[0]; p.oy = vec[1];
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
if (textToDraw) {
|
|
|
2ed0d1 |
int rows, cols;
|
|
|
2ed0d1 |
drawStr(NULL, 0, 0, textToDraw, 0, &rows, &cols);
|
|
|
2ed0d1 |
p.ox -= (cols - 1)*boxStep/2;
|
|
|
2ed0d1 |
p.oy -= (rows - 1)*boxStep/2;
|
|
|
2ed0d1 |
drawStr(&p, boxStep, boxStep, textToDraw, 0, &rows, &cols);
|
|
|
2ed0d1 |
} else {
|
|
|
2ed0d1 |
drawAllLetters(&p);
|
|
|
2ed0d1 |
}
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
restoreState();
|
|
|
2ed0d1 |
}
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
int main(int argc, char **argv) {
|
|
|
2ed0d1 |
initCurvePoints();
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
windowSetSize(768, 768);
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
if (argc > 1) {
|
|
|
2ed0d1 |
textToDraw = argv[1];
|
|
|
2ed0d1 |
if (argc > 2 && strcmp(argv[2], "render") == 0) renderToFiles = 1;
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
int rows, cols;
|
|
|
2ed0d1 |
drawStr(NULL, 0, 0, textToDraw, 0, &rows, &cols);
|
|
|
2ed0d1 |
double w = boxStep*cols;
|
|
|
2ed0d1 |
if (w > 1024) boxStep *= 1024/w;
|
|
|
2ed0d1 |
double h = boxStep*rows;
|
|
|
2ed0d1 |
if (h > 768) boxStep *= 768/h;
|
|
|
2ed0d1 |
windowSetSize( (int)ceil(boxStep*cols - 1e-5), (int)ceil(boxStep*rows - 1e-5) );
|
|
|
2ed0d1 |
} else {
|
|
|
2ed0d1 |
printf(
|
|
|
2ed0d1 |
"Usage: message3d <message> [render]\n"</message>
|
|
|
2ed0d1 |
" - render path is hardcoded to data/output/message3d/msgXXXX.png\n" );
|
|
|
2ed0d1 |
}
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
windowSetVariableFrameRate();
|
|
|
2ed0d1 |
windowSetResizable(TRUE);
|
|
|
2ed0d1 |
windowSetInit(&init);
|
|
|
2ed0d1 |
windowSetDraw(&draw);
|
|
|
2ed0d1 |
windowRun();
|
|
|
2ed0d1 |
}
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
|
|
|
2ed0d1 |
|