diff --git a/bin/index.html b/bin/index.html index 237e5bd..0b27c16 100644 --- a/bin/index.html +++ b/bin/index.html @@ -33,13 +33,17 @@

Je to tedy jednoduchý kalkulátor, jde napsat výraz s normální notací (+-*/^), obsahující čísla (i desetinná), který to normálně vyhodnotí. Postupně přibyly proměnné (jen písmenkové řetězce), které mohou mít i rozsah ve - kterém se pak výraz zobrazí jako funkce. Komentáře jsou ve složených závorkách. Vložené matematické funkce + kterém se pak výraz zobrazí jako funkce. Syntaxe je
+ proměnná = dolní_mez , horní_mez , počet_bodů
+ a použije se pro vodorovnou osu, poslední řádek je pak výraz, jehož hodnota je na svislé ose. Ostatní "proměnné" + jsou pak fakticky jen pojmenované konstanty. Zobrazovaných funkcí (výrazů) může být víc, první určí limity + zobrazení na ose "y". Komentáře jsou ve složených závorkách. Vložené matematické funkce jsou sin(), cos(), exp(), log() (přirozené).Na konci výrazu musí být ENTER.

Jsou v tom chyby, celé je to vlasně hloupost, celé by to šlo napsat v javascriptu mnohem jednodušeji, - ale v podstatě to funguje a jde si podle toho udělat představu, jak daná funkce vypadá. Zdrojáky v licenci - MIT přikládám. Pro kompilaci je použit jen clang a jím kompilovaná C-čková knihovna - newlib. + ale v podstatě to funguje a jde si podle toho udělat představu, jak daná funkce vypadá. Odkaz na zdrojáky v licenci + MIT přikládám. Pro kompilaci je použit jen + clang a jím kompilovaná C-čková knihovna newlib.

