-CXXFLAGS= -g -Wall -O2
-CPPFLAGS= -I/usr/include
+CPPFLAGS= -I/usr/include \
+ -Wall -O2 -g -Wmissing-prototypes -Wstrict-prototypes \
+ -Wno-deprecated \
+ $(WERROR)
+WERROR=-Werror
LDFLAGS=
LIBS=
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
+++ /dev/null
-
-OBJS= main.o moebius.o output.o library.o
-
-a.out: $(OBJS)
- g++ -o a.out $(OBJS)
-
+++ /dev/null
-CXXFLAGS= -g -Wall -O2
-CPPFLAGS= -I/usr/include
-LDFLAGS=
-LIBS=
-
-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++
-
-depend:
- $(C++) $(CPPFLAGS) -E -MM *.cc >.depend
-
-clean:
- rm -f $(OBJS) a.out
-
-include .depend
+++ /dev/null
-Aladdin Ghostscript 3.33 (4/10/1995)
-Copyright (C) 1995 Aladdin Enterprises, Menlo Park, CA. All rights reserved.
-This software comes with NO WARRANTY: see the file COPYING for details.
-GS>
\ No newline at end of file
#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));
window= XCreateSimpleWindow(display,
DefaultRootWindow(display),
- 0,0, 500,500, 0,0, pixelbase);
+ 0,0, dualx11size,dualx11size, 0,0, pixelbase);
XGCValues gcvalues;
- for (int i=0; i<2; i++) {
+ int i;
+ for (i=0; i<2; i++) {
gcvalues.plane_mask= planemasks[i];
// First, the fabric
gcvalues.function= GXclear;
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);
}
+++ /dev/null
-/*
- * X11 functions
- */
-
-#include "dualx11.hh"
-#include "parameter.hh"
-
-DualX11Output::DualX11Output() {
- display= XOpenDisplay(0);
- Colormap cmap= DefaultColormap(display,DefaultScreen(display));
-
- XAllocColorCells(display,cmap,
- False, // contig
- planemasks,
- 2, // nplanes
- &pixelbase,
- 1); // ncolors
- XColor colours[4], *cp= colours;
- for (int i=0; i<2; i++)
- for (int j=0; j<2; j++, cp++) {
- cp->pixel= pixelbase + (i? planemasks[0] :0) + (j? planemasks[1] :0);
- cp->red= i?65535:0; cp->green= j?/*65535*/32000:0; cp->blue= 0;
- cp->flags= DoRed|DoGreen|DoBlue;
- }
- XStoreColors(display,cmap,colours,4);
-
- window= XCreateSimpleWindow(display,
- DefaultRootWindow(display),
- 0,0, 500,500, 0,0, pixelbase);
-
- XGCValues gcvalues;
- for (i=0; i<2; i++) {
- gcvalues.plane_mask= planemasks[i];
- // First, the fabric
- gcvalues.function= GXclear;
- fabric[i]= XCreateGC(display,window,
- GCFunction|GCPlaneMask,
- &gcvalues);
- // Then, the mesh
- gcvalues.function= GXset;
- mesh[i]= XCreateGC(display,window,
- GCFunction|GCPlaneMask,
- &gcvalues);
- }
- XSelectInput(display,window,0);
- XMapWindow(display,window);
- XFlush(display);
-}
-
-void DualX11Output::startimage() {
- XClearWindow(display,window);
-}
-
-void DualX11Output::endimage() {
- XFlush(display);
-}
-
-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.);
- for (int i=0; i<2; i++) {
- Point::seteyex(eyeseparation*(i-0.5));
- 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);
- }
- 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);
-}
/*
- * X11 functions
+ * X11 functions - colour-stereographic output
+ * (currently broken)
*/
#ifndef DUALX11_HH
struct DualX11Output : Output {
DualX11Output();
~DualX11Output();
- void drawcell(const Point*, int);
+ void drawcell(const Point *list, int n, Colour colour);
void startimage();
void endimage();
private:
#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;
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;
- for (int i=0; i<4; i++) {
+ 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;
}
+++ /dev/null
-/*
- * Graphics library
- */
-
-#include <iostream.h>
-
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h>
-
-#include "library.hh"
-#include "graphics.hh"
-#include "output.hh"
-
-static int checkneededline(Onscreen a, Onscreen b) {
- double xd= a.x - b.x;
- double yd= a.y - b.y;
- int n= (int)ceil(sqrt(xd*xd+yd*yd)*100.0);
- return n>0 ? n : 1;
-}
-
-void Cell::display(Output& o) {
- int nn[4];
- int totalnn= 0;
- for (int 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;
- 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;
- }
- }
- o.drawcell(array,totalnn);
- delete[] array;
-}
-
-SortedCellList::Fragment* SortedCellList::insertfragment(int at) {
- if (used==size) {
- size+=5; size<<=1;
- fragments= (Fragment**)realloc(fragments,sizeof(Fragment*)*size);
- if (!fragments) { perror("realloc"); exit(1); }
- }
- memmove(fragments+at+1, fragments+at, sizeof(Fragment*)*(used-at));
- used++;
- Fragment *nf= new Fragment;
- fragments[at]= nf;
- return nf;
-}
-
-void SortedCellList::insert(Cell *it) {
- double index= it->index();
- for (int fragment= used-1;
- fragment >= 0 && index < fragments[fragment]->entries[0].index;
- fragment--);
- if (fragment < 0) {
- Fragment *nf= insertfragment(0);
- nf->used= 1;
- nf->entries[0].index= index;
- nf->entries[0].cell= it;
- return;
- }
- for (int entry= 0;
- entry < fragments[fragment]->used &&
- index > fragments[fragment]->entries[entry].index;
- entry++);
- if (fragments[fragment]->used >= fragmentsize) {
- Fragment *nf= insertfragment(fragment+1);
- nf->used= fragmentsize>>1;
- fragments[fragment]->used -= nf->used;
- memcpy(nf->entries,
- fragments[fragment]->entries + fragments[fragment]->used,
- nf->used*sizeof(Entry));
- if (entry >= fragments[fragment]->used) {
- entry-= fragments[fragment]->used;
- fragment++;
- }
- }
- memmove(fragments[fragment]->entries + entry+1,
- fragments[fragment]->entries + entry,
- sizeof(Entry) * (fragments[fragment]->used - entry));
- fragments[fragment]->entries[entry].index= index;
- fragments[fragment]->entries[entry].cell= it;
- fragments[fragment]->used++;
-}
-
-SortedCellList::~SortedCellList() {
- for (int fragment=0; fragment<used; fragment++) {
- for (int entry=0; entry<fragments[fragment]->used; entry++) {
- delete fragments[fragment]->entries[entry].cell;
- }
- delete fragments[fragment];
- }
- free(fragments);
-}
-
-void SortedCellList::display(Output& o) {
- o.startimage();
- for (int fragment=0; fragment<used; fragment++) {
- for (int entry=0; entry<fragments[fragment]->used; entry++) {
- if (Point::indexvisible(fragments[fragment]->entries[entry].index)) {
- fragments[fragment]->entries[entry].cell->display(o);
- }
- }
- }
- o.endimage();
-}
--- /dev/null
+theta=0.5
+bulge=2
+sheary=0.8
+eta=-1
+twist=0.5
+tear=1
* Points library
*/
-#include <stdio.h>
#include <stdlib.h>
+#include <stdio.h>
#include "library.hh"
#include "transforms.hh"
return Onscreen(it[0] * factor + eyex * (1.0-factor), it[1] * factor);
}
-const char *Point::printing() {
- const int nbuf= 20;
- static int cbuf= 0;
- static char buf[nbuf][300];
- cbuf++; cbuf%=nbuf;
- sprintf(buf[cbuf],"(%g, %g, %g)",xyz[0],xyz[1],xyz[2]);
- return buf[cbuf];
-}
-
void Point::setobserver(double theta, double eta, double planedist, double eyedist,
double cutoffdist) {
planedistance= planedist;
+++ /dev/null
-/*
- * Points library
- */
-
-#include <stdlib.h>
-
-#include "library.hh"
-#include "transforms.hh"
-
-double Point::planedistance= 1.0;
-double Point::eyedistance= 1.0;
-double Point::cutoffdistance= 10.0;
-double Point::eyex= 0.0;
-
-TransformList Point::usertransforms;
-TransformList Point::povtransform;
-
-Point TransformList::operator()(Point it) {
- for (int i=0; i<used; i++) { it= (*a[i])(it); }
- return it;
-}
-
-void TransformList::append(Transform *it) {
- if (used >= size) {
- size+=5; size<<=1;
- a= (Transform**)realloc(a,sizeof(Transform*)*size);
- if (!a) { perror("realloc"); exit(1); }
- }
- a[used++]= it;
-}
-
-void TransformList::clearcontents() {
- for (int i=0; i<used; i++) delete a[i];
-}
-
-Point::operator Onscreen() const {
- Point it= transformed();
- double factor= eyedistance / (eyedistance + planedistance - it[2]);
- return Onscreen(it[0] * factor + eyex * (1.0-factor), it[1] * factor);
-}
-
-void Point::setobserver(double theta, double eta, double planedist, double eyedist,
- double cutoffdist) {
- planedistance= planedist;
- eyedistance= eyedist;
- cutoffdistance= cutoffdist;
- povtransform.reset();
- if (theta != 0.0) povtransform.append(new XZRotationTransform(theta));
- if (eta != 0.0) povtransform.append(new YZRotationTransform(eta));
-}
#define POINTS_HH
#include <stdlib.h>
-#include <math.h>
/*
* Coordinate system:
Point(){}
Point(double x, double y, double z) { xyz[0]=x; xyz[1]=y; xyz[2]=z; }
Point operator+(Point r) { return Point(xyz[0]+r[0], xyz[1]+r[1], xyz[2]+r[2]); }
- Point operator-(Point r) { return Point(xyz[0]-r[0], xyz[1]-r[1], xyz[2]-r[2]); }
Point operator*(double f) { return Point(xyz[0]*f, xyz[1]*f, xyz[2]*f); }
double& operator[](int i) { return xyz[i]; }
- double magnitude() { return sqrt(xyz[0]*xyz[0]+xyz[1]*xyz[1]+xyz[2]*xyz[2]); }
- const char *printing();
operator Onscreen() const;
+ Point halftransformed() const { return usertransforms(*this); }
Point transformed() const { return povtransform(usertransforms(*this)); }
double index() const { return transformed()[2]; }
+++ /dev/null
-/*
- * Points library
- */
-
-#ifndef POINTS_HH
-#define POINTS_HH
-
-#include <stdlib.h>
-#include <math.h>
-
-/*
- * Coordinate system:
- *
- * Y |
- * |
- * |
- * /-------- X
- * /
- * /
- * Z (coming out of the monitor)
- */
-
-struct Onscreen {
- double x, y;
- Onscreen(){};
- Onscreen(double ix, double iy) { x=ix; y=iy; }
-};
-
-class Point;
-
-class Transform {
-public:
- virtual Point operator()(Point)= 0;
-};
-
-class TransformList {
- Transform **a;
- int size,used;
- void clearcontents();
- public:
- TransformList() { size=used=0; a=0; }
- ~TransformList() { clearcontents(); free(a); }
- void reset() { clearcontents(); used=0; }
- Point operator()(Point);
- void append(Transform*);
-};
-
-class Point {
- static TransformList usertransforms;
- static TransformList povtransform;
- static double planedistance, eyedistance, cutoffdistance, eyex;
- double xyz[3];
-public:
- Point(){}
- Point(double x, double y, double z) { xyz[0]=x; xyz[1]=y; xyz[2]=z; }
- Point operator+(Point r) { return Point(xyz[0]+r[0], xyz[1]+r[1], xyz[2]+r[2]); }
- Point operator-(Point r) { return Point(xyz[0]-r[0], xyz[1]-r[1], xyz[2]-r[2]); }
- Point operator*(double f) { return Point(xyz[0]*f, xyz[1]*f, xyz[2]*f); }
- double& operator[](int i) { return xyz[i]; }
- double magnitude() { return sqrt(xyz[0]*xyz[0]+xyz[1]*xyz[1]+xyz[2]*xyz[2]); }
-
- operator Onscreen() const;
- Point transformed() const { return povtransform(usertransforms(*this)); }
- double index() const { return transformed()[2]; }
-
- static int indexvisible(double index) { return index < cutoffdistance; }
- static void appendtransform(Transform *t) { usertransforms.append(t); }
- static void cleartransform() { usertransforms.reset(); }
- static void setobserver(double theta, double eta=0.0,
- double planedist=1.0, double eyedist=1.0,
- double cutoff=10.0);
- static void seteyex(double n) { eyex=n; }
-};
-
-#endif
+++ /dev/null
-total 168
--rw-rw-r-- 1 ijackson ijackson 553 Sep 11 1993 .depend
--rw-rw-r-- 1 ijackson ijackson 337 Jan 24 1997 x11.hh
--rw-rw-r-- 1 ijackson ijackson 1104 Jan 24 1997 x11.cc~
--rw-rw-r-- 1 ijackson ijackson 1988 Jan 24 1997 transforms.hh
--rw-rw-r-- 1 ijackson ijackson 2119 Jan 24 1997 transforms.cc
--rw-rw-r-- 1 ijackson ijackson 302 Jan 24 1997 postscript.hh
--rw-rw-r-- 1 ijackson ijackson 1280 Jan 24 1997 parameter.hh
--rw-rw-r-- 1 ijackson ijackson 526 Jan 24 1997 parameter.cc~
--rw-rw-r-- 1 ijackson ijackson 245 Jan 24 1997 output.hh
--rw-rw-r-- 1 ijackson ijackson 1559 Jan 24 1997 moebius.hh~
--rw-rw-r-- 1 ijackson ijackson 317 Jan 24 1997 main.cc%
--rw-rw-r-- 1 ijackson ijackson 1291 Jan 24 1997 library.cc~
--rw-rw-r-- 1 ijackson ijackson 62 Jan 24 1997 ins
--rw-rw-r-- 1 ijackson ijackson 645 Jan 24 1997 graphics.hh
--rw-rw-r-- 1 ijackson ijackson 3068 Jan 24 1997 graphics.cc~
--rw-rw-r-- 1 ijackson ijackson 31 Jan 24 1997 fit
--rw-rw-r-- 1 ijackson ijackson 405 Jan 24 1997 dualx11.hh
--rw-rw-r-- 1 ijackson ijackson 2299 Jan 24 1997 dualx11.cc~
--rw-rw-r-- 1 ijackson ijackson 82 Jan 24 1997 Makefile.bak
--rw-rw-r-- 1 ijackson ijackson 5519 Jan 24 1997 main.cc~
--rw-rw-r-- 1 ijackson ijackson 341 Jan 24 1997 Makefile~
--rw-rw-r-- 1 ijackson ijackson 190 Jan 24 1997 bmp
--rw-rw-r-- 1 ijackson ijackson 1123 Jan 24 1997 postscript.cc
--rw-rw-r-- 1 ijackson ijackson 2079 Jan 27 1997 moebius.cc.original
--rw-rw-r-- 1 ijackson ijackson 536 Jan 27 1997 parameter.cc
--rw-rw-r-- 1 ijackson ijackson 3093 Jan 27 1997 graphics.cc
--rw-rw-r-- 1 ijackson ijackson 2303 Jan 27 1997 dualx11.cc
--rw-rw-r-- 1 ijackson ijackson 1582 Jan 27 1997 moebius.hh
--rw-rw-r-- 1 ijackson ijackson 1971 Jan 27 1997 library.hh~
--rw-rw-r-- 1 ijackson ijackson 5508 Jan 27 1997 main.cc
--rw-rw-r-- 1 ijackson ijackson 1105 Jan 27 1997 x11.cc
--rw-rw-r-- 1 ijackson ijackson 4081 Jan 27 1997 moebius.cc~
--rw-rw-r-- 1 ijackson ijackson 1997 Jan 28 1997 library.hh
--rw-rw-r-- 1 ijackson ijackson 1519 Jan 28 1997 library.cc
--rw-rw-r-- 1 ijackson ijackson 341 Jan 28 1997 Makefile
--rw-rw-r-- 1 ijackson ijackson 5060 Jan 28 1997 moebius.cc
-drwxrwsr-x 56 ijackson ijackson 4096 Mar 16 23:41 ../
-drwxrwsr-x 7 ijackson ijackson 4096 Mar 16 23:49 .git/
--rw-rw-r-- 1 ijackson ijackson 0 Mar 16 23:49 ll -tr
-drwxrwsr-x 3 ijackson ijackson 4096 Mar 16 23:49 ./
#include "graphics.hh"
#include "parameter.hh"
-template class Parameter<int>;
-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);
- MoebiusNewEnfoldment strip;
+ 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++) {
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;
}
}
}
-int main(int, char**) {
+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.good() || !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,'=');
} 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 {
}
}
}
-
+++ /dev/null
-/*
- * Moebius main program.
- */
-
-#include <math.h>
-#include <iostream.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "output.hh"
-#include "x11.hh"
-#include "dualx11.hh"
-#include "postscript.hh"
-#include "library.hh"
-#include "moebius.hh"
-#include "transforms.hh"
-#include "graphics.hh"
-#include "parameter.hh"
-
-template class Parameter<int>;
-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.);
-
-SortedCellList *list=0;
-X11Output *x11= 0;
-DualX11Output *dualx11= 0;
-
-void generate() {
- if (list) delete list;
- // MoebiusStrip strip(width);
- MoebiusEnfoldment strip(thickness,bottomportion);
- list= new SortedCellList;
- double t0= 0.0;
- for (int ti=0; ti<tn; ti++) {
- double t1= (double)(ti+1)/tn;
- double u0= 0.0;
- for (int ui=0; ui<un; ui++) {
- double u1= (double)(ui+1)/un;
- Cell *cell= new Cell;
-//u0=u1=tear;
- 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);
- list->insert(cell);
- u0= u1;
- }
- t0= t1;
- }
-}
-
-int main(int argc, char **argv) {
- char buf[100];
-
- 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)));
- 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";
- exit(1);
- }
- char *equals= strchr(buf,'=');
- if (equals) {
- *equals++= 0;
- AnyParameter *param= AnyParameter::find(buf);
- if (param) {
- *param= atof(equals);
- break;
- } else {
- cerr << "parameter `" << buf << "' not found\n";
- }
- } else if (!strncmp(buf,"postscript ",11)) {
- const char *filename= buf+11;
- ofstream file(filename);
- if (file) {
- PostScriptOutput psout(file);
- list->display(psout);
- } else {
- cerr << "Failed to open `" << filename << "'\n";
- continue;
- }
- cerr << "PostScript written to `" << filename <<"'\n";
- } else if (!strcmp(buf,"x11")) {
- if (x11) {
- delete x11;
- x11= 0;
- } else {
- x11= new X11Output;
- }
- break;
- } else if (!strcmp(buf,"dualx11")) {
- if (dualx11) {
- delete dualx11;
- dualx11= 0;
- } else {
- dualx11= new DualX11Output;
- }
- break;
- } else if (!strcmp(buf,"quit")) {
- exit(0);
- } else if (!strcmp(buf,"list")) {
- AnyParameter::list();
- } else if (!*buf) {
- break;
- } else {
- cerr << "command not understood\n";
- }
- }
- }
-}
-
#include <math.h>
#include <stdio.h>
-#include <iostream.h>
#include "library.hh"
#include "moebius.hh"
-#include "parameter.hh"
-
-Parameter<double> stiff("stiff","stiffness of tangent specs.",0.4,0.1,0.0,1.0);
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),
// The first end is oriented towards [0,cos(theta),sin(theta)]
// The second end is oriented towards [0,-1,0]
+Point MoebiusEnfoldmentAny::edgepoint(double t) {
+ double theta= t*2.0*M_PI;
+ return Point(sin(theta),cos(theta),0);
+}
+
Point MoebiusEnfoldment::middlepoint(double t, double u) {
if (t > bottomportion) {
t -= bottomportion;
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,
}
}
-double smoothinterp(double t, const double values[], const double rates[]) {
- const int ncells=4;
- int n1= (int)floor(t*ncells);
- int n2= n1+1;
- double r= t*ncells-n1;
- double v1= values[n1];
- double v2= values[n2];
- double r1= rates[n1]/ncells;
- double r2= rates[n2]/ncells;
- double dv= v2-v1;
- double a= r1+r2-2*dv;
- double b= 3*dv-2*r1-r2;
- double c= r1;
- double vr= a*r*r + b*r*r + c*r;
- double v= vr + v1;
-// printf("smoothinterp %7.6f %7.6f %g(%g)..%g(%g) %g\n",t,r,v1,r1,v2,r2,v);
- return v;
-}
+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 MoebiusNewEnfoldment::middlepoint(double t, double u) {
- const double agammas[]= {
- /* angle at rim for surface near edge, for values of t:
- * 0.0 .25 0.5 0.75 1.0, not usu. used */
- PI, 0.75*PI, 0.5*PI, -0.25*PI, -PI, -PI
- };
- const double agammarates[]= {
- /* rates of change of gamma with t */
- -PI, -PI, -PI, -3*PI, -3*PI, -PI
- };
- const double alambdas[]= { 0.0, 0.0, 0.0, 0.0, 0.0 };
- const double alambdarates[]= { 0.0, 0.0, 0.0, 0.0, 0.0 };
- const double bgammas[]= {
- /* angle at middle (u=0.5) in direction of decreasing u, for values of t:
- * 0.0 .25 0.5 0.75 1.0, not usu. used */
- 0, 0.5*PI, 0.5*PI, 0.5*PI, PI, PI
- };
- const double bgammarates[]= {
- /* rates of change of gamma with t */
- 2*PI, 0, 0, 0, 2*PI, 2*PI
- };
- const double blambdas[]= {
- /* shear along middle (u=0.5) for values of t:
- * 0.0 .25 0.5 0.75 1.0, not usu. used */
- 0.0, 0.5, 0.5, 0.5, 0, 0
- };
- const double blambdarates[]= { 0.0, 0.0, 0.0, 0.0, 0.0 };
- if (u > 0.5) {
- Point p= middlepoint(1.0-t,1.0-u);
- return Point(-p[0],p[1],-p[2]);
+ 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]);
}
- double aangle= PI*t;
- double asine= sin(aangle);
- double acosine= cos(aangle);
- double agamma= smoothinterp(t,agammas,agammarates);
- double arotnl= smoothinterp(t,alambdas,alambdarates);
- double aradial= cos(agamma);
- double aaxial= sin(agamma);
- Point a(asine, acosine, 0);
- Point da(arotnl*acosine+aradial*asine,aradial*acosine-arotnl*asine,-aaxial);
- double bangle= 2*PI*t;
- double bsine= sin(bangle);
- double bcosine= cos(bangle);
- double bgamma= smoothinterp(t,bgammas,bgammarates);
- double brotnl= smoothinterp(t,blambdas,blambdarates);
- double bradial= cos(bgamma);
- double baxial= sin(bgamma);
- Point b(0, bcosine-1.0, -bsine);
- Point db(baxial,bradial*bcosine-brotnl*bsine,brotnl*bcosine+bradial*bsine);
- u*=2;
- double ab= (a-b).magnitude();
- double adscale= ab*stiff/da.magnitude();
- double bdscale= ab*stiff/db.magnitude();
- double facta= (1-u)*(1-u)*(1-u);
- double factb= u*u*u;
- double factan= 3*(1-u)*(1-u)*u;
- double factbn= 3*(1-u)*u*u;
- Point dan= a+da*adscale;
- Point dbn= b+db*bdscale;
- Point result= a*facta + dan*factan + dbn*factbn + b*factb;
-// printf("t=%7.6f u=%7.6f a=%-30s dan=%-30s dbn=%-30s b=%-30s\n",
-// t,u, a.printing(), dan.printing(), dbn.printing(), b.printing());
- return result;
}
+++ /dev/null
-/*
- * Equation for a Moebius strip
- */
-
-#include <math.h>
-#include <stdio.h>
-
-#include "library.hh"
-#include "moebius.hh"
-
-Point MoebiusStrip::edgepoint(double t) {
- double theta= (t-0.5)*4.0*PI;
- double r= 1.0 - halfgap*(1.0 - sin(theta/2.0));
- return Point(r*sin(theta),
- -r*cos(theta),
- halfbreadth*cos(theta/2.0));
-}
-
-Point MoebiusStrip::middlepoint(double t, double u) {
- return edgepoint(t*0.5)*u + edgepoint((t+1)*0.5)*(1.0-u);
-}
-
-class Bezier {
- double e,f,g,h;
-public:
- Bezier(double x0, double x1, double dx0, double dx1);
- double operator()(double t) { return h + t*(g + t*(f + t*e)); }
- void debug();
-};
-
-Bezier::Bezier(double x0, double x1, double dx0, double dx1) {
-// e= 2*x0 - 2*x1 + dx0 + dx1;
-// f= x1 - dx0 - x0 - e;
- h= x0;
- g= dx0;
- e= g + 2*h + dx1 - 2*x1;
- f= x1 - e - g - h;
-}
-
-void Bezier::debug() {
- fprintf(stderr,"bz e %7.4f f %7.4f g %7.4f h %7.4f\n",e,f,g,h);
-}
-
-// The first end is at [sin(theta/2),-cos(theta/2),0]
-// The second end is at [-theta/pi,0,sin(theta)]
-// 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;
- return Point(sin(theta),cos(theta),0);
-}
-
-Point MoebiusEnfoldment::middlepoint(double t, double u) {
- if (t > bottomportion) {
- t -= bottomportion;
- t /= (1.0 - bottomportion);
- double sizehere= sqrt(1-t*t);
- return Point((u*2.0-1.0) * sizehere,
- t,
- sizehere * thickness * sin(u*2.0*PI));
- } else {
- t /= bottomportion;
- double theta= (.5-u)*2*PI;
- Bezier bx(sin(theta*.5), -theta/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= (.5-u)*(.5-u)*4*cos(theta*.5);
- Bezier by(-cos(theta*.5), 0,
- cos(theta)*ypushiness + fudge*ypushiness,
- ypushiness);
-//by.debug();
- Bezier bz(0, sin(theta), sin(theta), 0);
- return Point( bx(t), by(t), thickness * bz(t) );
- }
-}
+++ /dev/null
-/*
- * Equation for a Moebius strip
- */
-
-#include <math.h>
-#include <stdio.h>
-
-#include "library.hh"
-#include "moebius.hh"
-
-Point MoebiusStrip::edgepoint(double t) {
- double theta= (t-0.5)*4.0*PI;
- double r= 1.0 - halfgap*(1.0 - sin(theta/2.0));
- return Point(r*sin(theta),
- -r*cos(theta),
- halfbreadth*cos(theta/2.0));
-}
-
-Point MoebiusStrip::middlepoint(double t, double u) {
- return edgepoint(t*0.5)*u + edgepoint((t+1)*0.5)*(1.0-u);
-}
-
-class Bezier {
- double e,f,g,h;
-public:
- Bezier(double x0, double x1, double dx0, double dx1);
- double operator()(double t) { return h + t*(g + t*(f + t*e)); }
- void debug();
-};
-
-Bezier::Bezier(double x0, double x1, double dx0, double dx1) {
-// e= 2*x0 - 2*x1 + dx0 + dx1;
-// f= x1 - dx0 - x0 - e;
- h= x0;
- g= dx0;
- e= g + 2*h + dx1 - 2*x1;
- f= x1 - e - g - h;
-}
-
-void Bezier::debug() {
- fprintf(stderr,"bz e %7.4f f %7.4f g %7.4f h %7.4f\n",e,f,g,h);
-}
-
-// The first end is at [sin(theta/2),-cos(theta/2),0]
-// The second end is at [-theta/pi,0,sin(theta)]
-// The first end is oriented towards [0,cos(theta),sin(theta)]
-// The second end is oriented towards [0,-1,0]
-
-Point MoebiusEnfoldment::middlepoint(double t, double u) {
- if (t > bottomportion) {
- t -= bottomportion;
- t /= (1.0 - bottomportion);
- double sizehere= sqrt(1-t*t);
- return Point((u*2.0-1.0) * sizehere,
- t,
- sizehere * thickness * sin(u*2.0*PI));
- } else {
- t /= bottomportion;
- double theta= (.5-u)*2*PI;
- Bezier bx(sin(theta*.5), -theta/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= (.5-u)*(.5-u)*4*cos(theta*.5);
- Bezier by(-cos(theta*.5), 0,
- cos(theta)*ypushiness + fudge*ypushiness,
- ypushiness);
-//by.debug();
- Bezier bz(0, sin(theta), sin(theta), 0);
- return Point( bx(t), by(t), thickness * bz(t) );
- }
-}
-
-double lininterp(double t, const double array[]) {
- const int ncells=4;
- int n1= (int)floor(t*ncells);
- int n2= n1+1;
- double r= t*ncells-n1;
- double v1= array[n1];
- double v2= array[n2];
- return v1*(1.0-r) + v2*r;
-}
-
-Point MoebiusNewEnfoldment::middlepoint(double t, double u) {
- const double agammas[]= {
- /* angle at rim for surface near edge, for values of t:
- * 0.0 .25 0.5 0.75 1.0, not usu. used */
- PI, 0.75*PI, 0.5*PI, -0.25*PI, -PI, -PI
- };
- const double alambdas[]= { 0.0, 0.0, 0.0, 0.0, 0.0 };
- const double bgammas[]= {
- /* angle at middle (u=0.5) in direction of decreasing u, for values of t:
- * 0.0 .25 0.5 0.75 1.0, not usu. used */
- 0, 0.5*PI, 0.5*PI, 0.5*PI, 0.5*PI, 0.5*PI
- };
- const double blambdas[]= {
- /* shear along middle (u=0.5) for values of t:
- * 0.0 .25 0.5 0.75 1.0, not usu. used */
- 0.0, 0.5, 0.5, 0.5, 1.0, 1.0
- };
- if (u > 0.5) {
- Point p= middlepoint(1.0-t,1.0-u);
- return Point(-p[0],p[1],-p[2]);
- }
- double aangle= PI*t;
- double asine= sin(aangle);
- double acosine= cos(aangle);
- double agamma= lininterp(t,agammas);
- double arotnl= lininterp(t,alambdas);
- double aradial= cos(agamma);
- double aaxial= sin(agamma);
- Point a(asine,acosine,0);
- Point da(arotnl*acosine+aradial*asine,aradial*acosine-arotnl*asine,-aaxial);
- double bangle= 2*PI*t;
- double bsine= sin(bangle);
- double bcosine= cos(bangle);
- double bgamma= lininterp(t,bgammas);
- double brotnl= lininterp(t,blambdas);
- double bradial= cos(bgamma);
- double baxial= sin(bgamma);
- Point b(0,bcosine-1.0,bsine);
- Point db(baxial,bradial*bcosine-brotnl*bsine,brotnl*bcosine+bradial*bsine);
- Point tp;
- tp=a; a=b; b=tp;
- tp=da; da=db; db=tp;
- double ab= (a-b).magnitude();
- double adscale= ab*0.2/da.magnitude();
- double bdscale= ab*0.2/db.magnitude();
- u*=2;
- Bezier x(a[0],b[0],da[0]*adscale,db[0]*bdscale);
- Bezier y(a[1],b[1],da[1]*adscale,db[1]*bdscale);
- Bezier z(a[2],b[2],da[2]*adscale,db[2]*bdscale);
- return Point(x(u),y(u),z(u));
- return a*u+b*(1.0-u);
-}
virtual Point middlepoint(double t, double u) =0;
};
-class Moebius : public Surface {
+class Edge {
public:
+ // t varies from 0 to 1.0
+ virtual Point edgepoint(double t) =0;
+};
+
+class Moebius : public Surface, Edge {
+public:
+ virtual Point edgepoint(double t) =0;
virtual Point middlepoint(double t, double u) =0;
};
// Z ranges from -halfbreadth to +halfbreadth.
double halfgap; // 1/2 the width of the strip at the crossing point
double halfbreadth; // 1/2 the width of the strip at the flat part
- Point edgepoint(double t);
public:
MoebiusStrip() { halfgap= 0.15; halfbreadth= 0.15; }
MoebiusStrip(double b) { halfgap= halfbreadth= b/2.0; }
MoebiusStrip(double hg, double hb) { halfgap= hg/2.0; halfbreadth= hb/2.0; }
+ Point edgepoint(double t);
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 MoebiusNewEnfoldment : public Moebius {
+class MoebiusEnfoldmentNew : public MoebiusEnfoldmentAny {
public:
- MoebiusNewEnfoldment() { }
-
- Point edgepoint(double t);
+ MoebiusEnfoldmentNew() { }
Point middlepoint(double t, double u);
};
+++ /dev/null
-/*
- * Moebius strip
- */
-
-#ifndef MOEBIUS_HH
-#define MOEBIUS_HH
-
-class Surface {
-public:
- // t and u vary from 0 to 1.0
- virtual Point middlepoint(double t, double u) =0;
-};
-
-class Edge {
-public:
- // t varies from 0 to 1.0
- virtual Point edgepoint(double t) =0;
-};
-
-class Moebius : public Surface, Edge {
-public:
- virtual Point edgepoint(double t) =0;
- virtual Point middlepoint(double t, double u) =0;
-};
-
-class MoebiusStrip : public Moebius {
- // Strip is `lying' in the XY plane. The crossing is at the
- // maximal Y value, where the edge which has X*Z positive
- // has smaller Y at the point where X=Z=0 than the `other' edge,
- // which has X*Z negative. The flat part of the strip
- // is at minimal Y value. Here one edge has Z positive and
- // the other Z negative.
- // X and Y range from -1.0 to 1.0;
- // Z ranges from -halfbreadth to +halfbreadth.
- double halfgap; // 1/2 the width of the strip at the crossing point
- double halfbreadth; // 1/2 the width of the strip at the flat part
-public:
- MoebiusStrip() { halfgap= 0.15; halfbreadth= 0.15; }
- MoebiusStrip(double b) { halfgap= halfbreadth= b/2.0; }
- MoebiusStrip(double hg, double hb) { halfgap= hg/2.0; halfbreadth= hb/2.0; }
-
- Point edgepoint(double t);
- Point middlepoint(double t, double u);
-};
-
-class MoebiusEnfoldment : public Moebius {
- 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);
-};
-
-#endif
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(){};
};
}
AnyParameter* AnyParameter::find(const char *n) {
- AnyParameter *search;
+ 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;
+++ /dev/null
-/*
- * Parameters library
- */
-
-#include "parameter.hh"
-
-AnyParameter::AnyParameter(const char *n, const char *d) {
- name= n; description= d;
- next= first;
- first= this;
-}
-
-AnyParameter* AnyParameter::find(const char *n) {
- for (AnyParameter* search= first;
- search && strcmp(search->name,n);
- search= search->next);
- return search;
-}
-
-void AnyParameter::list() {
- for (AnyParameter* search= first;
- search;
- search= search->next)
- search->rangecheck();
-}
-
-AnyParameter* AnyParameter::first= 0;
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;
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
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) {
PostScriptOutput::~PostScriptOutput() {
file <<
" restore\n"
- " showpage\n"
"%%Trailer\n"
"%%EOF\n";
}
-void PostScriptOutput::drawcell(const Point* list, int n) {
+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]);
- docell(p,n,"1 setgray fill");
- docell(p,n,"0 setgray stroke");
+ 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) {
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);
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]);
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:
#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);
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);
}
+++ /dev/null
-/*
- * X11 functions
- */
-
-
-#include "x11.hh"
-
-X11Output::X11Output() {
- XGCValues gcvalues;
- 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);
- XSelectInput(display,window,0);
- XMapWindow(display,window);
- XFlush(display);
-}
-
-void X11Output::startimage() {
- XClearWindow(display,window);
-}
-
-void X11Output::endimage() {
- XFlush(display);
-}
-
-X11Output::~X11Output() {
- XCloseDisplay(display);
-}
-
-void X11Output::drawcell(const Point* list, int n) {
- 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);
- }
- XFillPolygon(display,window,fabric,xp,n,Nonconvex,CoordModeOrigin);
- xp[n]= xp[0];
- XDrawLines(display,window,mesh,xp,n+1,CoordModeOrigin);
-}
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