chiark / gitweb /
new topology; check that graph and stuff makes sense
authorIan Jackson <ian@davenant.relativity.greenend.org.uk>
Tue, 1 Jan 2008 20:24:47 +0000 (20:24 +0000)
committerIan Jackson <ian@davenant.relativity.greenend.org.uk>
Tue, 1 Jan 2008 20:24:47 +0000 (20:24 +0000)
bgl.cpp
mgraph.c
mgraph.h
primer.c
view.c

diff --git a/bgl.cpp b/bgl.cpp
index 28c6ee6..30a1767 100644 (file)
--- a/bgl.cpp
+++ b/bgl.cpp
@@ -99,7 +99,7 @@ class OutEdgeIterator :
 
   static int voe_min(int _v) { return (_v & YMASK) ? 2 : 3; }
   static int voe_max(int _v) { return (~_v & YMASK) ? V6 : 4; }
-  static int voe_degree(int _v) { return (_v & YMASK | ~_v & YMASK) ? 4 : V6; }
+  static int voe_degree(int _v) { return RIM_VERTEX_P(_v) ? 4 : V6; }
 };
  
 typedef counting_iterator<int> VertexIterator;
index cf57624..23a10e3 100644 (file)
--- a/mgraph.c
+++ b/mgraph.c
@@ -4,19 +4,23 @@
 
 #include "mgraph.h"
 
-static const unsigned dx[V6]= {  +1,  +1,   0,  -1,  -1,   0  },
-                      dy[V6]= {   0, -Y1, -Y1,   0, +Y1, +Y1  };
+static const unsigned dx[2][V6]= {{  +1,   0,  -1,  -1,  -1,   0  },
+                                 {  +1,  +1,   0,  -1,   0,  +1  }},
+                      dy[V6]=     {   0, -Y1, -Y1,   0, +Y1, +Y1  };
 
 int edge_end2(unsigned v1, int e) {
   unsigned x, y;
 
   y= (v1 & YMASK) + dy[e];
-  if (y & ~YMASK) return -1;
+  if (y >= Y*Y1) return -1;
 
-  x= (v1 & XMASK) + dx[e];
+  x= (v1 & XMASK) + dx[(v1 >> YSHIFT) & 1][e];
   if (x & ~XMASK) {
+    //int orgy= y;
     y= (Y-1)*Y1 - y;
     x &= XMASK;;
+    //printf("%40s %02x -%d-> %02x  (was %02x) \n", "", v1, e, x|y, x|orgy);
   }
+  
   return x | y;
 }