diff --git a/bin/index.js b/bin/index.js index ead361f..e3749b9 100644 --- a/bin/index.js +++ b/bin/index.js @@ -28,7 +28,6 @@ window.onload = async function() { const utf8decoder = new TextDecoder(); const obj = JSON.parse (utf8decoder.decode(view)); // console.log (obj); - if (!obj) obj = '{"name":"nothing"}'; polyLine (xview, yview, len, obj); }, }, @@ -86,13 +85,16 @@ function drawLine (ctx, line, x, y) { } ctx.stroke(); } +const colors = ['#00ff00', '#ff0000', '#00ffff', '#ff00ff']; +var colorIndex = 0; function polyLine (ax, ay, len, obj) { // console.log (ax, ay); const ctx = canvas.getContext("2d"); - ctx.clearRect(0, 0, canvas.width, canvas.height); - ctx.font = '16px serif'; - ctx.textAlign = 'left'; if (obj.name === "axes") { + colorIndex = 0; + ctx.clearRect(0, 0, canvas.width, canvas.height); + ctx.font = '16px serif'; + ctx.textAlign = 'left'; drawLine (ctx, obj.x, 0, 0); drawLine (ctx, obj.y, 0, 0); const ndotsx = obj.xdots.length; @@ -106,7 +108,7 @@ function polyLine (ax, ay, len, obj) { ctx.lineTo(ax[n], ay[n]); } ctx.lineWidth = 3; - ctx.strokeStyle = "#00ff00"; + ctx.strokeStyle = colors [colorIndex++ % 4]; ctx.stroke(); } async function getFile (name) { diff --git a/bin/test.txt b/bin/test.txt index ebc7b0b..3de8b2a 100644 --- a/bin/test.txt +++ b/bin/test.txt @@ -2,6 +2,9 @@ max=10 x=-max,max,1000 a=1/4 +z=10 omega=2*pi phi=omega/4 -1.e-8 * sin (omega*x - phi) * exp (-(x*a)^2) + z * sin (omega*x + phi) * exp (-(x*a)^2) + z * exp (-(x*a)^2) {kladná obálka} +-z * exp (-(x*a)^2) {záporná obálka} diff --git a/calculator.cpp b/calculator.cpp index 4eccc2a..4cf051a 100644 --- a/calculator.cpp +++ b/calculator.cpp @@ -47,7 +47,8 @@ Variable::Variable(const char * name) { data = & zero; } } -extern void emitData (double * x, double * y, const int len); +static bool first = false; +extern void emitData (double * x, double * y, const int len, const bool first); void addExpression (Expression * e) { if (main_data->root) delete main_data->root; main_data->root = e; @@ -63,17 +64,20 @@ void addExpression (Expression * e) { if (n <= 0) return; double * vx = new double [n + 1]; double * vy = new double [n + 1]; - // printf("n=%d\n", n); for (int i=0; ivalue = x; const double y = e->eval(); vx[i] = x; vy[i] = y; } - emitData (vx, vy, n+1); + r->value = x0; + // printf("add expression first=%d, n=%d\n", (int) first, n); + emitData (vx, vy, n+1, first); + if (first) first = false; delete [] vx; delete [] vy; } void initData () { + first = true; main_data = new CommonData(); } void finiData () { diff --git a/wasm.cpp b/wasm.cpp index 2d9bd57..a7c4174 100644 --- a/wasm.cpp +++ b/wasm.cpp @@ -5,6 +5,7 @@ #include #include "calculator.h" #include "heap.h" +#include "wasm.h" extern "C" void EXPORT(init) (const int memlen); extern "C" int EXPORT(cAlloc) (int len); extern "C" void EXPORT(compute) (char * ptr, int len); @@ -38,98 +39,14 @@ void compute (char * ptr, int len) { free (ptr); finiData(); } -struct Canvas { - double width, height; - double xscale, yscale; - double xofset, yofset; - float xt (const double x) { - return float (xscale * (x - xofset)); - } - float yt (const double y) { - return float (height - yscale * (y - yofset)); - } -}; -static const char * multipliers [] = {"f","p","n","μ","m","","k","M","G","T","P"}; -struct Stepping { - double b,e,s; - char fmtbuf [16]; - explicit Stepping (const double from, const double to) { - double lp; - const double z = log10 (fabs (to - from)); - const double fp = modf (z, & lp); - if (fp < 0.30103) s = 1.0; - else if (fp > 0.69897) s = 5.0; - else s = 2.0; - int ip = int (lp) - 1; - if (z < 0.0) ip -= 1; - s *= ::pow (10.0, double (ip)); - do { - const int k = int (fabs(to - from) / s); - b = round (from / s) * s; - e = round (to / s) * s; - if (k > 50) s *= 10.0; // prevence přeplnění osy, nevím proč, ale tohle to odstraní - else break; // patrně log10() nedává přesně to, co bych čekal - } while (true); - } - void f () {printf("stepping = %g, b = %g, e = %g\n", s, b, e);} - char * ing (const double x, int n=0) { - if (fabs(x) < 0.5 * s) { - fmtbuf[n++] = ' '; - fmtbuf[n++] = '\0'; - return fmtbuf; - } - if (x < 0.0) { - fmtbuf[n++] = '-'; - return ing (-x, n); - } - if (x > 0.0) { - double ip; - const double fp = modf(log10(x), & ip); - int pi = ip, ofs = 5 * 3; - if (pi < -ofs) pi = -ofs; - if (pi > 18 ) pi = 18; - const div_t dt = div(pi + ofs, 3); - n += snprintf (fmtbuf + n, 16 - n, "%g%s", ::pow (10.0, fp + double (dt.rem)), multipliers [dt.quot]); - } - return fmtbuf; - } -protected: -}; static Canvas canvas; void resizeCanvas (int x, int y) { printf("resizeCanvas: x=%d, y=%d\n", x, y); canvas.width = x; canvas.height = y; } -void emitData (double * x, double * y, const int len) { - double ymin = 1.0e100, ymax = -1.0e100; - for (int n=0; n ymax) ymax = y[n]; - // printf("f(%g) = %g\n", x[n], y[n]); - } - const double xmin = x[0]; - const double xmax = x[len - 1]; - printf("xmin = %g, xmax = %g, ymin = %g, ymax = %g\n", xmin, xmax, ymin, ymax); - const double f = 1.0; - ymin *= f; - ymax *= f; - canvas.xofset = xmin; - canvas.yofset = ymin; - canvas.xscale = canvas.width / (xmax - xmin); - canvas.yscale = canvas.height / (ymax - ymin); - Stepping sx (xmin, xmax), sy (ymin, ymax); - // sx.f(); sy.f(); - - float * ix = new float [len]; // float32 stačí - float * iy = new float [len]; - for (int n=0; n ymax) ymax = y[n]; + // printf("f(%g) = %g\n", x[n], y[n]); + } + const double xmin = x[0]; + const double xmax = x[len - 1]; + printf("xmin = %g, xmax = %g, ymin = %g, ymax = %g\n", xmin, xmax, ymin, ymax); + canvas.xofset = xmin; + canvas.yofset = ymin; + canvas.xscale = canvas.width / (xmax - xmin); + canvas.yscale = canvas.height / (ymax - ymin); + Stepping sx (xmin, xmax), sy (ymin, ymax); + // sx.f(); sy.f(); + + n += CreateJSON (json, json_max, canvas, sx, sy); + } else { + n += snprintf(json + n, json_max - n, "{ \"name\":\"unknown\" }"); + } /* Pro kreslení na canvas se používají 2 metody: * 1. Přímé předání dat pomocí ukazatelů. * Ukázalo se, že typ int nestačí, zaokrouhlení je kostrbaté, double je zbytečně velký, @@ -166,6 +110,13 @@ void emitData (double * x, double * y, const int len) { * (3. zde nepoužito) Vytvoříme přímo javascript zdroják, který to celé vykreslí * a ten pak spustíme v javascriptu pomocí eval(). Funguje také, ale je to divné. * */ + float * ix = new float [len]; // float32 stačí + float * iy = new float [len]; + for (int k=0; k +#include +struct Canvas { + double width, height; + double xscale, yscale; + double xofset, yofset; + float xt (const double x) const { + return float (xscale * (x - xofset)); + } + float yt (const double y) const { + return float (height - yscale * (y - yofset)); + } +}; +static const char * multipliers [] = {"f","p","n","μ","m","","k","M","G","T","P"}; +struct Stepping { + double b,e,s; + char fmtbuf [16]; + explicit Stepping (const double from, const double to) { + double lp; + const double z = log10 (fabs (to - from)); + const double fp = modf (z, & lp); + if (fp < 0.30103) s = 1.0; + else if (fp > 0.69897) s = 5.0; + else s = 2.0; + int ip = int (lp) - 1; + if (z < 0.0) ip -= 1; + s *= ::pow (10.0, double (ip)); + do { + const int k = int (fabs(to - from) / s); + b = round (from / s) * s; + e = round (to / s) * s; + if (k > 50) s *= 10.0; // prevence přeplnění osy, nevím proč, ale tohle to odstraní + else break; // patrně log10() nedává přesně to, co bych čekal + } while (true); + } + void f () {printf("stepping = %g, b = %g, e = %g\n", s, b, e);} + char * ing (const double x, int n=0) { + if (fabs(x) < 0.5 * s) { + fmtbuf[n++] = ' '; + fmtbuf[n++] = '\0'; + return fmtbuf; + } + if (x < 0.0) { + fmtbuf[n++] = '-'; + return ing (-x, n); + } + if (x > 0.0) { + double ip; + const double fp = modf(log10(x), & ip); + int pi = ip, ofs = 5 * 3; + if (pi < -ofs) pi = -ofs; + if (pi > 18 ) pi = 18; + const div_t dt = div(pi + ofs, 3); + n += snprintf (fmtbuf + n, 16 - n, "%g%s", ::pow (10.0, fp + double (dt.rem)), multipliers [dt.quot]); + } + return fmtbuf; + } +}; +#endif // _WASM_H_DEF