chiark / gitweb /
merge into history old stuff found on chiark
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 16 Mar 2014 23:52:04 +0000 (23:52 +0000)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 16 Mar 2014 23:52:04 +0000 (23:52 +0000)
22 files changed:
.cvsignore [new file with mode: 0644]
Makefile
Makefile.bak [deleted file]
dualx11.cc
dualx11.hh
graphics.cc
ins-new [new file with mode: 0644]
library.cc
library.hh
ll -tr [deleted file]
main.cc
moebius.cc
moebius.hh
output.hh
parameter.cc
parameter.hh
postscript.cc
postscript.hh
transforms.cc
transforms.hh
x11.cc
x11.hh

diff --git a/.cvsignore b/.cvsignore
new file mode 100644 (file)
index 0000000..cba7efc
--- /dev/null
@@ -0,0 +1 @@
+a.out
index 80111df5db09261104a43fd9076cd027afabb251..54e80614be1022ad5c5235b0f6fb3f070066e0f7 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,8 @@
-C++FLAGS= -Wall -O2
-CPPFLAGS= -I/usr/include
+CPPFLAGS= -I/usr/include \
+       -Wall -O2 -g -Wmissing-prototypes -Wstrict-prototypes \
+       -Wno-deprecated \
+       $(WERROR)
+WERROR=-Werror
 LDFLAGS= 
 LIBS= 
 
@@ -7,7 +10,7 @@ OBJS=  dualx11.o x11.o main.o parameter.o graphics.o library.o \
        transforms.o postscript.o moebius.o
 
 a.out: $(OBJS)
-       $(LINK.cc) -o a.out $(OBJS) -lm -L/usr/X11R6/lib -lX11 -lg++
+       $(LINK.cc) -o a.out $(OBJS) -lm -L/usr/X11R6/lib -lX11
 
 depend:
        $(C++) $(CPPFLAGS) -E -MM *.cc >.depend
diff --git a/Makefile.bak b/Makefile.bak
deleted file mode 100644 (file)
index ee52661..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-
-OBJS= main.o moebius.o output.o library.o
-
-a.out: $(OBJS)
-       g++ -o a.out $(OBJS)
-
index 4bfc39cba3edb3b7c39012a7eafd0bc9d6a6d670..6a2edd5a796aeaac6e8e6fe288b62ea39cd0a9dd 100644 (file)
@@ -5,6 +5,9 @@
 #include "dualx11.hh"
 #include "parameter.hh"
 
