Skip to content

Instantly share code, notes, and snippets.

@tobin
Created July 3, 2011 23:58
Show Gist options
  • Save tobin/1062726 to your computer and use it in GitHub Desktop.
Save tobin/1062726 to your computer and use it in GitHub Desktop.
draw a series/parallel combination of capacitors in postscript (incomplete)
#include <iostream>
#include <vector>
#include <string>
using namespace std;
class drawable {
public:
virtual float getHeight() = 0;
virtual float getWidth() = 0;
virtual void draw_at(float, float) = 0;
virtual ~drawable() { }
};
class column : public drawable{
public:
column(bool vertical);
virtual void add(drawable *item);
virtual float getHeight();
virtual float getWidth();
virtual void draw_at(float, float);
virtual ~column() {}
private:
vector<drawable*> contents;
bool vertical;
};
column::column(bool vertical) {
this->vertical = vertical;
}
void column::add(drawable *item) {
contents.push_back(item);
}
float column::getHeight() {
float height = 0;
for (unsigned int ii=0; ii<contents.size(); ii++) {
float thing_height = contents[ii]->getHeight();
if (vertical)
height += thing_height;
else
height = (height > thing_height ? height : thing_height); // max
}
return height;
}
float column::getWidth() {
float width = 0;
for (unsigned int ii=0; ii<contents.size(); ii++) {
float thing_width = contents[ii]->getWidth();
if (!vertical)
width += thing_width;
else
width = (width > thing_width ? width : thing_width); // max
}
return width;
}
void column::draw_at(float x, float y) {
float x0 = x;
float y0 = y;
float myheight = this->getHeight();
float mywidth = this->getWidth();
for (unsigned int ii=0; ii<contents.size(); ii++) {
drawable *thing = contents[ii];
// centering
if (vertical)
x = x0 + mywidth/2.0 - thing->getWidth()/2.0;
else
y = y0 + myheight/2.0 - thing->getHeight()/2.0;
thing->draw_at(x, y);
if (vertical)
y += thing->getHeight();
else
x += thing->getWidth();
}
}
class box : public drawable {
public:
box(float width, float height) { this->width = width; this->height = height; }
float getHeight() {return height; }
float getWidth() {return width; }
void draw_at(float x, float y);
private:
float width, height;
};
void box::draw_at(float x, float y) {
/* cout << "newpath" << endl
<< x << " " << y << " moveto " << endl
<< width << " 0 rlineto" << endl
<< "0 " << height << " rlineto" << endl
<< -width << " 0 rlineto" << endl
<< "closepath" << endl
<< "stroke" << endl;
*/
// -||-
float d = 1*width/16;
float h = 5*height/8;
cout << "newpath" << endl;
cout << x << " " << y << " moveto " << endl;
cout << "0 " << height/2 << " rmoveto" << endl;
cout << (width-d)/2 << " 0 rlineto" << endl; // left lead
cout << "0 " << -h/2 << " rmoveto" << endl;
cout << "0 " << h << " rlineto" << endl;
cout << d << " 0 rmoveto" << endl;
cout << "0 " << -h << " rlineto" << endl;
cout << "0 " << h/2 << " rmoveto" << endl;
cout << (width-d)/2 << " 0 rlineto stroke" << endl;
}
class EPS {
public:
static void draw(drawable *item);
};
void EPS::draw(drawable *item) {
cout << "%%BoundingBox: 0 0 " << item->getWidth() << " " << item->getHeight() << endl;
cout << "%%EndComments" << endl;
item->draw_at(0,0);
cout << "showpage" << endl;
return;
}
int main(int argc, char **argv) {
// Should take in circuit descriptions and emit postscript (?)
/*
circuit = series | parallel | capacitor
series = series(N) | series(circuit, circuit, ...)
parallel = parallel(N) | parallel(circuit, circuit, ...)
Or maybe a circuit-assembling stack machine?
+----||-----+
----||----+ +------
+--||---||--+
series(capacitor,parallel(capacitor,series(capacitor,capacitor)))
*/
box *abox = new box(36,36);
column *col = new column(true);
column *row = new column(false);
cout << "%!PS-Adobe-2.0 EPSF-2.0" << endl;
row->add(abox);
col->add(abox);
col->add(abox);
row->add(col);
row->add(abox);
column *row2 = new column(false);
row2->add(abox);
row2->add(abox);
column *col2 = new column(true);
col2->add(row);
col2->add(row2);
EPS::draw(col2);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment