// _prelude_ // _generic_ // _glut_ // _window_ // _editor_ // _compiler_ // _shapes_ // _graphs_ // _startup_ //#include "done.cc" // _prelude_ --------------------------------------------------------- #include #include #include #include #include #include using namespace std; namespace AMPS { typedef double Num; // _generic_ --------------------------------------------------------- // base object class - not needed? class Object { public: virtual ~Object() = 0; }; inline Object::~Object() {} // _glut_ ------------------------------------------------------------ class Window; vector windows; // _window_ ---------------------------------------------------------- class Window : Object { protected: int window; int width; int height; private: // This static member 'windows' does not work for some obscure reason. // static unordered_map windows; static void static_display() { int window = glutGetWindow(); windows[window]->display(); } // static void static_timer(int window) { // windows[window]->timer(); // } public: Window(const char *title = "app", int width_ = 0, int height_ = 0, bool fullscreen = 0) : width(width_), height(height_) { if (width && height) { glutInitWindowSize(width, height); } window = glutCreateWindow(title); // cerr << "window: " << window << endl; // TODO use growvec? if (window >= (int)windows.size()) windows.resize(window+1); windows[window] = this; if (fullscreen) glutFullScreen(); glutDisplayFunc(&static_display); width = glutGet(GLUT_WINDOW_WIDTH); height = glutGet(GLUT_WINDOW_HEIGHT); } virtual ~Window() { glutDestroyWindow(window); } virtual void display() { glClear(GL_COLOR_BUFFER_BIT); glutSwapBuffers(); } void refresh() { // cerr << "refresh" << window << endl; glutPostWindowRedisplay(window); } }; // _shapes_ ---------------------------------------------------------- // max number of pixels error Num angle_per_radian = 180 / M_PI; Num arc_max_error = 0.25; Num a_pixel = 1; void draw_arc(Num x0, Num y0, Num x1, Num y1, Num angle) { angle /= angle_per_radian; // TODO simplify, use GL rotate / scale / translate Num dx, dy, d, hf, ox, oy, r, da, x, y, s, c, x_, y_, altx, alty, alt; Num bend = 1; angle = -angle; dx = (x1 - x0)/2; dy = (y1 - y0)/2; d = hypot(dx, dy); // calc origin hf = 1 / tan(angle / 2); ox = x0 + dx + dy*hf * bend; oy = y0 + dy - dx*hf * bend; // radius r = d / sin(fabs(angle)/2); // length // l = pi2*r * angle / 360 // delta angle // r * (1 - cos(da/2)) == arc_max_error // da = 0.2; // da = 1 / angle_per_radian; da = acos(1 - arc_max_error * a_pixel / r) * 2; // warn("da = %f old_da(3) = %f old_da(16) = %f", da, angle / l * 3 * a_pixel, angle / l * 16 * a_pixel) // da = angle / l * calc_arc_d * a_pixel altx = dy * hf; alty = -dx * hf; alt = hypot(altx, alty); altx /= alt; alty /= alt; // glVertex2d(x0, y0); int steps = fabs(angle) / da; for(int i=0; i