index 0870489..de26852 100644 (file)
--- a/mgraph.h
+++ b/mgraph.h
@@ -4,26 +4,35 @@
 /*
  * Vertices in strip are numbered as follows:
  *
- *     ___ X-2 ___ X-1 ___  0  ___  1  ___  2  ___  3  ___  4  __
- *         Y-1     Y-1     0       0       0       0       0 
+ *                       |
+ *     ___ X-2 ___ X-1 ___| 0  ___  1  ___  2  ___  3  ___  4  __
+ *         Y-1     Y-1    |0       0       0       0       0
  *        /  \    /  \    /  \    /  \    /  \    /  \    /  \
- *       /    \  /    \  /    \  /    \  /    \  /    \  /    \
- *     X-3 ___ X-2 ___ X-1 ___  0  ___  1  ___  2  ___  3  ___  4
- *     Y-2     Y-2     Y-2     1       1       1       1       1
- *       \    /  \    /  \    /  \    /  \    /  \    /  \    /
+ *       /    \  /    \  /|   \  /    \  /    \  /    \  /    \
+ *     X-3 ___ X-2 ___ X-1|___  0  ___  1  ___  2  ___  3  ___  4
+ *     Y-2     Y-2     Y-2|    1       1       1       1       1
+ *       \    /  \    /  \|   /  \    /  \    /  \    /  \    /
  *        \  /    \  /    \  /    \  /    \  /    \  /    \  /
- *     ___ X-3 ___ X-2 ___ X-1 ___  0  ___  1  ___  2  ___  3  __
- *         Y-3     Y-3     Y-3     2       2       2       2 
- *
- *       .   .   .   .   .   .   .   .   .   .   .   .   .   .   .
- *
- *      X-4 ___ X-3 ___ X-2 ___ X-1 ___ 0   ___ 1   ___ 2   ___ 3
- *       1       1       1       1      Y-2     Y-2     Y-2     Y-2
- *        \    /  \    /  \    /  \    /  \    /  \    /  \    /
- *         \  /    \  /    \  /    \  /    \  /    \  /    \  /
- *      ___ X-4 ___ X-3 ___ X-2 ___ X-1 ___ 0   ___ 1   ___ 2   __
- *           0       0       0       0      Y-1     Y-1     Y-1
- *
+ *     ___ X-2 ___ X-1 ___| 0  ___  1  ___  2  ___  3  __   4 ___
+ *         Y-3     Y-3    |2       2       2       2      2
+ *        /  \    /  \    /  \    /  \    /  \    /  \    /  \
+ *       /    \  /    \  /|   \  /    \  /    \  /    \  /    \
+ *     X-3 ___ X-2 ___ X-1|___  0  ___  1  ___  2  ___  3  ___  4
+ *     Y-4     Y-4     Y-4|    3       3       3       3       3
+ *                       |
+ *       .   .   .   .   .|  .   .   .   .   .   .   .   .   .   .
+ *                       |
+ *     ___ X-2 ___ X-1 ___| 0  ___  1  ___  2  ___  3  ___  4 ___
+ *         2       2      |Y-3     Y-3     Y-3     Y-3     Y-3
+ *        /  \    /  \    /  \    /  \    /  \    /  \    /  \
+ *       /    \  /    \  /|   \  /    \  /    \  /    \  /    \
+ *          __ X-2 ___ X-1|___  0  ___  1  ___  2  ___  3  ___  3  ___  4
+ *             1       1  |    Y-2     Y-2     Y-2     Y-2     Y-2     Y-2
+ *    /  \    /  \    /  \|   /  \    /  \    /         \    /  \    /
+ *   /    \  /    \  /    \  /    \  /    \  /   \  /    \  /
+ *  -3 ___ X-2 ___ X-1 ___| 0  ___  1  ___  2  ___  3  ___  4 ___
+ *  0      0       0      |Y-1     Y-1     Y-1     Y-1     Y-1
+ *                       |
  * Node x,y for
  *   0 <= x < X     x = distance along
  *   0 <= y < Y     y = distance across
  *
  * We label edges as follows:        Or in the square view:
  *
- *                 \2   /1                 2  1  
- *                  \  /                   | /   
- *               ___ 0   __                |/    
- *               3    1   0             3--*--0  
- *                  /  \                  /|     
- *                4/   5\                / |     
+ *                 \2   /1                 2  1
+ *                  \  /                   | /
+ *               ___ 0   __                |/
+ *               3    1   0             3--*--0
+ *                  /  \                  /|
+ *                4/   5\                / |
  *                                      4  5
  *
  *                                   (This makes the numbering
 
 #include "common.h"
 
-#define DIMBITS 5
+#define DIMBITS 4
 
 #define XBITS DIMBITS
 #define X (1<<XBITS)
 #define YBITS DIMBITS
-#define Y (1<<YBITS)
+#define Y ((1<<YBITS) - 1)
 
 /* vertex number:   0000 | y     | x
  *                        YBITS   XBITS
@@ -73,7 +82,7 @@
 #define XMASK (X-1)
 #define YSHIFT XBITS
 #define Y1 (1 << YSHIFT)
-#define YMASK ((Y-1) << YSHIFT)
+#define YMASK (Y << YSHIFT)
 
 #define DIM (N*D3)
 
@@ -88,6 +97,8 @@
 extern int edge_end2(unsigned v1, int e);
 #define EDGE_END2 edge_end2
 
+#define RIM_VERTEX_P(v) (((v) & YMASK) == 0 || ((v) & YMASK) == (Y-1)*Y1)
+
 #define FOR_VEDGE_X(v1,e,v2,init,otherwise)    \
   FOR_VPEDGE((v1),(e))                         \
     if (((v2)= EDGE_END2((v1),(e)),            \
index 42c4019..3d9244a 100644 (file)
--- a/primer.c
+++ b/primer.c
@@ -22,8 +22,8 @@ int main(int argc, const char **argv) {
 
     /* SGT's v runs 0..pi along the strip, where the join is at 0==pi.
      * So that corresponds to 0..X (since 0==X in our scheme). */
