-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=
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)
-
#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;
+ int i;
for (i=0; i<2; i++) {
gcvalues.plane_mask= planemasks[i];
// First, the fabric
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);
}
/*
- * 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;
+ 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;
}
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) {
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++);
--- /dev/null
+theta=0.5
+bulge=2
+sheary=0.8
+eta=-1
+twist=0.5
+tear=1
*/
#include <stdlib.h>
+#include <stdio.h>
#include "library.hh"
#include "transforms.hh"
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]; }
+++ /dev/null
-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 ./
#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++) {
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 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,'=');
} 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 {
}
}
}
-
#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),
// 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);
}
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,
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]);
+ }
+}
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);
};
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) {
- 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;
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) {
"%%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) {
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);
}
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