From: Ian Jackson Date: Sun, 30 Dec 2007 22:23:41 +0000 (+0000) Subject: can rescale X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=moebius2.git;a=commitdiff_plain;h=2e8e765ae894f9921fa97db2f21915662f162224;ds=sidebyside can rescale --- diff --git a/common.c b/common.c index b87dedb..bc4dcae 100644 --- a/common.c +++ b/common.c @@ -2,9 +2,6 @@ * Generally useful stuff. */ -#include -#include - #include "common.h" double magnD(const double pq[D3]) { diff --git a/common.h b/common.h index d6d1e58..1b79fe8 100644 --- a/common.h +++ b/common.h @@ -16,6 +16,12 @@ #include #include #include +#include + +#include +#include +#include +#include #define D3 3 diff --git a/primer.c b/primer.c index eaa3459..a21dded 100644 --- a/primer.c +++ b/primer.c @@ -16,10 +16,11 @@ int main(int argc, const char **argv) { FOR_VERTEX(v) { int x= v & XMASK; /* distance along strip */ - int y= y >> YSHIFT; /* distance across strip */ + int y= v >> YSHIFT; /* distance across strip */ double u= y * 1.0 / (Y-1); double v= x * M_PI / (X-1); /* SGT's u runs 0..pi along the strip */ - K printf("print %c(%.*g,%.*g)\n", + K printf("print %c%c(%.*g,%.*g)\n", + "+-+"[k], "xyz"[k], DBL_DIG+2,u, DBL_DIG+2,v); } diff --git a/project.c b/project.c index 2d24f08..0921edf 100644 --- a/project.c +++ b/project.c @@ -15,6 +15,12 @@ static Triangle trisbuffer[MAXTRIS], *displaylist[MAXTRIS]; static int ntris; static Vertices conformation; +#define STATIC_MATRIX(x) \ + static double x[D3][D3]; \ + static gsl_matrix x##_gsl= { D3,D3,D3,&x[0][0] }; + +STATIC_MATRIX(transform); + const char *input_filename; static void read_input(void) { @@ -23,7 +29,7 @@ static void read_input(void) { f= fopen(input_filename, "rb"); if (!f) diee("input file"); errno= 0; - r= fread(&conformation,1,sizeof(conformation),f); if (r!=1) diee("fread"); + r= fread(&conformation,sizeof(conformation),1,f); if (r!=1) diee("fread"); fclose(f); } @@ -49,7 +55,8 @@ static void addtriangle(int va, int vb, int vc) { static void generate_display_list(void) { int vb, ve[3], e; - + + ntris= 0; FOR_VERTEX(vb) { /* We use the two triangles in the parallelogram vb, vb+e1, vb+e0, vb+e2. * We go round each triangle clockwise (although our surface is non- @@ -68,8 +75,8 @@ static int dl_compare(const void *tav, const void *tbv) { const Triangle *const *tbp= tbp, *tb= *tbp; double za= ta->vertex[0][2]; double zb= tb->vertex[0][2]; - return za > zb ? +1 : - za < zb ? -1 : 0; + return za > zb ? -1 : + za < zb ? +1 : 0; } static void sort_display_list(void) { @@ -84,7 +91,8 @@ static Display *display; static Pixmap pixmap, doublebuffers[2]; static Window window; static GC linegc, fillgc; -static int wwidth=WSZ, wheight=WSZ, currentbuffer; +static int wwidth=WSZ, wheight=WSZ, wmaxdim=WSZ, currentbuffer; +static int ncut; static double scale= WSZ * 0.3; static double eye_z= -10, eye_x= 0; @@ -105,34 +113,45 @@ static void drawtriangle(const Triangle *t) { double x= v[0]; double y= v[1]; double z= v[2]; - if (z < cut_z) return; + + if (z < cut_z) { ncut++; return; } + double zezezp= eye_z / (eye_z - z); - points[i].x= scale * (zezezp * (x - eye_x) + eye_x); - points[i].y= scale * (zezezp * y ); + points[i].x= scale * (zezezp * (x - eye_x) + eye_x) + WSZ/2; + points[i].y= scale * (zezezp * y ) + WSZ/2; } points[3]= points[0]; - - XA(! XFillPolygon(display,pixmap,fillgc, points,3,Convex,CoordModeOrigin) ); - XA(! XDrawLines(display,pixmap,linegc,points, 4,CoordModeOrigin) ); + + XA( XFillPolygon(display,pixmap,fillgc, points,3,Convex,CoordModeOrigin) ); + XA( XDrawLines(display,pixmap,linegc,points, 4,CoordModeOrigin) ); } +static const unsigned long core_event_mask= + ButtonPressMask|ButtonReleaseMask|StructureNotifyMask|ButtonMotionMask; + static void display_prepare(void) { XGCValues gcv; XSetWindowAttributes wa; int screen, depth; XVisualInfo vinfo; + XSizeHints hints; XA( display= XOpenDisplay(0) ); screen= DefaultScreen(display); depth= DefaultDepth(display,screen); - XA(! XMatchVisualInfo(display,screen,depth, TrueColor,&vinfo) ); + XA( XMatchVisualInfo(display,screen,depth, TrueColor,&vinfo) ); - wa.event_mask= ButtonPress|ConfigureNotify; + wa.event_mask= core_event_mask; XA( window= XCreateWindow(display, DefaultRootWindow(display), - 10,10, wwidth,wheight, 0,depth, + 0,0, wwidth,wheight, 0,depth, InputOutput, vinfo.visual, CWEventMask, &wa) ); + hints.flags= USPosition; + hints.x= 10; + hints.y= 10; + XSetWMNormalHints(display,window,&hints); + for (currentbuffer=0; currentbuffer<2; currentbuffer++) { XA( pixmap= XCreatePixmap(display,window,wwidth,wheight,depth) ); doublebuffers[currentbuffer]= pixmap; @@ -155,11 +174,13 @@ static void display_conformation(void) { int i; pixmap= doublebuffers[currentbuffer]; - XA(! XFillRectangle(display,pixmap,fillgc,0,0,wwidth,wheight) ); - for (i=0, t=displaylist; idelta((x - drag_last_x) * 1.0 / wmaxdim, + (y - drag_last_y) * 1.0 / wmaxdim); + drag_last_x= x; + drag_last_y= y; +} + +static void event_button(XButtonEvent *e) { + if (e->window != window || !e->same_screen) return; + if (e->type == ButtonPress) { + if (e->state || drag != &drag_none) { + printf("drag=%s press state=0x%lx abandon\n", + drag->name, (unsigned long)e->state); + drag->abandon(); + drag= &drag_none; + return; + } + switch (e->button) { + case Button1: drag= &drag_rotate; break; + case Button2: drag= &drag_scale; break; + default: printf("unknown drag start %d\n", e->button); + } + printf("drag=%s press button=%lu start %d,%d\n", + drag->name, (unsigned long)e->button, e->x, e->y); + drag_last_x= e->x; + drag_last_y= e->y; + drag->start(); + } + if (e->type == ButtonRelease) { + printf("drag=%s release %d,%d\n", drag->name, e->x, e->y); + drag_position(e->x, e->y); + drag->conclude(); + drag= &drag_none; + } +} + +static void event_motion(int x, int y) { + printf("drag=%s motion %d,%d\n", drag->name, x, y); + drag_position(x,y); +} + +static void event_config(XConfigureEvent *e) { printf("configure\n"); } + int main(int argc, const char *const *argv) { + XEvent event; + int motion_deferred=0, motion_x=-1, motion_y=-1; + if (argc != 2 || argv[1][0]=='-') { fputs("need filename\n",stderr); exit(8); } @@ -181,7 +319,35 @@ int main(int argc, const char *const *argv) { read_input(); display_prepare(); show(); - XSync(display,0); - for (;;); + + XMapWindow(display,window); + for (;;) { + if (motion_deferred) { + int r= XCheckMaskEvent(display,~0UL,&event); + if (!r) { + event_motion(motion_x, motion_y); + motion_deferred=0; + continue; + } + } else { + XNextEvent(display,&event); + } + switch (event.type) { + + case ButtonPress: + case ButtonRelease: event_button(&event.xbutton); break; + + case ConfigureNotify: event_config(&event.xconfigure); break; + + case MotionNotify: + motion_x= event.xmotion.x; + motion_y= event.xmotion.y; + motion_deferred= 1; + continue; + + default: + printf("unknown event type %u 0x%x\n", event.type,event.type); + } + } }