-    double v= x * M_PI / X;
-    
+    double v= (x*2 + (y&1)) * M_PI / (X*2);
+
     K printf("print %c%c( %-*.*g, %-*.*g);  # %03x %2d %2d\n",
             "+-+"[k], "xyz"[k],
             prec+5,prec,u, prec+5,prec,v,
diff --git a/view.c b/view.c
index 72ea237..cfa3975 100644 (file)
--- a/view.c
+++ b/view.c
@@ -54,6 +54,8 @@ static void transform_coordinates(void) {
   }
 }
 
+static int vertex_in_triangles[N], vertex_in_triangles_checked;
+
 static void addtriangle(int va, int vb, int vc) {
   Triangle *t= &trisbuffer[ntris];
   int k;
@@ -64,23 +66,41 @@ static void addtriangle(int va, int vb, int vc) {
     t->vertex[1][k]= conformation[vb][k];
     t->vertex[2][k]= conformation[vc][k];
   }
+  if (!vertex_in_triangles_checked) {
+    vertex_in_triangles[va]++;
+    vertex_in_triangles[vb]++;
+    vertex_in_triangles[vc]++;
+  }
   displaylist[ntris++]= t;
 }
 
 static void generate_display_list(void) {
-  int vb, ve[3], e;
+  int vb, ve[V6], e;
 
   ntris= 0;
   FOR_VERTEX(vb) {
-    /* We use the two triangles in the parallelogram vb, vb+e0, vb+e1, vb+e2.
+    /* We use the two triangles in the parallelogram vb, vb+e5, vb+e0, vb+e1.
      * We go round each triangle clockwise (although our surface is non-
-     * orientable so it shouldn't matter).
+     * orientable so it shouldn't matter).  Picking the parallelogram
+     * to our right avoids getting it wrong at the join.
      */
-    for (e=0; e<3; e++) ve[e]= EDGE_END2(vb,e);
-    if (ve[1]>=0) {
-      if (ve[0]>=0) addtriangle(vb,ve[0],ve[1]);
-      if (ve[2]>=0) addtriangle(vb,ve[1],ve[2]);
+    for (e=0; e<V6; e++) ve[e]= EDGE_END2(vb,e);
+    assert(ve[0]>=0);
+    if (ve[5]>=0) addtriangle(vb,ve[0],ve[5]);
+    if (ve[1]>=0) addtriangle(vb,ve[1],ve[0]);
+  }
+
+  if (!vertex_in_triangles_checked) {
+    int v, expd;
+    FOR_VERTEX(v) {
+      expd= RIM_VERTEX_P(v) ? 3 : 6;
+      if (vertex_in_triangles[v] != expd) {
+       fprintf(stderr,"vertex %02x used for %d triangles, expected %d\n",
+               v, vertex_in_triangles[v], expd);
+       abort();
+      }
     }
+    vertex_in_triangles_checked= 1;
   }
 }    
 
@@ -578,6 +598,23 @@ static void check_input(void) {
   show();
 }
 
+static void topocheck(void) {
+  int v1,e,v2,eprime,v1prime, count;
+  FOR_EDGE(v1,e,v2) {
+    count= 0;
+    FOR_VEDGE(v2,eprime,v1prime)
+      if (v1prime==v1) count++;
+    if (count!=1) {
+      fprintf(stderr,"%02x -%d-> %02x  reverse edge count = %d!\n",
+             v1,e,v2, count);
+      FOR_VEDGE(v2,eprime,v1prime)
+       fprintf(stderr,"%02x -%d-> %02x -> %d -> %02x\n",
+               v1,e,v2,eprime,v1prime);
+      exit(-1);
+    }
+  }
+}
+
 int main(int argc, const char *const *argv) {
   static const int wantedevents= POLLIN|POLLPRI|POLLERR|POLLHUP;
 
@@ -585,6 +622,9 @@ int main(int argc, const char *const *argv) {
   int k, i, r, *xfds, nxfds, polls_alloc=0;
   struct pollfd *polls=0;
   int motion_deferred=0, motion_x=-1, motion_y=-1;
+
+  topocheck();
+  if (argc==1) { printf("topology self-consistent, ok\n"); exit(0); }
   
   if (argc != 2 || argv[1][0]=='-') {
     fputs("need filename\n",stderr); exit(8);