123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934 |
- extern "C"{
- #include "fxlib.h"
- }
- #include <string.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h>
- #include "stdafx.h"
- #include "defs.h"
- #define DIMX 128
- #define DIMY 64
- #define F p3
- #define T p4
- #define X p5
- #define Y p6
- #define XT p7
- #define YT p8
- static double tmin, tmax;
- static double xmin, xmax;
- static double ymin, ymax;
- #define YMAX 1000
- typedef struct {
- int x, y;
- double t;
- } DRAWBUF;
- DRAWBUF *draw_buf;
- static int draw_count;
- void
- eval_draw(void)
- {
- draw_buf=(DRAWBUF*)calloc(YMAX,sizeof(DRAWBUF));
- F = cadr(p1);
- T = caddr(p1);
- if (T == symbol(NIL)) {
- push(F);
- rewrite();
- guess();
- T = pop();
- F = pop();
- }
- push(get_binding(T));
- push(get_arglist(T));
- draw_main();
- p2 = pop();
- p1 = pop();
- set_binding_and_arglist(T, p1, p2);
-
- push(symbol(NIL));
- }
- void
- draw_main(void)
- {
- if (draw_flag) {
- draw_flag = 0;
- stop("draw calls draw");
- }
- draw_flag++;
- setup_trange();
- setup_xrange();
- setup_yrange();
- check_for_parametric_draw();
- create_point_set();
- emit_graph();
- draw_flag--;
- }
- void
- check_for_parametric_draw(void)
- {
- eval_f(tmin);
- p1 = pop();
- if (!istensor(p1)) {
- tmin = xmin;
- tmax = xmax;
- }
- }
- #define N 100
- void
- create_point_set(void)
- {
- int i, n;
- double t;
- draw_count = 0;
- for (i = 0; i <= N; i++) {
- t = tmin + ((double) i / (double) N) * (tmax - tmin);
- new_point(t);
- }
- n = draw_count;
- for (i = 0; i < n - 1; i++)
- fill(i, i + 1, 0);
- }
- void
- new_point(double t)
- {
- double x, y;
- if (draw_count >= YMAX)
- return;
- draw_buf[draw_count].x = -10000;
- draw_buf[draw_count].y = -10000;
- draw_buf[draw_count].t = t;
- draw_count++;
- get_xy(t);
- if (!isnum(XT) || !isnum(YT))
- return;
- push(XT);
- x = pop_double();
- x = (x - xmin) / (xmax - xmin);
- x = (double) DIMX * x + 0.5;
- push(YT);
- y = pop_double();
- y = (y - ymin) / (ymax - ymin);
- y = (double) DIMY * y + 0.5;
- if (x < -10000.0)
- x = -10000.0;
- if (x > 10000.0)
- x = 10000.0;
- if (y < -10000.0)
- y = -10000.0;
- if (y > 10000.0)
- y = 10000.0;
- draw_buf[draw_count - 1].x = (int) x;
- draw_buf[draw_count - 1].y = (int) y;
- }
- void
- get_xy(double t)
- {
- eval_f(t);
- p1 = pop();
- if (istensor(p1)) {
- if (p1->u.tensor->nelem >= 2) {
- XT = p1->u.tensor->elem[0];
- YT = p1->u.tensor->elem[1];
- } else {
- XT = symbol(NIL);
- YT = symbol(NIL);
- }
- return;
- }
- push_double(t);
- XT = pop();
- YT = p1;
- }
- void
- eval_f(double t)
- {
-
-
- int volatile save_tos;
- U ** volatile save_frame;
- save();
- save_tos = tos;
- save_frame = frame;
- draw_flag++;
- if (setjmp(draw_stop_return)) {
- tos = save_tos;
- push(symbol(NIL));
- frame = save_frame;
- restore();
- draw_flag--;
- return;
- }
- push_double(t);
- p1 = pop();
- set_binding(T, p1);
- push(F);
- eval();
- yyfloat();
- eval();
- restore();
- draw_flag--;
- }
- #define MAX_DEPTH 6
- void
- fill(int i, int k, int level)
- {
- int dx, dy, j;
- double t;
- if (level >= MAX_DEPTH || draw_count >= YMAX)
- return;
- dx = abs(draw_buf[i].x - draw_buf[k].x);
- dy = abs(draw_buf[i].y - draw_buf[k].y);
- if (dx < 1 && dy < 1)
- return;
- t = (draw_buf[i].t + draw_buf[k].t) / 2.0;
- j = draw_count;
- new_point(t);
- fill(i, j, level + 1);
- fill(j, k, level + 1);
- }
- void
- setup_trange(void)
- {
- save();
- setup_trange_f();
- restore();
- }
- void
- setup_trange_f(void)
- {
-
- tmin = -M_PI;
- tmax = M_PI;
- p1 = usr_symbol("trange");
- if (!issymbol(p1))
- return;
- p1 = get_binding(p1);
-
- if (!istensor(p1) || p1->u.tensor->ndim != 1 || p1->u.tensor->nelem != 2)
- return;
- push(p1->u.tensor->elem[0]);
- eval();
- yyfloat();
- eval();
- p2 = pop();
- push(p1->u.tensor->elem[1]);
- eval();
- yyfloat();
- eval();
- p3 = pop();
- if (!isnum(p2) || !isnum(p3))
- return;
- push(p2);
- tmin = pop_double();
- push(p3);
- tmax = pop_double();
- if (tmin == tmax)
- stop("draw: trange is zero");
- }
- void
- setup_xrange(void)
- {
- save();
- setup_xrange_f();
- restore();
- }
- void
- setup_xrange_f(void)
- {
-
- xmin = -10.0;
- xmax = 10.0;
- p1 = usr_symbol("xrange");
- if (!issymbol(p1))
- return;
- p1 = get_binding(p1);
-
- if (!istensor(p1) || p1->u.tensor->ndim != 1 || p1->u.tensor->nelem != 2)
- return;
- push(p1->u.tensor->elem[0]);
- eval();
- yyfloat();
- eval();
- p2 = pop();
- push(p1->u.tensor->elem[1]);
- eval();
- yyfloat();
- eval();
- p3 = pop();
- if (!isnum(p2) || !isnum(p3))
- return;
- push(p2);
- xmin = pop_double();
- push(p3);
- xmax = pop_double();
- if (xmin == xmax)
- stop("draw: xrange is zero");
- }
- void
- setup_yrange(void)
- {
- save();
- setup_yrange_f();
- restore();
- }
- void
- setup_yrange_f(void)
- {
-
- ymin = -10.0;
- ymax = 10.0;
- p1 = usr_symbol("yrange");
- if (!issymbol(p1))
- return;
- p1 = get_binding(p1);
-
- if (!istensor(p1) || p1->u.tensor->ndim != 1 || p1->u.tensor->nelem != 2)
- return;
- push(p1->u.tensor->elem[0]);
- eval();
- yyfloat();
- eval();
- p2 = pop();
- push(p1->u.tensor->elem[1]);
- eval();
- yyfloat();
- eval();
- p3 = pop();
- if (!isnum(p2) || !isnum(p3))
- return;
- push(p2);
- ymin = pop_double();
- push(p3);
- ymax = pop_double();
- if (ymin == ymax)
- stop("draw: yrange is zero");
- }
- void get_xyminmax(double* xminp, double* xmaxp, double* yminp, double* ymaxp) {
- *xminp = xmin;
- *xmaxp = xmax;
- *yminp = ymin;
- *ymaxp = ymax;
- }
- #define XOFF 0
- #define YOFF 24
- static void emit_xaxis(void);
- static void emit_yaxis(void);
- static void emit_xscale(void);
- static void emit_yscale(void);
- static void get_xzero(void);
- static void get_yzero(void);
- static int xzero, yzero;
- void
- emit_graph(void)
- {
- int i, x, y;
- Bdisp_AllClr_VRAM();
- get_xzero();
- get_yzero();
- emit_xaxis();
- emit_yaxis();
- emit_xscale();
- emit_yscale();
-
- for (i = 0; i < draw_count; i++) {
- x = draw_buf[i].x;
- y = DIMY - draw_buf[i].y;
- if (x < 0 || x > DIMX)
- continue;
- if (y < 0 || y > DIMY)
- continue;
- Bdisp_SetPoint_VRAM(x+XOFF, y+YOFF, 1);
- }
- set_has_drawn(1);
- }
- static void
- emit_xaxis(void)
- {
- int x, y, x2, y2;
- if (yzero < 0 || yzero > DIMY)
- return;
- x = XOFF;
- y = YOFF + yzero;
- x2 = XOFF + DIMX;
- y2 = YOFF + yzero;
- Bdisp_DrawLineVRAM(x, y, x2, y2);
- }
- static void
- emit_yaxis(void)
- {
- int x, y, x2, y2;
- if (xzero < 0 || xzero > DIMX)
- return;
- x = XOFF + xzero;
- y = YOFF;
- x2 = XOFF + xzero;
- y2 = YOFF + DIMY;
- Bdisp_DrawLineVRAM(x, y, x2, y2);
- }
- static void
- get_xzero(void)
- {
- double x;
- x = -((double) DIMX) * xmin / (xmax - xmin) + 0.5;
- if (x < -10000.0)
- x = -10000.0;
- if (x > 10000.0)
- x = 10000.0;
- xzero = (int) x;
- }
- static void
- get_yzero(void)
- {
- double y;
- y = -((double) DIMY) * ymin / (ymax - ymin) + 0.5;
- if (y < -10000.0)
- y = -10000.0;
- if (y > 10000.0)
- y = 10000.0;
- yzero = DIMY - (int) y;
- }
- static void emit_xscale_f(int, char *);
- static void
- emit_xscale(void)
- {
- static char s[100];
- sprintf(s, "%g", xmin);
- emit_xscale_f(0, s);
- sprintf(s, "%g", xmax);
- emit_xscale_f(DIMX, s);
- }
- static void
- emit_xscale_f(int xx, char *s)
- {
- int w, x, y;
- y = 0;
- w = 0;
- PrintMini( w, y, (unsigned char*)s, 0);
- x = XOFF + xx;
- if(x >= DIMX) x = x-w;
- y = YOFF + yzero - 24+2;
- PrintMini( x, y, (unsigned char*)s, 0);
- }
- static void emit_yscale_f(int, char *);
- static void
- emit_yscale(void)
- {
- static char s[100];
- sprintf(s, "%g", ymax);
- emit_yscale_f(0, s);
- sprintf(s, "%g", ymin);
- emit_yscale_f(DIMY, s);
- }
- static void
- emit_yscale_f(int yy, char *s)
- {
- int w, x, y;
- y = 0;
- w = 0;
- PrintMini( w, y, (unsigned char*)s, 0);
- x = xzero - w;
- y = YOFF + yy;
- if(y >= DIMY) y = y-9;
- y -= 24;
- PrintMini( x, y, (unsigned char*)s, 0);
- }
|