void fillrect (float x1, float y1, float x2, float y2) { /* (x1,y1) and (x2,y2) are diagonally opposed corners in world coords. */ unsigned int width, height; int xw1, yw1, xw2, yw2, xl, yt; if (rect_off_screen(x1,y1,x2,y2)) return; if (disp_type == SCREEN) { /* translate to X Windows calling convention. */ xw1 = xcoord(x1); xw2 = xcoord(x2); yw1 = ycoord(y1); yw2 = ycoord(y2); xl = min(xw1,xw2); yt = min(yw1,yw2); width = abs (xw1-xw2); height = abs (yw1-yw2); XFillRectangle(display, toplevel, gc, xl, yt, width, height); } else { fprintf(ps,"%.2f %.2f %.2f %.2f fillrect\n",XPOST(x1),YPOST(y1), XPOST(x2),YPOST(y2)); } }
MSLPoint3d MSLPoint3d::reflect(const MSLPoint3d& a, const MSLPoint3d& b, const MSLPoint3d& c) const { // reflect point across plane through a, b, and c double x1 = b.xcoord() - a.xcoord(); double y1 = b.ycoord() - a.ycoord(); double z1 = b.zcoord() - a.zcoord(); double x2 = c.xcoord() - a.xcoord(); double y2 = c.ycoord() - a.ycoord(); double z2 = c.zcoord() - a.zcoord(); double x3 = xcoord() - a.xcoord(); double y3 = ycoord() - a.ycoord(); double z3 = zcoord() - a.zcoord(); double x = (z1*y2-y1*z2); double y = (x1*z2-z1*x2); double z = (y1*x2-x1*y2); if (x == 0 && y == 0 && z == 0) error_handler(1,"MSLPoint3d::reflect(a,b,c): a,b,c are coplanar"); double f = -2*(x*x3+y*y3+z*z3)/(x*x+y*y+z*z); return translate(f*x,f*y,f*z); }
void drawtext (float xc, float yc, char *text, float boundx) { /* Draws text centered on xc,yc if it fits in boundx */ int len, width, xw_off, yw_off; len = strlen(text); width = XTextWidth(font_info[currentfontsize], text, len); if (width > fabs(boundx*xmult)) return; /* Don't draw if it won't fit */ xw_off = width/(2.*xmult); /* NB: sign doesn't matter. */ /* NB: 2 * descent makes this slightly conservative but simplifies code. */ yw_off = (font_info[currentfontsize]->ascent + 2 * font_info[currentfontsize]->descent)/(2.*ymult); /* Note: text can be clipped when a little bit of it would be visible * * right now. Perhaps X doesn't return extremely accurate width and * * ascent values, etc? Could remove this completely by multiplying * * xw_off and yw_off by, 1.2 or 1.5. */ if (rect_off_screen(xc-xw_off, yc-yw_off, xc+xw_off, yc+yw_off)) return; if (disp_type == SCREEN) { XDrawString(display, toplevel, gc, xcoord(xc)-width/2, ycoord(yc) + (font_info[currentfontsize]->ascent - font_info[currentfontsize]->descent)/2, text, len); } else { fprintf(ps,"(%s) %.2f %.2f censhow\n",text,XPOST(xc),YPOST(yc)); } }
void drawline (float x1, float y1, float x2, float y2) { /* Draw a line from (x1,y1) to (x2,y2) in the user-drawable area. * * Coordinates are in world (user) space. */ if (rect_off_screen(x1,y1,x2,y2)) return; if (disp_type == SCREEN) { /* Xlib.h prototype has x2 and y1 mixed up. */ XDrawLine(display, toplevel, gc, xcoord(x1), ycoord(y1), xcoord(x2), ycoord(y2)); } else { fprintf(ps,"%.2f %.2f %.2f %.2f drawline\n",XPOST(x1),YPOST(y1), XPOST(x2),YPOST(y2)); } }
static void buildMaze(int y, int x) { int numOffsets, offset, offsets[4]; while (1) { numOffsets = 0; maze[y][x].visited = true; if (y > 0 && !maze[y - 1][x].visited) offsets[numOffsets ++] = -width; if (y < height - 1 && !maze[y + 1][x].visited) offsets[numOffsets ++] = width; if (x > 0 && !maze[y][x - 1].visited) offsets[numOffsets ++] = -1; if (x < width - 1 && !maze[y][x + 1].visited) offsets[numOffsets ++] = 1; if (numOffsets > 0) { offset = offsets[rand() % numOffsets]; addFirst(dp, offset(x, y)); if (offset == -width) { maze[y - 1][x].bottom = false; buildMaze(y - 1, x); } else if (offset == width) { maze[y][x].bottom = false; buildMaze(y + 1, x); } else if (offset == -1) { maze[y][x - 1].right = false; buildMaze(y, x - 1); } else if (offset == 1) { maze[y][x].right = false; buildMaze(y, x + 1); } else abort(); } else if (numItems(dp) > 0) { offset = removeFirst(dp); x = xcoord(offset); y = ycoord(offset); } else break; } maze[height - 1][width - 1].right = false; }
static void solveMaze(void) { int x, y, offset; for (y = 0; y < height; y ++) for (x = 0; x < width; x ++) maze[y][x].visited = false; y = 0; x = 0; while (y != height - 1 || x != width - 1) { draw(x, y, true); maze[y][x].visited = true; if (!maze[y][x].right && !maze[y][x + 1].visited) { addLast(dp, offset(x + 1, y)); maze[y][x + 1].from = 1; } if (!maze[y][x].bottom && !maze[y + 1][x].visited) { addLast(dp, offset(x, y + 1)); maze[y + 1][x].from = width; } if (x > 0 && !maze[y][x - 1].right && !maze[y][x - 1].visited) { addLast(dp, offset(x - 1, y)); maze[y][x - 1].from = -1; } if (y > 0 && !maze[y - 1][x].bottom && !maze[y - 1][x].visited) { addLast(dp, offset(x, y - 1)); maze[y - 1][x].from = -width; } if (getLast(dp) == offset(x, y)) { draw(x, y, false); removeLast(dp); } offset = getLast(dp); x = xcoord(offset); y = ycoord(offset); } draw(width - 1, height - 1, true); }
void fillpoly (t_point *points, int npoints) { XPoint transpoints[MAXPTS]; int i; float xmin, ymin, xmax, ymax; if (npoints > MAXPTS) { printf("Error in fillpoly: Only %d points allowed per polygon.\n", MAXPTS); printf("%d points were requested. Polygon is not drawn.\n",npoints); return; } /* Conservative (but fast) clip test -- check containing rectangle of * * polygon. */ xmin = xmax = points[0].x; ymin = ymax = points[0].y; for (i=1;i<npoints;i++) { xmin = min (xmin,points[i].x); xmax = max (xmax,points[i].x); ymin = min (ymin,points[i].y); ymax = max (ymax,points[i].y); } if (rect_off_screen(xmin,ymin,xmax,ymax)) return; if (disp_type == SCREEN) { for (i=0;i<npoints;i++) { transpoints[i].x = (short) xcoord (points[i].x); transpoints[i].y = (short) ycoord (points[i].y); } XFillPolygon(display, toplevel, gc, transpoints, npoints, Complex, CoordModeOrigin); } else { fprintf(ps,"\n"); for (i=npoints-1;i>=0;i--) fprintf (ps, "%.2f %.2f\n", XPOST(points[i].x), YPOST(points[i].y)); fprintf (ps, "%d fillpoly\n", npoints); } }
void drawarc (float xc, float yc, float rad, float startang, float angextent) { /* Draws a circular arc. X11 can do elliptical arcs quite simply, and * * PostScript could do them by scaling the coordinate axes. Too much * * work for now, and probably too complex an object for users to draw * * much, so I'm just doing circular arcs. Startang is relative to the * * Window's positive x direction. Angles in degrees. */ int xl, yt; unsigned int width, height; /* Conservative (but fast) clip test -- check containing rectangle of * * a circle. */ if (rect_off_screen (xc-rad,yc-rad,xc+rad,yc+rad)) return; /* X Windows has trouble with very large angles. (Over 360). * * Do following to prevent its inaccurate (overflow?) problems. */ if (fabs(angextent) > 360.) angextent = 360.; startang = angnorm (startang); if (disp_type == SCREEN) { xl = (int) (xcoord(xc) - fabs(xmult*rad)); yt = (int) (ycoord(yc) - fabs(ymult*rad)); width = (unsigned int) (2*fabs(xmult*rad)); height = width; XDrawArc (display, toplevel, gc, xl, yt, width, height, (int) (startang*64), (int) (angextent*64)); } else { fprintf(ps,"%.2f %.2f %.2f %.2f %.2f %s stroke\n", XPOST(xc), YPOST(yc), fabs(rad*ps_xmult), startang, startang+angextent, (angextent < 0) ? "drawarcn" : "drawarc") ; } }
void fillarc (float xc, float yc, float rad, float startang, float angextent) { /* Fills a circular arc. Startang is relative to the Window's positive x * * direction. Angles in degrees. */ int xl, yt; unsigned int width, height; /* Conservative (but fast) clip test -- check containing rectangle of * * a circle. */ if (rect_off_screen (xc-rad,yc-rad,xc+rad,yc+rad)) return; /* X Windows has trouble with very large angles. (Over 360). * * Do following to prevent its inaccurate (overflow?) problems. */ if (fabs(angextent) > 360.) angextent = 360.; startang = angnorm (startang); if (disp_type == SCREEN) { xl = (int) (xcoord(xc) - fabs(xmult*rad)); yt = (int) (ycoord(yc) - fabs(ymult*rad)); width = (unsigned int) (2*fabs(xmult*rad)); height = width; XFillArc (display, toplevel, gc, xl, yt, width, height, (int) (startang*64), (int) (angextent*64)); } else { fprintf(ps,"%.2f %.2f %.2f %.2f %.2f %s\n", fabs(rad*ps_xmult), startang, startang+angextent, XPOST(xc), YPOST(yc), (angextent < 0) ? "fillarcn" : "fillarc") ; } }
MSLPoint3d MSLPoint3d::reflect(const MSLPoint3d& q) const { // reflect point across point q return MSLPoint3d(2*q.xcoord()-xcoord(), 2*q.ycoord()-ycoord(), 2*q.zcoord()-zcoord()); }
MSLPoint3d MSLPoint3d::translate(double dx, double dy, double dz) const { return MSLPoint3d(xcoord()+dx,ycoord()+dy,zcoord()+dz); }
void Viewport::updateYAxis(bool yAxisChanged) { // steps on the y-axis (number of labeled values) const int amount = 10; /* calculate raw numbers for y-axis */ std::vector<float> ycoord(amount); float maximum = 0.f; SharedDataLock ctxlock(ctx->mutex); float plotmaxval = (*ctx)->maxval; float plotminval = (*ctx)->minval; float binscount = (qreal)((*ctx)->nbins); ctxlock.unlock(); float maxvalue; float range = 1/zoom; if (yAxisChanged) { QPointF bottom(0.f, boundaries.vp); bottom = modelviewI.map(bottom); qreal ratio = bottom.y()/binscount; maxvalue = plotmaxval - (1.f-ratio) * (plotmaxval - plotminval); if (maxvalue > plotmaxval) maxvalue = plotmaxval; } else { maxvalue = plotmaxval; } for (int i = 0; i < amount; ++i) { ycoord[i] = maxvalue - i*(1.f/(amount-1))*range*(plotmaxval - plotminval); ycoord[i] = std::max(ycoord[i], plotminval); maximum = std::max(maximum, std::abs(ycoord[i])); } if (maximum == 0.f) return; /* find order of magnitude of maximum value */ float roundAt = 0.001f; // we want 3 significant digits if (maximum >= 1.f) { do { maximum *= 0.1f; roundAt *= 10.f; } while (maximum >= 1.f); } else { while (maximum < 1.f) { maximum *= 10.f; roundAt *= 0.1f; }; } /* set y-axis strings and find width of y-axis legend */ yaxis.resize(amount); yaxisWidth = 0; QFontMetrics fm(font()); for (int i = 0; i < amount; ++i) { float value = roundAt * std::floor(ycoord[i]/roundAt + 0.5f); yaxis[i] = QString().setNum(value, 'g', 3); yaxisWidth = std::max(yaxisWidth, fm.width(yaxis[i])); } }