+static Parameter<int> dualx11size("dualx11size", "Dual X11 window size",
+                                 500, 100, 10, 10000);
+
 DualX11Output::DualX11Output() {
   display= XOpenDisplay(0);
   Colormap cmap= DefaultColormap(display,DefaultScreen(display));
@@ -26,9 +29,10 @@ DualX11Output::DualX11Output() {
   
   window= XCreateSimpleWindow(display,
                               DefaultRootWindow(display),
-                              0,0, 500,500, 0,0, pixelbase);
+                              0,0, dualx11size,dualx11size, 0,0, pixelbase);
 
   XGCValues gcvalues;
+  int i;
   for (i=0; i<2; i++) {
     gcvalues.plane_mask= planemasks[i];
     // First, the fabric
@@ -59,21 +63,36 @@ DualX11Output::~DualX11Output() {
   XCloseDisplay(display);
 }
 
-void DualX11Output::drawcell(const Point* list, int n) {
-  static Parameter<double> eyeseparation("eyesep",
-                                         "Distance from projection eye to origin", 
-                                         0.3, .1, 0., 100.);
+void DualX11Output::drawcell(const Point* list, int n, Colour colour) {
+  static Parameter<double>
+    eyeseparation("eyesep", "Distance from projection eye to origin", 
+                 0.3, .1, 0., 100.);
+
   for (int i=0; i<2; i++) {
+    GC fill;
+    bool draw;
+    
     Point::seteyex(eyeseparation*(i-0.5));
+
+    switch (colour) {
+    case grid:       fill= fabric[i]; draw= true;  break;
+    case solidblack: fill= fabric[i]; draw= false; break;
+    case solidwhite: fill= mesh[i];   draw= false; break;
+    default: abort();
+    }
+
     XPoint xp[n+1];
     for (int j=0; j<n; j++) {
       Onscreen here= Onscreen(list[j]);
-      xp[j].x= (int)((here.x+1.0)*250.0);
-      xp[j].y= (int)((-here.y+1.0)*250.0);
+      xp[j].x= (int)((here.x+1.0)*(dualx11size*0.5));
+      xp[j].y= (int)((-here.y+1.0)*(dualx11size*0.5));
+    }
+
+    XFillPolygon(display,window,fill,xp,n,Nonconvex,CoordModeOrigin);
+    if (draw) {
+      xp[n]= xp[0];
+      XDrawLines(display,window,mesh[i],xp,n+1,CoordModeOrigin);
     }
-    XFillPolygon(display,window,fabric[i],xp,n,Nonconvex,CoordModeOrigin);
-    xp[n]= xp[0];
-    XDrawLines(display,window,mesh[i],xp,n+1,CoordModeOrigin);
   }
   Point::seteyex(0);
 }
index 042bc1127b0adbcdfa2146460fbd3c11238491f7..b07358c1f4b68d30ab34d36a466a4920abd73f06 100644 (file)
@@ -1,5 +1,6 @@
 /*
- * X11 functions
+ * X11 functions - colour-stereographic output
+ * (currently broken)
  */
 
 #ifndef DUALX11_HH
@@ -13,7 +14,7 @@
 struct DualX11Output : Output {
   DualX11Output();
   ~DualX11Output();
-  void drawcell(const Point*, int);
+  void drawcell(const Point *list, int n, Colour colour);
   void startimage();
   void endimage();
 private:
index 5fdfb25d6ba434675d85dd0222736a8093d0344f..605d8834535925b2bcc85203e4b379b694fa357d 100644 (file)
@@ -12,6 +12,7 @@
 #include "library.hh"
 #include "graphics.hh"
 #include "output.hh"
+#include "parameter.hh"
 
 static int checkneededline(Onscreen a, Onscreen b) {
   double xd= a.x - b.x;
@@ -20,23 +21,42 @@ static int checkneededline(Onscreen a, Onscreen b) {
   return n>0 ? n : 1;
 }
 
+static Parameter<double>
+sotextpit("sotextpit", "Pitch of solid texture (0: grid mode)",
+         0., 1., 0., 1000.);
+
 void Cell::display(Output& o) {
   int nn[4];
   int totalnn= 0;
-  for (int i=0; i<4; i++) {
+  int i;
+  for (i=0; i<4; i++) {
     nn[i]= checkneededline(p[i],p[(i+1)&3]);
     totalnn+= nn[i];
   }
   Point *array= new Point[totalnn];
   Point *inarrayp= array;
+  Point mean(0,0,0);
   for (i=0; i<4; i++) {
     for (int a=0; a<nn[i]; a++) {
       double fp= (double)a         / nn[i];
       double fn= (double)(nn[i]-a) / nn[i];
       *inarrayp++= p[i]*fn + p[(i+1)&3]*fp;
     }
+    mean = mean + p[i];
+  }
+  mean = mean * 0.25;
+  Output::Colour colour= Output::grid;
+  if (sotextpit > 0) {
+    bool white= false;
+    for (i=0; i<3; i++) {
+      double intpartdummy;
+      double remainder= modf(mean[i] / sotextpit, &intpartdummy);
+      if (remainder >= 0.5 || (remainder >= -0.5 && remainder < 0.0))
+       white= !white;
+    }
+    colour= white ? Output::solidwhite : Output::solidblack;
   }
-  o.drawcell(array,totalnn);
+  o.drawcell(array,totalnn,colour);
   delete[] array;
 }                          
 
@@ -55,7 +75,8 @@ SortedCellList::Fragment* SortedCellList::insertfragment(int at) {
 
 void SortedCellList::insert(Cell *it) {
   double index= it->index();
-  for (int fragment= used-1;
+  int fragment;
+  for (fragment= used-1;
        fragment >= 0 && index < fragments[fragment]->entries[0].index;
        fragment--);
   if (fragment < 0) {
@@ -65,7 +86,8 @@ void SortedCellList::insert(Cell *it) {
     nf->entries[0].cell= it;
     return;
   }
-  for (int entry= 0;
+  int entry;
+  for (entry= 0;
        entry < fragments[fragment]->used &&
        index > fragments[fragment]->entries[entry].index;
        entry++);
diff --git a/ins-new b/ins-new
new file mode 100644 (file)
index 0000000..8712c59
--- /dev/null
+++ b/ins-new
@@ -0,0 +1,6 @@
+theta=0.5
+bulge=2
+sheary=0.8
+eta=-1
+twist=0.5
+tear=1
index 60f8446a97175b05975c08dfd5628f77635aec79..d15c454ca6103601f73a6e096e917dfbdc2acbf7 100644 (file)
@@ -3,6 +3,7 @@
  */
 
 #include <stdlib.h>
+#include <stdio.h>
 
 #include "library.hh"
 #include "transforms.hh"
index bb226dd31d2a9ba19404a64da4b09fc06aa221c1..e122a9d528d33dfaa87ff9ceb437d5b38206c14b 100644 (file)
@@ -57,6 +57,7 @@ public:
   double& operator[](int i) { return xyz[i]; }
 
   operator Onscreen() const;
+  Point halftransformed() const { return usertransforms(*this); }
   Point transformed() const { return povtransform(usertransforms(*this)); }
   double index() const { return transformed()[2]; }
 
diff --git a/ll -tr b/ll -tr
deleted file mode 100644 (file)
index 338407e..0000000
--- a/ll -tr
+++ /dev/null
@@ -1,29 +0,0 @@
-total 112
--rw-rw-r--  1 ian ian   82 Jul 17  1993 Makefile.bak
--rw-rw-r--  1 ian ian  317 Jul 17  1993 main.cc%
--rw-rw-r--  1 ian ian  645 Jul 17  1993 graphics.hh
--rw-rw-r--  1 ian ian 1988 Jul 18  1993 transforms.hh
--rw-rw-r--  1 ian ian   62 Jul 18  1993 ins
--rw-rw-r--  1 ian ian 2119 Jul 18  1993 transforms.cc
--rw-rw-r--  1 ian ian 1559 Jul 19  1993 moebius.hh
--rw-rw-r--  1 ian ian 2079 Jul 20  1993 moebius.cc
--rw-rw-r--  1 ian ian   31 Jul 20  1993 fit
--rw-rw-r--  1 ian ian  245 Sep 11  1993 output.hh
--rw-rw-r--  1 ian ian  337 Sep 11  1993 x11.hh
--rw-rw-r--  1 ian ian  302 Sep 11  1993 postscript.hh
--rw-rw-r--  1 ian ian 1104 Sep 11  1993 x11.cc
--rw-rw-r--  1 ian ian 3068 Sep 11  1993 graphics.cc
--rw-rw-r--  1 ian ian 1102 Sep 11  1993 postscript.cc
--rw-rw-r--  1 ian ian 1788 Sep 11  1993 library.hh
--rw-rw-r--  1 ian ian 1291 Sep 11  1993 library.cc
--rw-rw-r--  1 ian ian 5488 Sep 11  1993 main.cc
--rw-rw-r--  1 ian ian  405 Sep 11  1993 dualx11.hh
--rw-rw-r--  1 ian ian  553 Sep 11  1993 .depend
--rw-rw-r--  1 ian ian 1280 Sep 11  1993 parameter.hh
--rw-rw-r--  1 ian ian  526 Sep 11  1993 parameter.cc
--rw-rw-r--  1 ian ian 2299 Sep 11  1993 dualx11.cc
--rw-rw-r--  1 ian ian  338 Aug 31  1996 Makefile
-drwxrwsr-x 60 ian ian 4096 Nov 16 11:06 ../
-drwxrwsr-x  7 ian ian 4096 Mar 16 23:50 .git/
--rw-rw-r--  1 ian ian    0 Mar 16 23:50 ll -tr
-drwxrwsr-x  3 ian ian 4096 Mar 16 23:50 ./
diff --git a/main.cc b/main.cc
index 700719426255463c5ad67ebfada24e17ca8fec03..645d93a568db6c4df3907f622413631f9e62ca1b 100644 (file)
--- a/main.cc
+++ b/main.cc
 #include "graphics.hh"
 #include "parameter.hh"
 
-Parameter<int> tn("tn", "Number of sections around `strip'", 30, 1, 1, 500);
-Parameter<int> un("un", "Number of sections across `strip'", 15, 1, 1, 500);
-Parameter<double> theta("theta", "Angle of model rotation",
-                        /*-PI/2.*/0, PI/8., -PI*2., PI*2.);
-Parameter<double> eta("eta", "Angle of model elevation", 0., PI/8., -PI*2., PI*2.);
-Parameter<double> planedistance("plane", "Distance from projection plane to origin", 
-                                4., .25, 0., 100.);
-Parameter<double> eyedistance("eye", "Distance from projection eye to origin", 
-                              1.5, .25, 0., 100.);
-Parameter<double> cutoffdistance("cutoff", "Distance from projection cutoff to origin", 
-                                 10., .25, -10., 100.);
-Parameter<double> width("width", "Width of the `strip' before transformation", 
-                        .4, .1, 0., 1.);
-Parameter<double> thickness("thick", "Thickness of the `pancake'", 1., .1, 0., 1.);
-Parameter<double> bottomportion("bp", "Proportion in the bottom half", 
-                                .7, .1, 0., 1.);
-//Parameter<double> tear("tear", "Angle factor in tear-open", 0/*1.1*/, .1, -5., 5.);
-//Parameter<double> teary("teary", "Axis y coord in tear-open", 1.3, .1, -10., 10.);
-//Parameter<double> twist("twist", "Angle per length in twist", 0/*.8*/, .25, -5., 5.);
-//Parameter<double> twisty("twisty", "Axis y coord in twist", .85, .1, -10., 10.);
-//Parameter<double> bulge("bulge", "Amount of bulge", 0/*1.*/, .25, -15., 15.);
-//Parameter<double> bulgesd("bulgesd", "S.D. of bulge", 1., .2, .000001, 20.);
-//Parameter<double> bulgey("bulgey", "Axis y coord in bulge", .85, .1, -10., 10.);
-//Parameter<double> shearx("shearx", "Amount of shear (x)", 0., .1, -15., 15.);
-//Parameter<double> sheary("sheary", "Amount of shear (y)", 0/*1.*/, .1, -15., 15.);
-//Parameter<double> shearsdx("shearsdx", "S.D. of shear (x)", .5, .1, -15., 15.);
-//Parameter<double> shearsdy("shearsdy", "S.D. of shear (y)", .5, .1, -15., 15.);
-//Parameter<double> shearey("shearey", "Centre of shear (y)", 1.3, .1, -10., 10.);
+static Parameter<int>
+tn("tn", "Number of sections around `strip'", 30, 1, 1, 500);
+
+static Parameter<int>
+un("un", "Number of sections across `strip'", 15, 1, 1, 500);
+
+static Parameter<int>
+version("version", "Version to use: 0=original strip,"
+       " 1=reformulated, 2=reformulated again", 0, 1, 0, 2);
+
+static Parameter<double>
+theta("theta", "Angle of model rotation",
+      /*-PI/2.*/0, M_PI/8., -M_PI*2., M_PI*2.);
+
+static Parameter<double>
+eta("eta", "Angle of model elevation",
+    0., M_PI/8., -M_PI*2., M_PI*2.);
+
+static Parameter<double>
+scale("scale", "Scale factor for resulting object", 1.0, 0.25, 0.001, 1000.);
+
+static Parameter<double>
+planedistance("plane", "Distance from projection plane to origin", 
+             4., .25, 0., 100.);
+
+static Parameter<double>
+eyedistance("eye", "Distance from projection eye to origin", 
+           1.5, .25, 0., 100.);
+
+static Parameter<double>
+cutoffdistance("cutoff", "Distance from projection cutoff to origin", 
+              10., .25, -10., 100.);
+
+static Parameter<double>
+width("width", "Width of the `strip' before transformation", .4, .1, 0., 1.);
+
+static Parameter<double>
+thickness("thick", "Thickness of the `pancake'", 1., .1, 0., 1.);
+
+static Parameter<double>
+bottomportion("bp", "Proportion in the bottom half", .7, .1, 0., 1.);
+
+static Parameter<double>
+tear("tear", "Angle factor in tear-open", 0/*1.1*/, .1, -5., 5.);
+
+static Parameter<double>
+teary("teary", "Axis y coord in tear-open", 1.3, .1, -10., 10.);
+
+static Parameter<double>
+twist("twist", "Angle per length in twist", 0/*.8*/, .25, -5., 5.);
+
+static Parameter<double>
+twisty("twisty", "Axis y coord in twist", .85, .1, -10., 10.);
+
+static Parameter<double>
+bulge("bulge", "Amount of bulge", 0/*1.*/, .25, -15., 15.);
+
+static Parameter<double>
+bulgesd("bulgesd", "S.D. of bulge", 1., .2, .000001, 20.);
+
+static Parameter<double>
+bulgey("bulgey", "Axis y coord in bulge", .85, .1, -10., 10.);
+
+static Parameter<double>
+shearx("shearx", "Amount of shear (x)", 0., .1, -15., 15.);
+
+static Parameter<double>
+sheary("sheary", "Amount of shear (y)", 0/*1.*/, .1, -15., 15.);
+
+static Parameter<double>
+shearsdx("shearsdx", "S.D. of shear (x)", .5, .1, -15., 15.);
+
+static Parameter<double>
+shearsdy("shearsdy", "S.D. of shear (y)", .5, .1, -15., 15.);
+
+static Parameter<double>
+shearey("shearey", "Centre of shear (y)", 1.3, .1, -10., 10.);
+
 
 SortedCellList *list=0;
 X11Output *x11= 0;
 DualX11Output *dualx11= 0;
 
+static Moebius *strip= 0;
+
 void generate() {
   if (list) delete list;
-  // MoebiusStrip strip(width);
-  MoebiusEnfoldment strip(thickness,bottomportion);
+  if (strip) { delete strip; strip= 0; }
+  switch (version) {
+  case 0: strip= new MoebiusStrip(width);                           break;
+  case 1: strip= new MoebiusEnfoldment(thickness,bottomportion);    break;
+  case 2: strip= new MoebiusEnfoldmentNew();                        break;
+  default: abort();
+  }
   list= new SortedCellList;
   double t0= 0.0;
   for (int ti=0; ti<tn; ti++) {
@@ -64,12 +121,12 @@ void generate() {
       double u1= (double)(ui+1)/un;
       Cell *cell= new Cell;
 //u0=u1=tear;
-      cell->p[0]= strip.middlepoint(t0,u0);
+      cell->p[0]= strip->middlepoint(t0,u0);
 //fprintf(stderr,"t %7.4f u %7.4f  %7.4f,%7.4f,%7.4f\n",
 //        t0,u0, cell->p[0][0], cell->p[0][1], cell->p[0][2]);
-      cell->p[1]= strip.middlepoint(t0,u1);
-      cell->p[2]= strip.middlepoint(t1,u1);
-      cell->p[3]= strip.middlepoint(t1,u0);
+      cell->p[1]= strip->middlepoint(t0,u1);
+      cell->p[2]= strip->middlepoint(t1,u1);
+      cell->p[3]= strip->middlepoint(t1,u0);
       list->insert(cell);
       u0= u1;
     }
@@ -78,26 +135,29 @@ void generate() {
 }
 
 int main(int argc, char **argv) {
+  static const char pointmap_cmd[]= "pointmap ";
   char buf[100];
+  double pointmap_t, pointmap_u;
 
   for (;;) {
     Point::setobserver(theta,eta,planedistance,eyedistance,cutoffdistance);
     Point::cleartransform();
-//    if (tear != 0.0) Point::appendtransform(new TearOpenTransform(tear,teary));
-//    if (twist != 0.0) Point::appendtransform(new TwistTransform(twist,twisty));
-//    if (bulge != 0.0) Point::appendtransform(new BulgeTransform(bulge,bulgesd,bulgey));
-//    if (shearx != 0.0 || sheary != 0.0)
-//      Point::appendtransform(new ShearTransform(Point(0.0,shearey,0.0),
-//                                                Point(shearx,sheary,0.0),
-//                                                Point(shearsdx,shearsdy,1e20)));
+    if (tear != 0.0) Point::appendtransform(new TearOpenTransform(tear,teary));
+    if (twist != 0.0) Point::appendtransform(new TwistTransform(twist,twisty));
+    if (bulge != 0.0) Point::appendtransform(new BulgeTransform(bulge,bulgesd,bulgey));
+    if (shearx != 0.0 || sheary != 0.0)
+      Point::appendtransform(new ShearTransform(Point(0.0,shearey,0.0),
+                                                Point(shearx,sheary,0.0),
+                                                Point(shearsdx,shearsdy,1e20)));
+    Point::appendtransform(new ScaleTransform(scale));
     generate();
     if (x11) list->display(*x11);
     if (dualx11) list->display(*dualx11);
     for (;;) {
-      cin.get(buf,100,'\n');
-      char c;
-      if (!cin.get(c) || c!='\n') {
-        cerr << "error reading command input, giving up\n";
+      cerr << "> ";
+      cin.getline(buf,sizeof(buf),'\n');
+      if (!cin.good()) {
+       cerr << "error reading command input, giving up\n";
         exit(1);
       }
       char *equals= strchr(buf,'=');
@@ -140,7 +200,18 @@ int main(int argc, char **argv) {
       } else if (!strcmp(buf,"quit")) {
         exit(0);
       } else if (!strcmp(buf,"list")) {
+        AnyParameter::help();
+      } else if (!strcmp(buf,"help")) {
         AnyParameter::list();
+      } else if (!strncmp(buf,pointmap_cmd,sizeof(pointmap_cmd)-1)) {
+       if (sscanf(buf+sizeof(pointmap_cmd)-1, "%lf %lf",
+                  &pointmap_t, &pointmap_u) != 2) {
+         cerr << "failed to parse pointmap args\n";
+         continue;
+       }
+       Point p= strip->middlepoint(pointmap_t,pointmap_u);
+       cout << "\n";
+       for (int i=0; i<3; i++) cout << p.halftransformed()[i] << "\n";
       } else if (!*buf) {
         break;
       } else {
@@ -149,4 +220,3 @@ int main(int argc, char **argv) {
     }
   }
 }
-
index d68f4aff8174426088f4f7c9972a60268ac4fecf..f169ab52520866f81c40703ce1c87dab3255504d 100644 (file)
@@ -9,7 +9,7 @@
 #include "moebius.hh"
 
 Point MoebiusStrip::edgepoint(double t) {
-  double theta= (t-0.5)*4.0*PI;
+  double theta= (t-0.5)*4.0*M_PI;
   double r= 1.0 - halfgap*(1.0 - sin(theta/2.0));
   return Point(r*sin(theta),
                -r*cos(theta),
@@ -46,8 +46,8 @@ void Bezier::debug() {
 // The first end is oriented towards [0,cos(theta),sin(theta)]
 // The second end is oriented towards [0,-1,0]
 
-Point MoebiusEnfoldment::edgepoint(double t) {
-  double theta= t*2.0*PI;
+Point MoebiusEnfoldmentAny::edgepoint(double t) {
+  double theta= t*2.0*M_PI;
   return Point(sin(theta),cos(theta),0);
 }
 
@@ -58,13 +58,13 @@ Point MoebiusEnfoldment::middlepoint(double t, double u) {
     double sizehere= sqrt(1-t*t);
     return Point((u*2.0-1.0) * sizehere,
                  t,
-                 sizehere * thickness * sin(u*2.0*PI));
+                 sizehere * thickness * sin(u*2.0*M_PI));
   } else {
     t /= bottomportion;
-    double theta= (.5-u)*2*PI;
-    Bezier bx(sin(theta*.5), -theta/PI, 0, 0);
+    double theta= (.5-u)*2*M_PI;
+    Bezier bx(sin(theta*.5), -theta/M_PI, 0, 0);
     double ypushiness= (1-cos(theta))*2.5+1;
-//        double fudge= (PI*sin(theta*.5)*cos(theta*.5))*(.5-u)*(.5-u)*4;
+//        double fudge= (M_PI*sin(theta*.5)*cos(theta*.5))*(.5-u)*(.5-u)*4;
     double fudge= (.5-u)*(.5-u)*4*cos(theta*.5);
     Bezier by(-cos(theta*.5), 0,
               cos(theta)*ypushiness + fudge*ypushiness,
@@ -74,3 +74,37 @@ Point MoebiusEnfoldment::middlepoint(double t, double u) {
     return Point( bx(t), by(t), thickness * bz(t) );
   }
 }    
+
+Point MoebiusEnfoldmentNew::middlepoint(double t, double u) {
+  if (u <= 0.5) {
+    if (t <= 0.5) {
+      double sin_pi_t= sin(M_PI*t);
+      double cos_pi_t= cos(M_PI*t);
+      double sin_2pi_t= sin(2.0*M_PI*t);
+      double cos_2pi_t= cos(2.0*M_PI*t);
+
+      double prop_circ= 0.5+0.5*cos(2.0*M_PI*u);
+      //      double prop_circ= 1.0-2.0*u;
+
+      Point p_edge(-sin_pi_t,cos_pi_t,0);
+
+      double alpha_circ= (2.0*M_PI)*(2.0*t)*(2.0*u);
+      Point v_edge1(cos_2pi_t*sin_pi_t,-cos_2pi_t*cos_pi_t,sin_2pi_t);
+      Point v_edge2(sin_2pi_t*cos_pi_t,-sin_2pi_t*sin_pi_t,-cos_2pi_t);
+      Point p_circ_cent= p_edge + v_edge2*(2.0*t);
+      Point p_circ_pt= p_circ_cent + (v_edge1*sin(alpha_circ) + v_edge2*-cos(alpha_circ))*(2.0*t);
+      p_circ_pt[1]= p_edge[1];
+
+      Point v_line(-cos_pi_t,0,sin_pi_t);
+      Point p_line_start(0,1.0-2.0*t,0);
+      Point p_line_pt= p_line_start + v_line*(1.0-2.0*u)*(M_PI*t);
+
+      return p_circ_pt*prop_circ + p_line_pt*(1.0-prop_circ);
+    } else {
+      return middlepoint(0.5,u) + Point(0,0.5-t,0);
+    }
+  } else {
+    Point p_mirror= middlepoint(t,1.0-u);
+    return Point(-p_mirror[0], p_mirror[1], -p_mirror[2]);
+  }
+}
index e834d3b4397b148b9fb6a6d0a9de8bbf63cdd98a..f3e04390277b214c1bbe68ea3dbb2dcd2b9f4ad3 100644 (file)
@@ -43,13 +43,22 @@ public:
   Point middlepoint(double t, double u);
 };
 
-class MoebiusEnfoldment : public Moebius {
+class MoebiusEnfoldmentAny : public Moebius {
+public:
+  Point edgepoint(double t);
+};
+
+class MoebiusEnfoldment : public MoebiusEnfoldmentAny {
   double thickness;
   double bottomportion;
 public:
   MoebiusEnfoldment(double t=.35, double bp=.5) { thickness= t; bottomportion= bp; }
-    
-  Point edgepoint(double t);
+  Point middlepoint(double t, double u);
+};
+
+class MoebiusEnfoldmentNew : public MoebiusEnfoldmentAny {
+public:
+  MoebiusEnfoldmentNew() { }
   Point middlepoint(double t, double u);
 };
 
index 92cc33bf9e90e2c7c2cadbfa9ce6e50d1f354f78..4b40747f6046bcd7975dd52ee3e136f840eec44e 100644 (file)
--- a/output.hh
+++ b/output.hh
@@ -9,7 +9,8 @@
 
 struct Output {
   virtual ~Output(){};
-  virtual void drawcell(const Point*, int) =0;
+  enum Colour { grid, solidblack, solidwhite };
+  virtual void drawcell(const Point *list, int n, Colour colour) =0;
   virtual void startimage(){};
   virtual void endimage(){};
 };
index 0eb6df6c355fc9c068095ca3e9f2e012366f1c30..cc8b17516dbb6e18324407ca85335c64788ca803 100644 (file)
@@ -11,17 +11,33 @@ AnyParameter::AnyParameter(const char *n, const char *d) {
 }
 
 AnyParameter* AnyParameter::find(const char *n) {
-  for (AnyParameter* search= first;
+  AnyParameter* search;
+  for (search= first;
        search && strcmp(search->name,n);
        search= search->next);
   return search;
 }
 
+void AnyParameter::printvalue(void) {
+  cerr << name << " ";
+  rangecheckprint();
+}
+
 void AnyParameter::list() {
   for (AnyParameter* search= first;
        search;
-       search= search->next)
-    search->rangecheck();
+       search= search->next) {
+    cerr << search->description << ": ";
+    search->printvalue();
+  }
+}
+
+void AnyParameter::help() {
+  for (AnyParameter* search= first;
+       search;
+       search= search->next) {
+    search->printvalue();
+  }
 }
 
 AnyParameter* AnyParameter::first= 0;
index 07b0137c0f6c3128732d33d40ace520ea2a13fe7..b426e3746560af8aea0390c40008596a57ee6654 100644 (file)
@@ -13,7 +13,8 @@ class AnyParameter {
 protected:
   const char *name;
   const char *description;
-  virtual void rangecheck() =0;
+  void printvalue();
+  virtual void rangecheckprint() =0;
 public:
   AnyParameter(const char *n, const char *d);
   virtual void operator ++() =0;
@@ -21,17 +22,18 @@ public:
   virtual void operator =(double) =0;
   static AnyParameter *find(const char *n);
   static void list();
+  static void help();
 };
 
 template<class T> class Parameter : AnyParameter {
   T value, delta, min, max;
-  void rangecheck();
+  void rangecheckprint();
 public:
   Parameter(const char *n, const char *d, T i, T de, T mi, T ma);
   operator T (){ return value; }
-  void operator ++(){ value+= delta; rangecheck(); }
-  void operator --(){ value-= delta; rangecheck(); }
-  void operator =(double v) { value= (T)v; rangecheck(); }
+  void operator ++(){ value+= delta; rangecheckprint(); }
+  void operator --(){ value-= delta; rangecheckprint(); }
+  void operator =(double v) { value= (T)v; rangecheckprint(); }
 };
 
 template<class T> Parameter<T>::Parameter
@@ -40,8 +42,7 @@ template<class T> Parameter<T>::Parameter
   value=i; delta=de; min=mi; max=ma;
 }
 
-template<class T> void Parameter<T>::rangecheck() {
-  cerr << name << " ";
+template<class T> void Parameter<T>::rangecheckprint() {
   if (value<min) {
     value= min;  cerr << "underflowed; ";
   } else if (value>max) {
index 3fbe4e7585179e73e18c39bc4ad16b519d5b0a34..f27a08138160fc6e32d96d7d47a9a3135993980a 100644 (file)
@@ -29,11 +29,23 @@ PostScriptOutput::~PostScriptOutput() {
     "%%EOF\n";
 }
 
-void PostScriptOutput::drawcell(const Point* list, int n) {
-  Onscreen p[4];
-  for (int i=0; i<4; i++) p[i]= Onscreen(list[i]);
-  docell(p,n,"1 setgray fill");
-  docell(p,n,"0 setgray stroke");
+void PostScriptOutput::drawcell(const Point* list, int n, Colour colour) {
+  Onscreen p[n];
+  for (int i=0; i<n; i++) p[i]= Onscreen(list[i]);
+  switch (colour) {
+  case grid:
+    docell(p,n,"1 setgray fill");
+    docell(p,n,"0 setgray stroke");
+    break;
+  case solidwhite:
+    docell(p,n,"1 setgray fill");
+    break;
+  case solidblack:
+    docell(p,n,"0 setgray fill");
+    break;
+  default:
+    abort();
+  }
 }
 
 void PostScriptOutput::docell(const Onscreen* list, int n, const char *what) {
index d385513f1fa238b44362e9d96e0e6856d5a63d4b..e7d311ab3449c88e458188d57ba7afac013944c4 100644 (file)
@@ -9,7 +9,7 @@
 struct PostScriptOutput : Output {
   PostScriptOutput(ofstream&);
   ~PostScriptOutput();
-  void drawcell(const Point*, int);
+  void drawcell(const Point *list, int n, Colour colour);
 private:
   ofstream& file;
   void docell(const Onscreen*, int, const char* what);
index d5b6cd6bb230a8782057cbf0fae84110b5446578..abd3fce3bb8bbf338021df6962f8919a24f7c1bf 100644 (file)
@@ -68,6 +68,10 @@ Point TwistTransform::operator()(Point in) {
   return Point(nx,ny,in[2]);
 }
 
+Point ScaleTransform::operator()(Point in) {
+  return in*scale;
+}
+
 Point MagicTransform::operator()(Point in) {
   double nz= in[2]*zfactor;
   double r= sqrt(in[0]*in[0] + in[1]*in[1]);
index e398d279b96d96a3dd89d96d3688cbc9146f8916..bb7c3ce0bec01ab8396bc2e46c58a05e23c089b5 100644 (file)
@@ -78,6 +78,13 @@ public:
   Point operator()(Point in);
 };
 
+class ScaleTransform : public Transform {
+  double scale;
+public:
+  ScaleTransform(double s) { scale= s; }
+  Point operator()(Point in);
+};
+
 class MagicTransform : public Transform {
   double xkonstant, xfactor, yoffset, yfactor, zfactor;
 public:
diff --git a/x11.cc b/x11.cc
index b724594e676253fef6a5bb80082704495b67838a..c8eb915cac381c706762b10167080273670c997c 100644 (file)
--- a/x11.cc
+++ b/x11.cc
@@ -4,18 +4,37 @@
 
 
 #include "x11.hh"
+#include "parameter.hh"
 
-X11Output::X11Output() {
+static Parameter<int> x11size("x11size", "X11 window size", 500, 100, 10, 10000);
+
+GC X11Output::gc(const char *colour_name) {
   XGCValues gcvalues;
+  XColor colour;
+  Status st;
+
+  st= XAllocNamedColor(display,cmap,colour_name,&colour,&colour);
+  if (!st) {
+    cerr << "cannot allocate colour " << colour_name << ", quitting\n";
+    exit(1);
+  }
+
+  gcvalues.foreground= gcvalues.background= colour.pixel;
+  return XCreateGC(display,window,GCForeground|GCBackground,&gcvalues);
+}
+
+X11Output::X11Output() {
   display= XOpenDisplay(0);
   window= XCreateSimpleWindow(display,
                               DefaultRootWindow(display),
-                              0,0, 500,500, 0,0,0);
-  gcvalues.background= 0;
-  fabric= XCreateGC(display,window,GCBackground,&gcvalues);
-  gcvalues.foreground= 1;
-  gcvalues.background= 1;
-  mesh= XCreateGC(display,window,GCForeground|GCBackground,&gcvalues);
+                              0,0, x11size,x11size, 0,0,0);
+  cmap= DefaultColormap(display,DefaultScreen(display));
+
+  black= gc("black");
+  white= gc("white");
+  blue= gc("blue");
+  red= gc("red");
+
   XSelectInput(display,window,0);
   XMapWindow(display,window);
   XFlush(display);
@@ -33,14 +52,24 @@ X11Output::~X11Output() {
   XCloseDisplay(display);
 }
 
-void X11Output::drawcell(const Point* list, int n) {
+void X11Output::drawcell(const Point* list, int n, Colour colour) {
+  GC fill, draw;
+  
   XPoint xp[n+1];
   for (int i=0; i<n; i++) {
     Onscreen here= Onscreen(list[i]);
-    xp[i].x= (int)((here.x+1.0)*250.0);
-    xp[i].y= (int)((-here.y+1.0)*250.0);
+    xp[i].x= (int)((here.x+1.0)*(x11size*0.5));
+    xp[i].y= (int)((-here.y+1.0)*(x11size*0.5));
+  }
+  switch (colour) {
+  case grid:       fill= black;  draw= white;  break;
+  case solidblack: fill= red;    draw= 0;      break;
+  case solidwhite: fill= blue;   draw= 0;      break;
+  default: abort();
+  }
+  XFillPolygon(display,window,fill,xp,n,Nonconvex,CoordModeOrigin);
+  if (draw) {
+    xp[n]= xp[0];
+    XDrawLines(display,window,draw,xp,n+1,CoordModeOrigin);
   }
-  XFillPolygon(display,window,fabric,xp,n,Nonconvex,CoordModeOrigin);
-  xp[n]= xp[0];
-  XDrawLines(display,window,mesh,xp,n+1,CoordModeOrigin);
 }
diff --git a/x11.hh b/x11.hh
index d7117414faac00b8c1e02e40af7b6537638c5472..babcfc384efb3e21393f92fcd36e3375c7d23fd3 100644 (file)
--- a/x11.hh
+++ b/x11.hh
 struct X11Output : Output {
   X11Output();
   ~X11Output();
-  void drawcell(const Point*, int);
+  void drawcell(const Point*, int, Colour);
   void startimage();
   void endimage();
 private:
   Display *display;
   Window window;
-  GC fabric;
-  GC mesh;
+  Colormap cmap;
+  GC black, white, red, blue;
+  GC gc(const char *colour_name);
 };
 
 #endif