chiark / gitweb /
linear interpolation works; view presets
authorIan Jackson <ian@davenant.greenend.org.uk>
Sat, 19 Jan 2008 00:47:38 +0000 (00:47 +0000)
committerIan Jackson <ian@davenant.greenend.org.uk>
Sat, 19 Jan 2008 00:47:38 +0000 (00:47 +0000)
.bzrignore
interpolate.c
mgraph.h
view.c

index 156d40a..28f0f63 100644 (file)
@@ -10,3 +10,4 @@ vgcore.*
 prime.data
 *.cfm
 *.CFM
+.view-preset-[0-9]
index f5d7c1b..b705bcf 100644 (file)
 static struct Vertices all;
 static int computed_count[N];
 
+static void note_computed(int v, int k) {
+  assert(computed_count[v] == k);
+  computed_count[v]++;
+}
+
 static void characterise_input(void) {
   struct stat stab;
   int r;
@@ -36,9 +41,12 @@ static void characterise_input(void) {
 static void read_input(void) {
   int x,y, ox,oy, v,ov;
   
-  for (oy=y=0; y<Y; oy++, y+=INC) {
+  for (oy=0; oy<OY; oy++) {
+    y= oy*2;
     fprintf(stderr, "y=%2d>%2d", oy,y);
-    for (ox=x=0; x<X; ox++, x+=INC) {
+    for (ox=0; ox<OX; ox++) {
+      x= ox*2 + (oy&1);
+      if (x>=X) { y= (Y-1)-y; x-=X; }
       errno= 0;
       ov= (oy << OXBITS) | ox;
       v= (y << YSHIFT) | x;
@@ -73,6 +81,10 @@ typedef struct {
 
 static void traverse_next(Traverse *t) {
   int v2;
+
+  if (t->v<0)
+    return;
+  
   v2= EDGE_END2(t->v, t->e);
   if (v2>=0) {
     int e2= edge_reverse(t->v, t->e);
@@ -81,7 +93,66 @@ static void traverse_next(Traverse *t) {
   }
   t->v= v2;
 }
-     
+
+static void interpolate(void) {
+  /* four points P Q R S, although P and S may be missing
+   * interpolate in QR finding M. */
+  int xq,yq,eqr, vp,vq,vm,vr,vs, k;
+  double pqtarg[D3], srtarg[D3];
+
+  for (eqr=1; eqr!=4; eqr+=5, eqr%=V6) { /* each old edge exactly once */
+    fprintf(stderr,"eqr=%d\n",eqr);
+    for (yq=0; yq<Y; yq+=INC) {
+      fprintf(stderr," yq=%2d ",yq);
+      for (xq=((yq>>1)&1); xq<X; xq+=INC) {
+       vq= yq << YSHIFT | xq;
+       Traverse trav; trav.v=vq; trav.e=eqr;
+
+       traverse_next(&trav);
+       vm= trav.v;
+       if (vm<0) continue;
+
+       traverse_next(&trav);
+       vr= trav.v;
+       assert(vr>=0);
+
+       traverse_next(&trav);
+       traverse_next(&trav);
+       vs= trav.v;
+
+       trav.v= vq; trav.e= EDGE_OPPOSITE(eqr);
+       traverse_next(&trav);
+       traverse_next(&trav);
+       vp= trav.v;
+       
+       fprintf(stderr," 0x%02x-##-%02x-!%02x!-%02x-##-%02x",
+               vp&0xff,vq,vm,vr,vs&0xff);
+
+       if (vp>=0)
+         K pqtarg[k]= all.a[vq][k]*2 - all.a[vp][k];
+       else
+         K pqtarg[k]= all.a[vr][k];
+
+       if (vs>=0)
+         K srtarg[k]= all.a[vr][k]*2 - all.a[vs][k];
+       else
+         K srtarg[k]= all.a[vq][k];
+
+       K {
+         all.a[vm][k]= 0.5 * (all.a[vq][k] + all.a[vr][k]);
+//       pqtarg[k]= 0.5 * (pqtarg[k] + all.a[vm][k]);
+//       srtarg[k]= 0.5 * (srtarg[k] + all.a[vm][k]);
+//       all.a[vm][k]= 0.5 * (pqtarg[k] + srtarg[k]);
+         note_computed(vm,k);
+       }
+      }
+      fputc('\n',stderr);
+    }
+  }
+}
+
+#if 0
+
 static void interpolate_line(int startvertex,
                             int direction /* edge number */,
                             int nmax) {
@@ -136,10 +207,9 @@ static void interpolate_line(int startvertex,
         i++, NEXTV) {
       assert(traverse.v>=0); NEXTV; assert(traverse.v>=0);
       fputc('#',stderr);
-      assert(computed_count[traverse.v] == k);
       GA( gsl_interp_eval_e(interp,xa,ya[k], i+0.5, accel,
                            &all.a[traverse.v][k]) );
-      computed_count[traverse.v]++;
+      note_computed(traverse.v, k);
     }
     
     gsl_interp_accel_free(accel);
@@ -159,6 +229,7 @@ static void interpolate(void) {
     interpolate_line((Y-1)<<YSHIFT | x, 1, OY);
   }
 }
+#endif
 
 static void write_output(void) {
   int x, y, v, c, bad=0;
@@ -170,7 +241,7 @@ static void write_output(void) {
       c= computed_count[v];
       if (c==D3) fputc('#',stderr);
       else if (c==-1) fputc('*',stderr);
-      else { fputc('!',stderr); bad++; }
+      else { fprintf(stderr,"!%d",c); bad++; }
     }
     fputc('\n',stderr);
   }
index a5eb611..85f1a3c 100644 (file)
--- a/mgraph.h
+++ b/mgraph.h
@@ -87,6 +87,7 @@
 #define Y1 (1 << YSHIFT)
 
 #define V6 6
+#define V3 3
 
 #define FOR_VERTEX(v) \
   for ((v)=0; (v)<N; (v)++)
@@ -101,6 +102,8 @@ int edge_end2(unsigned v1, int e);
  * returns  eprime   s.t.  v1==EDGE_END2(v2,eprime) */
 int edge_reverse(int v1, int e);
 
+#define EDGE_OPPOSITE(e) (((e)+V3) % V6)
+
 #define RIM_VERTEX_P(v) (((v) & ~XMASK) == 0 || ((v) & ~XMASK) == (Y-1)*Y1)
 
 #define FOR_VEDGE_X(v1,e,v2,init,otherwise)    \
diff --git a/view.c b/view.c
index 0121cad..32ae7d7 100644 (file)
--- a/view.c
+++ b/view.c
@@ -337,7 +337,7 @@ static void make_z_rotation(double rotz[D3][D3], double cz, double sz) {
   rotz[0][0]=  cz;    rotz[0][1]=  sz;     rotz[0][2]=  0;
   rotz[1][0]= -sz;    rotz[1][1]=  cz;     rotz[1][2]=  0;
   rotz[2][0]=   0;    rotz[2][1]=   0;     rotz[2][2]=  1;
-}  
+}
 
 static void drag_rotate_delta(double dx, double dy) {
   /* We multiple our transformation matrix by a matrix:
@@ -540,10 +540,38 @@ static void event_motion(int x, int y) {
   drag_position(x,y);
 }
 
+static void transform_preset_record(const char *fn, const char *fn_new) {
+  FILE *f;
+  f= fopen(fn_new,"wb");
+  if (!f) diee("open new transform");
+  if (fwrite(transform,sizeof(transform),1,f) != 1) diee("write transform");
+  if (fclose(f)) diee("fclose new transform");
+  if (rename(fn_new,fn)) diee("install transform");
+}
+
+static void transform_preset_playback(const char *fn) {
+  FILE *f;
+  f= fopen(fn,"rb");
+  if (!f && errno==ENOENT) {
+    fprintf(stderr,"no preset %s\n",fn);
+    XBell(display,100);
+    return;
+  }
+  errno= 0;
+  if (fread(transform,sizeof(transform),1,f) != 1) {
+    perror("read preset!");
+    XBell(display,100);
+    return;
+  }
+  fclose(f);
+  show();
+}
+
 static void event_key(XKeyEvent *e) {
   KeySym ks;
-  char buf[10];
-  int r;
+  XKeyEvent e_nomod;
+  char buf[10], buf_nomod[10];
+  int r, r_nomod;
 
   r= XLookupString(e,buf,sizeof(buf)-1,&ks,0);
   if (!r) {
@@ -564,11 +592,31 @@ static void event_key(XKeyEvent *e) {
     eyes_apart= eyes_apart>0 ? eyes_apart_min : eyes_apart_preferred;
     show();
     return;
-  } else {
-    printf("unknown key keycode=%d state=0x%x char=%c 0x%02x\n",
-          e->keycode, e->state, buf[0]>' ' && buf[0]<127 ? buf[0] : '?',
-          buf[0]);
   }
+
+  e_nomod= *e;
+  e_nomod.state= 0;
+  buf_nomod[0]= 0;
+  r_nomod= XLookupString(&e_nomod,buf_nomod,sizeof(buf_nomod)-1,&ks,0);
+  if (r_nomod && !buf_nomod[1] && buf_nomod[0]>='0' && buf_nomod[0]<='9') {
+    char filename[20], filename_new[25];
+    snprintf(filename,sizeof(filename)-1,".view-preset-%s",buf_nomod);
+    snprintf(filename_new,sizeof(filename_new)-1,"%s.new",filename);
+    printf("transform preset %d %s\n", e->state, filename);
+    if (e->state) transform_preset_record(filename,filename_new);
+    else transform_preset_playback(filename);
+    return;
+  }
+
+  printf("unknown key keycode=%d state=0x%x char=%c 0x%02x "
+        "[rnm=%d bnm[0,1]=0x%02x,%02x]\n",
+        e->keycode, e->state, buf[0]>' ' && buf[0]<127 ? buf[0] : '?',
+        buf[0], r_nomod, buf_nomod[0], buf_nomod[1]);
+  printf("%d %d %d %d\n",
+        r_nomod,
+        !buf_nomod[1],
+        buf_nomod[0]>='0',
+        buf_nomod[0]<='9');
 }
 
 static void event_config(XConfigureEvent *e) {