static int compute_relevant_points (double xx, double yy, double oldxx, double oldyy, int clip_mode, double user_min_x, double user_min_y, double user_max_x, double user_max_y, bool spec_min_x, bool spec_min_y, bool spec_max_x, bool spec_max_y, double xxr[2], double yyr[2]) { int clipval; switch (clip_mode) { case 0: if ((!spec_min_x || xx >= user_min_x) && (!spec_max_x || xx <= user_max_x) && (!spec_min_y || yy >= user_min_y) && (!spec_max_y || yy <= user_max_y)) { xxr[0] = xx; yyr[0] = yy; return 1; } else return 0; break; case 1: default: clipval = clip_line (&oldxx, &oldyy, &xx, &yy, user_min_x, user_max_x, user_min_y, user_max_y, spec_min_x, spec_min_y, spec_max_x, spec_max_y); if ((clipval & ACCEPTED) && !((clipval & CLIPPED_FIRST) && (clipval & CLIPPED_SECOND))) { xxr[0] = oldxx; yyr[0] = oldyy; xxr[1] = xx; yyr[1] = yy; return 2; } else return 0; break; case 2: clipval = clip_line (&oldxx, &oldyy, &xx, &yy, user_min_x, user_max_x, user_min_y, user_max_y, spec_min_x, spec_min_y, spec_max_x, spec_max_y); if (clipval & ACCEPTED) { xxr[0] = oldxx; yyr[0] = oldyy; xxr[1] = xx; yyr[1] = yy; return 2; } else return 0; break; } }
//deal with a clipped line bool must_clip_line(g3s_point *p0,g3s_point *p1,ubyte codes_or) { bool ret; if ((p0->p3_flags&PF_TEMP_POINT) || (p1->p3_flags&PF_TEMP_POINT)) ret = 0; //line has already been clipped, so give up else { clip_line(&p0,&p1,codes_or); ret = g3_draw_line(p0,p1); } //free temp points if (p0->p3_flags & PF_TEMP_POINT) free_temp_point(p0); if (p1->p3_flags & PF_TEMP_POINT) free_temp_point(p1); return ret; }
void sng_current_draw_bright_line(float x1, float y1, float x2, float y2, int color) { float sx1, sy1, sx2, sy2, dx, dy; if (fabs(x1 - x2) > fabs(y1 - y2)) { dx = 0; dy = 1; } else { dx = 1; dy = 0; } if (!clip_line(&sgc.c, &x1, &y1, &x2, &y2)) return; sx1 = x1 * sgc.xscale; sx2 = x2 * sgc.xscale; sy1 = y1 * sgc.yscale; sy2 = y2 * sgc.yscale; sng_set_foreground(WHITE); graph_dev_draw_line(sx1, sy1, sx2, sy2); sng_set_foreground(color); graph_dev_draw_line(sx1 - dx, sy1 - dy, sx2 - dx, sy2 - dy); graph_dev_draw_line(sx1 + dx, sy1 + dy, sx2 + dx, sy2 + dy); }
int main(int argc, char** argv) { std::vector<std::string> args; for (int i=1;i<argc;++i) { args.push_back(argv[i]); } bool quiet = std::find(args.begin(), args.end(), "-q")!=args.end(); try { BOOST_TEST(set_working_dir(args)); std::string filename("tests/cpp_tests/data/cases.txt"); std::ifstream stream(filename.c_str(),std::ios_base::in | std::ios_base::binary); if (!stream.is_open()) throw std::runtime_error("could not open: '" + filename + "'"); std::string csv_line; while(std::getline(stream,csv_line,'\n')) { if (csv_line.empty() || csv_line[0] == '#') continue; std::vector<std::string> parts; boost::split(parts, csv_line, boost::is_any_of(";")); // first part is clipping box mapnik::box2d<double> bbox; if (!bbox.from_string(parts[0])) { throw std::runtime_error(std::string("could not parse bbox '") + parts[0] + "'"); } // second part is input geometry mapnik::geometry_type geom; parse_geom(geom,parts[1]); //std::clog << dump_path(geom) << "\n"; // third part is expected, clipped geometry BOOST_TEST_EQ(clip_line(bbox,geom),mapnik::util::trim_copy(parts[2])); } stream.close(); } catch (std::exception const& ex) { std::cerr << ex.what() << "\n"; } if (!::boost::detail::test_errors()) { if (quiet) std::clog << "\x1b[1;32m.\x1b[0m"; else std::clog << "C++ clipping: \x1b[1;32m✓ \x1b[0m\n"; ::boost::detail::report_errors_remind().called_report_errors_function = true; } else { return ::boost::report_errors(); } }
void draw_line(double x0, double y0, double x1, double y1) { int i; double x,y; double dx,dy; double xinc,yinc; double lenosuh; int result; int width,height; /* set the clipping window */ osuGetFramebufferSize (&width, &height); set_clip_window (0.0f, 0.0f, width - 0.51f, height - 0.51f); /* clip the line in 2D */ result = clip_line (&x0, &y0, &x1, &y1); /* return if line is entirely outside the clip window */ if (result == 0) return; /* incremental line drawing */ dx = x1 - x0; dy = y1 - y0; /* determine whether horizontal or vertical change is larger */ if (fabs(dx) > fabs(dy)) lenosuh = (double)fabs(dx); else lenosuh = (double)fabs(dy); /* special case to avoid dividing by zero */ if (lenosuh == 0) { osuWritePixel ((int) floor(x0+0.5), (int) floor(y0+0.5), 255, 255, 255); return; } xinc = dx / lenosuh; yinc = dy / lenosuh; x = x0; y = y0; /* write "lenosuh" number of pixels along the line */ for (i = 0; i <= lenosuh; i++) { osuWritePixel ((int) floor(x+0.5), (int) floor(y+0.5), 255, 255, 255); x += xinc; y += yinc; } }
int clip_line_copy(struct liang_barsky_clip_window *c, float x1, float y1, float x2, float y2, float *ox1, float *oy1, float *ox2, float *oy2) { *ox1 = x1; *oy1 = y1; *ox2 = x2; *oy2 = y2; return clip_line(c, ox1, ox2, oy1, oy2); }
void Edges::endpoint(Edge *e, EdgeEnd lr, Site *s) { e -> ep[lr] = s; sites.ref(s); if(e -> ep[opp(lr)] == (Site *) 0) return; clip_line (e); #ifdef STANDALONE out_ep(e); #endif sites.deref(e->reg[le]); sites.deref(e->reg[re]); fedges.free(e); }
static void sng_draw_bright_white_electric_line(float x1, float y1, float x2, float y2, int color) { struct sng_dotted_plot_func_context context; context.i = color; if (!clip_line(&sgc.c, &x1, &y1, &x2, &y2)) return; bline(x1 * sgc.xscale, y1 * sgc.yscale, x2 * sgc.xscale, y2 * sgc.yscale, sng_bright_electric_line_plot_func, &context); }
void sng_draw_electric_line(float x1, float y1, float x2, float y2) { struct sng_dotted_plot_func_context context; context.i = 0; if (!clip_line(&sgc.c, &x1, &y1, &x2, &y2)) return; bline(x1 * sgc.xscale, y1 * sgc.yscale, x2 * sgc.xscale, y2 * sgc.yscale, sng_electric_line_plot_func, &context); }
void VoronoiDiagramGenerator::endpoint(struct Edge *e,int lr,struct Site * s) { e -> ep[lr] = s; ref(s); if(e -> ep[re-lr]== (struct Site *) NULL) return; clip_line(e); //RhinoApp().Print(L"\n clip line deref\n"); //deref(e->reg[le]); //deref(e->reg[re]); //makefree((Freenode*)e, &efl); }
/* Clip the given line to drawing coords defined by BoundingBox. * This routine uses the cohen & sutherland bit mapping for fast clipping - * see "Principles of Interactive Computer Graphics" Newman & Sproull page 65. */ void draw_clip_line(int x1, int y1, int x2, int y2) { struct termentry *t = term; if (!clip_line(&x1, &y1, &x2, &y2)) /* clip_line() returns zero --> segment completely outside * bounding box */ return; (*t->move) (x1, y1); (*t->vector) (x2, y2); }
void VoronoiDiagramGenerator::endpoint(struct VoronoiDiagramGenerator::Edge *e,int lr,struct VoronoiDiagramGenerator::Site * s) { e -> ep[lr] = s; ref(s); if(e -> ep[re-lr]== (struct Site *) NULL) return; clip_line(e); deref(e->reg[le]); deref(e->reg[re]); makefree((Freenode*)e, &efl); }
void endpoint(Edge * e, int lr, Site * s) { e->ep[lr] = s; ref(s); if (e->ep[re - lr] == (Site *) NULL) return; clip_line(e); #ifdef STANDALONE out_ep(e); #endif deref(e->reg[le]); deref(e->reg[re]); makefree(e, &efl); }
void out_ep(Edge * e) { if (!triangulate && plot) { clip_line(e) ; } if (!triangulate && !plot) { printf("e %d", e->edgenbr); printf(" %d ", e->ep[le] != (Site *)NULL ? e->ep[le]->sitenbr : -1) ; printf("%d\n", e->ep[re] != (Site *)NULL ? e->ep[re]->sitenbr : -1) ; } }
void draw_clip_arrow( int sx, int sy, int ex, int ey, int head) { struct termentry *t = term; /* Don't draw head if the arrow itself is clipped */ if (clip_point(sx,sy)) head &= ~BACKHEAD; if (clip_point(ex,ey)) head &= ~END_HEAD; clip_line(&sx, &sy, &ex, &ey); /* Call terminal routine to draw the clipped arrow */ (*t->arrow)((unsigned int)sx, (unsigned int)sy, (unsigned int)ex, (unsigned int)ey, head); }
/* Clip the given line to drawing coords defined by BoundingBox. * This routine uses the cohen & sutherland bit mapping for fast clipping - * see "Principles of Interactive Computer Graphics" Newman & Sproull page 65. */ void draw_clip_line(int x1, int y1, int x2, int y2) { struct termentry *t = term; /* HBB 20000522: I've made this routine use the clippling in * clip_line(), in a movement to reduce code duplication. There * was one very small difference between these two routines. See * clip_line() for a comment about it, at the relevant place. */ if (!clip_line(&x1, &y1, &x2, &y2)) /* clip_line() returns zero --> segment completely outside * bounding box */ return; (*t->move) (x1, y1); (*t->vector) (x2, y2); }
void out_ep(Edge * e) { /* Save endpoint to our ruby object */ (*rubyvorState.storeE)(e->edgenbr, e->ep[le] != (Site *)NULL ? e->ep[le]->sitenbr : -1, e->ep[re] != (Site *)NULL ? e->ep[re]->sitenbr : -1, e->reg[0] != (Site *)NULL ? e->reg[0]->sitenbr : -1, e->reg[1] != (Site *)NULL ? e->reg[1]->sitenbr : -1); /* printf("e %d", e->edgenbr); printf(" %d ", e->ep[le] != (Site *)NULL ? e->ep[le]->sitenbr : -1) ; printf("%d\n", e->ep[re] != (Site *)NULL ? e->ep[re]->sitenbr : -1) ; */ if (rubyvorState.plot) clip_line(e) ; }
/* * Bresenham algorithm for drawing line points */ void Line::doDraw(PPM_Image &I, const PPM_Color &c) const { int x1 {p1_.x()}, y1 {p1_.y()}, x2 {p2_.x()}, y2 {p2_.y()}; // clip the line if needed if (!clip_line(x1, y1, x2, y2, 0, I.width(), 0, I.height())) return; int dx {std::abs(x1- x2)}, dy {std::abs(y1 - y2)}; const bool steep {dy > dx}; if (steep) { std::swap(x1, y1); std::swap(x2, y2); std::swap(dx, dy); } if (x1 > x2) { std::swap(x1, x2); std::swap(y1, y2); } const int incdy {dy << 1}, incdx {dx << 1}, ystep {y1 < y2 ? 1 : -1}; const uint clr {c.color()}; for (int x {x1}, e {dx}; x <= x2; ++x) { steep ? I[y1][x] = clr : I[x][y1] = clr; if ((e -= incdy) < 0) { y1 += ystep; e += incdx; } } }
/* Draw a contiguous line path which may be clipped. Compared to * draw_clip_line(), this routine moves to a coordinate only when * necessary. */ void draw_clip_polygon(int points, gpiPoint *p) { int i; int x1, y1, x2, y2; int pos1, pos2, clip_ret; struct termentry *t = term; if (points <= 1) return; x1 = p[0].x; y1 = p[0].y; pos1 = clip_point(x1, y1); if (!pos1) /* move to first point if it is inside */ (*t->move)(x1, y1); for (i = 1; i < points; i++) { x2 = p[i].x; y2 = p[i].y; pos2 = clip_point(x2, y2); clip_ret = clip_line(&x1, &y1, &x2, &y2); if (clip_ret) { /* there is a line to draw */ if (pos1) /* first vertex was recalculated, move to new start point */ (*t->move)(x1, y1); (*t->vector)(x2, y2); } x1 = p[i].x; y1 = p[i].y; /* The end point and the line do not necessarily have the same * status. The end point can be 'inside', but the whole line is * 'outside'. Do not update pos1 in this case. Bug #1268. * FIXME: This is papering over an inconsistency in coordinate * calculation somewhere else! */ if (!(clip_ret == 0 && pos2 == 0)) pos1 = pos2; } }
static gint draw_line (gint n, gint startx, gint starty, gint pw, gint ph, gdouble cx1, gdouble cy1, gdouble cx2, gdouble cy2, GimpVector3 a, GimpVector3 b) { gdouble x1, y1, x2, y2; gint i = n; gimp_vector_3d_to_2d (startx, starty, pw, ph, &x1, &y1, &mapvals.viewpoint, &a); gimp_vector_3d_to_2d (startx, starty, pw, ph, &x2, &y2, &mapvals.viewpoint, &b); if (clip_line (&x1, &y1, &x2, &y2, cx1, cy1, cx2, cy2) == TRUE) { linetab[i].x1 = RINT (x1); linetab[i].y1 = RINT (y1); linetab[i].x2 = RINT (x2); linetab[i].y2 = RINT (y2); linetab[i].linewidth = 3; linetab[i].linestyle = GDK_LINE_SOLID; gdk_gc_set_line_attributes (gc, linetab[i].linewidth, linetab[i].linestyle, GDK_CAP_NOT_LAST, GDK_JOIN_MITER); gdk_draw_line (previewarea->window, gc, linetab[i].x1, linetab[i].y1, linetab[i].x2, linetab[i].y2); i++; } return i; }
void sng_draw_laser_line(float x1, float y1, float x2, float y2, int color) { float dx, dy; if (fabs(x1 - x2) > fabs(y1 - y2)) { dx = 0; dy = 1; } else { dx = 1; dy = 0; } if (!clip_line(&sgc.c, &x1, &y1, &x2, &y2)) return; sng_draw_bright_white_electric_line(x1, y1, x2, y2, color); sng_set_foreground(color); sng_draw_electric_line(x1 - dx, y1 - dy, x2 - dx, y2 - dy); sng_draw_electric_line(x1 + dx, y1 + dy, x2 + dx, y2 + dy); }
void draw_2d_half_thick_line (float x1, float y1, float x2, float y2, const rgb_colour col) { float x1t, y1t, x2t, y2t; ASSERT (active_2d_environment); validate_2d_composite_transformation_matrix (active_2d_environment); x1t = (x1 * active_2d_environment->composite_transformation[0][0]) + (y1 * active_2d_environment->composite_transformation[1][0]) + active_2d_environment->composite_transformation[2][0]; y1t = (x1 * active_2d_environment->composite_transformation[0][1]) + (y1 * active_2d_environment->composite_transformation[1][1]) + active_2d_environment->composite_transformation[2][1]; x2t = (x2 * active_2d_environment->composite_transformation[0][0]) + (y2 * active_2d_environment->composite_transformation[1][0]) + active_2d_environment->composite_transformation[2][0]; y2t = (x2 * active_2d_environment->composite_transformation[0][1]) + (y2 * active_2d_environment->composite_transformation[1][1]) + active_2d_environment->composite_transformation[2][1]; x1t += active_2d_environment->offset_x * active_2d_environment->window_scaling[0][0] * 0.9; x2t += active_2d_environment->offset_x * active_2d_environment->window_scaling[0][0] * 0.9; y1t -= active_2d_environment->offset_y * active_2d_environment->window_scaling[1][1] * 0.9; y2t -= active_2d_environment->offset_y * active_2d_environment->window_scaling[1][1] * 0.9; if (clip_line (&x1t, &y1t, &x2t, &y2t)) { draw_half_thick_line (x1t, y1t, x2t, y2t, col); } }
void sng_current_draw_thick_line(float x1, float y1, float x2, float y2) { float sx1, sy1, sx2, sy2, dx, dy; if (!clip_line(&sgc.c, &x1, &y1, &x2, &y2)) return; if (fabs(x1 - x2) > fabs(y1 - y2)) { dx = 0; dy = 1; } else { dx = 1; dy = 0; } sx1 = x1 * sgc.xscale; sx2 = x2 * sgc.xscale; sy1 = y1 * sgc.yscale; sy2 = y2 * sgc.yscale; graph_dev_draw_line(sx1, sy1, sx2, sy2); graph_dev_draw_line(sx1 - dx, sy1 - dy, sx2 - dx, sy2 - dy); graph_dev_draw_line(sx1 + dx, sy1 + dy, sx2 + dx, sy2 + dy); }
void item_bin_write_clipped(struct item_bin *ib, struct tile_parameter *param, struct item_bin_sink *out) { struct tile_data tile_data; int i; bbox((struct coord *)(ib+1), ib->clen/2, &tile_data.item_bbox); tile_data.buffer[0]='\0'; tile_data.tile_depth=tile(&tile_data.item_bbox, NULL, tile_data.buffer, param->max, param->overlap, &tile_data.tile_bbox); if (tile_data.tile_depth == param->max || tile_data.tile_depth >= param->min) { item_bin_write_to_sink(ib, out, &tile_data); return; } for (i = 0 ; i < 4 ; i++) { struct rect clip_rect; tile_data.buffer[tile_data.tile_depth]='a'+i; tile_data.buffer[tile_data.tile_depth+1]='\0'; tile_bbox(tile_data.buffer, &clip_rect, param->overlap); if (ib->type < type_area) clip_line(ib, &clip_rect, param, out); else clip_polygon(ib, &clip_rect, param, out); } }
static void clip_primitives (GL_primitive_list *pl, GLcontext *g, GL_float plane[4]) { GLrenderstate *r = g->renderstate; GL_primitive *p = pl->head, *next; pl->head = NULL; pl->tail = NULL; for ( ; p; p = next) { int bits = 0; int cull = 1; int clip = 0; int i; next = p->next; for (i = 0; i < p->nverts; i++) { int c = (vdot(p->verts[i]->position, plane) < 0.0f); cull &= c; clip |= c; bits = (bits << 1) | c; } if (cull) __glcore_destroy_primitive(p); else if (!clip) __glcore_add_primitive(pl, p); else { switch (p->nverts) { case 1: clip_point(pl, g, plane, p, bits); break; case 2: clip_line(pl, g, plane, p, bits); break; case 3: clip_triangle(pl, g, plane, p, bits); break; } } } }
int out_ep(struct Edge *e) { static struct line_pnts *Points = NULL; static struct line_cats *Cats = NULL; if (!Points) { Points = Vect_new_line_struct(); Cats = Vect_new_cats_struct(); } if (!triangulate & plot) clip_line(e); if (!triangulate & !plot) { /* fprintf (stdout,"e %d", e->edgenbr); fprintf (stdout," %d ", e->ep[le] != (struct Site *)NULL ? e->ep[le]->sitenbr : -1); fprintf (stdout,"%d\n", e->ep[re] != (struct Site *)NULL ? e->ep[re]->sitenbr : -1); */ write_ep(e); } return 0; }
bool VoronoiDiagramGenerator::voronoi(int triangulate) { struct Site *newsite, *bot, *top, *temp, *p; struct Site *v; struct Point newintstar; int pm; struct Halfedge *lbnd, *rbnd, *llbnd, *rrbnd, *bisector; struct Edge *e; PQinitialize(); bottomsite = nextone(); out_site(bottomsite); bool retval = ELinitialize(); if(!retval) return false; newsite = nextone(); while(1) { if(!PQempty()) newintstar = PQ_min(); //if the lowest site has a smaller y value than the lowest vector intersection, process the site //otherwise process the vector intersection if (newsite != (struct Site *)NULL && (PQempty() || newsite -> coord.y < newintstar.y || (newsite->coord.y == newintstar.y && newsite->coord.x < newintstar.x))) {/* new site is smallest - this is a site event*/ out_site(newsite); //output the site lbnd = ELleftbnd(&(newsite->coord)); //get the first HalfEdge to the LEFT of the new site rbnd = ELright(lbnd); //get the first HalfEdge to the RIGHT of the new site bot = rightreg(lbnd); //if this halfedge has no edge, , bot = bottom site (whatever that is) e = bisect(bot, newsite); //create a new edge that bisects bisector = HEcreate(e, le); //create a new HalfEdge, setting its ELpm field to 0 ELinsert(lbnd, bisector); //insert this new bisector edge between the left and right vectors in a linked list if ((p = intersect(lbnd, bisector)) != (struct Site *) NULL) //if the new bisector intersects with the left edge, remove the left edge's vertex, and put in the new one { PQdelete(lbnd); PQinsert(lbnd, p, dist(p,newsite)); }; lbnd = bisector; bisector = HEcreate(e, re); //create a new HalfEdge, setting its ELpm field to 1 ELinsert(lbnd, bisector); //insert the new HE to the right of the original bisector earlier in the IF stmt if ((p = intersect(bisector, rbnd)) != (struct Site *) NULL) //if this new bisector intersects with the { PQinsert(bisector, p, dist(p,newsite)); //push the HE into the ordered linked list of vertices }; newsite = nextone(); } else if (!PQempty()) /* intersection is smallest - this is a vector event */ { lbnd = PQextractmin(); //pop the HalfEdge with the lowest vector off the ordered list of vectors llbnd = ELleft(lbnd); //get the HalfEdge to the left of the above HE rbnd = ELright(lbnd); //get the HalfEdge to the right of the above HE rrbnd = ELright(rbnd); //get the HalfEdge to the right of the HE to the right of the lowest HE bot = leftreg(lbnd); //get the Site to the left of the left HE which it bisects top = rightreg(rbnd); //get the Site to the right of the right HE which it bisects out_triple(bot, top, rightreg(lbnd)); //output the triple of sites, stating that a circle goes through them v = lbnd->vertex; //get the vertex that caused this event makevertex(v); //set the vertex number - couldn't do this earlier since we didn't know when it would be processed endpoint(lbnd->ELedge,lbnd->ELpm,v); //set the endpoint of the left HalfEdge to be this vector endpoint(rbnd->ELedge,rbnd->ELpm,v); //set the endpoint of the right HalfEdge to be this vector ELdelete(lbnd); //mark the lowest HE for deletion - can't delete yet because there might be pointers to it in Hash Map PQdelete(rbnd); //remove all vertex events to do with the right HE ELdelete(rbnd); //mark the right HE for deletion - can't delete yet because there might be pointers to it in Hash Map pm = le; //set the pm variable to zero if (bot->coord.y > top->coord.y) //if the site to the left of the event is higher than the Site { //to the right of it, then swap them and set the 'pm' variable to 1 temp = bot; bot = top; top = temp; pm = re; } e = bisect(bot, top); //create an Edge (or line) that is between the two Sites. This creates //the formula of the line, and assigns a line number to it bisector = HEcreate(e, pm); //create a HE from the Edge 'e', and make it point to that edge with its ELedge field ELinsert(llbnd, bisector); //insert the new bisector to the right of the left HE endpoint(e, re-pm, v); //set one endpoint to the new edge to be the vector point 'v'. //If the site to the left of this bisector is higher than the right //Site, then this endpoint is put in position 0; otherwise in pos 1 deref(v); //delete the vector 'v' //if left HE and the new bisector don't intersect, then delete the left HE, and reinsert it if((p = intersect(llbnd, bisector)) != (struct Site *) NULL) { PQdelete(llbnd); PQinsert(llbnd, p, dist(p,bot)); }; //if right HE and the new bisector don't intersect, then reinsert it if ((p = intersect(bisector, rrbnd)) != (struct Site *) NULL) { PQinsert(bisector, p, dist(p,bot)); }; } else break; }; for(lbnd=ELright(ELleftend); lbnd != ELrightend; lbnd=ELright(lbnd)) { e = lbnd -> ELedge; clip_line(e); }; cleanup(); return true; }
/* * Add a point to the curve we're currently drawing. * Should be in between a gr_init() and a gr_end() * expect when iplotting, very bad hack * Differences from old gr_point: * We save points here, instead of in lower levels. * Assume we are in right context * Save points in data space (not screen space). * We pass two points in so we can multiplex plots. * */ void gr_point(struct dvec *dv, double newx, double newy, double oldx, double oldy, int np) { int oldtox, oldtoy; /* value before clipping */ char pointc[2]; int fromx, fromy, tox, toy; int ymin, dummy; DatatoScreen(currentgraph, oldx, oldy, &fromx, &fromy); DatatoScreen(currentgraph, newx, newy, &tox, &toy); /* note: we do not particularly want to clip here */ oldtox = tox; oldtoy = toy; if (!currentgraph->grid.circular) { if (clip_line(&fromx, &fromy, &tox, &toy, currentgraph->viewportxoff, currentgraph->viewportyoff, currentgraph->viewport.width + currentgraph->viewportxoff, currentgraph->viewport.height + currentgraph->viewportyoff)) return; } else { if (clip_to_circle(&fromx, &fromy, &tox, &toy, currentgraph->grid.xaxis.circular.center, currentgraph->grid.yaxis.circular.center, currentgraph->grid.xaxis.circular.radius)) return; } if (currentgraph->plottype != PLOT_POINT) { SetLinestyle(dv->v_linestyle); } else { /* if PLOT_POINT, don't want to plot an endpoint which have been clipped */ if (tox != oldtox || toy != oldtoy) return; } SetColor(dv->v_color); switch (currentgraph->plottype) { double *tics; case PLOT_LIN: case PLOT_MONOLIN: /* If it's a linear plot, ignore first point since we don't want to connect with oldx and oldy. */ if (np) DevDrawLine(fromx, fromy, tox, toy); if ((tics = currentgraph->ticdata) != NULL) { for (; *tics < HUGE; tics++) if (*tics == (double) np) { DevDrawText("x", (int) (tox - currentgraph->fontwidth / 2), (int) (toy - currentgraph->fontheight / 2), 0); /* gr_redraw will redraw this w/o our having to save it Guenther Roehrich 22-Jan-99 */ /* SaveText(currentgraph, "x", (int) (tox - currentgraph->fontwidth / 2), (int) (toy - currentgraph->fontheight / 2)); */ break; } } else if ((currentgraph->ticmarks >0) && (np > 0) && (np % currentgraph->ticmarks == 0)) { /* Draw an 'x' */ DevDrawText("x", (int) (tox - currentgraph->fontwidth / 2), (int) (toy - currentgraph->fontheight / 2), 0); /* gr_redraw will redraw this w/o our having to save it Guenther Roehrich 22-Jan-99 */ /* SaveText(currentgraph, "x", (int) (tox - currentgraph->fontwidth / 2), (int) (toy - currentgraph->fontheight / 2)); */ } break; case PLOT_COMB: DatatoScreen(currentgraph, 0.0, currentgraph->datawindow.ymin, &dummy, &ymin); DevDrawLine(tox, ymin, tox, toy); break; case PLOT_POINT: /* Here, gi_linestyle is the character used for the point. */ pointc[0] = (char) dv->v_linestyle; pointc[1] = '\0'; DevDrawText(pointc, (int) (tox - currentgraph->fontwidth / 2), (int) (toy - currentgraph->fontheight / 2), 0); default: break; } }
void draw_line(float x0, float y0, float x1, float y1) { GLint viewport[4]; int i; float x, y; float dx, dy; float xinc, yinc; float length = 0.; int result; int width, height; Pixel white = { 1, 1, 1 }; /* set the clipping window */ glGetIntegerv(GL_VIEWPORT, viewport); width = abs(viewport[2] - viewport[0]); height = abs(viewport[3] - viewport[1]); set_clip_window(0.0, 0.0, width - 0.51, height - 0.51); /* clip the line in 2D */ result = clip_line(&x0, &y0, &x1, &y1); /* return if line is entirely outside the clip window */ if (result == 0) return; /* incremental line drawing */ dx = x1 - x0; dy = y1 - y0; /* determine whether horizontal or vertical change is larger */ if (fabs(dx) > fabs(dy)) length = fabs(dx); else length = fabs(dy); /* special case to avoid dividing by zero */ if (length == 0) { setPixel(x0, y0, white); return; } xinc = dx / length; yinc = dy / length; x = x0; y = y0; /* write "length" number of pixels along the line */ for (i = 0; i <= length; i++) { if (x < displayImage.width && y < displayImage.height) setPixel(y, x, white); x += xinc; y += yinc; } glFlush(); }
void voronoi(int triangulate, Site * (*nextsite) (void)) { Site *newsite, *bot, *top, *temp, *p; Site *v; Point newintstar = {0}; char pm; Halfedge *lbnd, *rbnd, *llbnd, *rrbnd, *bisector; Edge *e; edgeinit(); siteinit(); PQinitialize(); bottomsite = (*nextsite) (); #ifdef STANDALONE out_site(bottomsite); #endif ELinitialize(); newsite = (*nextsite) (); while (1) { if (!PQempty()) newintstar = PQ_min(); if (newsite != (struct Site *) NULL && (PQempty() || newsite->coord.y < newintstar.y || (newsite->coord.y == newintstar.y && newsite->coord.x < newintstar.x))) { /* new site is smallest */ #ifdef STANDALONE out_site(newsite); #endif lbnd = ELleftbnd(&(newsite->coord)); rbnd = ELright(lbnd); bot = rightreg(lbnd); e = gvbisect(bot, newsite); bisector = HEcreate(e, le); ELinsert(lbnd, bisector); if ((p = hintersect(lbnd, bisector)) != (struct Site *) NULL) { PQdelete(lbnd); PQinsert(lbnd, p, dist(p, newsite)); } lbnd = bisector; bisector = HEcreate(e, re); ELinsert(lbnd, bisector); if ((p = hintersect(bisector, rbnd)) != (struct Site *) NULL) PQinsert(bisector, p, dist(p, newsite)); newsite = (*nextsite) (); } else if (!PQempty()) { /* intersection is smallest */ lbnd = PQextractmin(); llbnd = ELleft(lbnd); rbnd = ELright(lbnd); rrbnd = ELright(rbnd); bot = leftreg(lbnd); top = rightreg(rbnd); #ifdef STANDALONE out_triple(bot, top, rightreg(lbnd)); #endif v = lbnd->vertex; makevertex(v); endpoint(lbnd->ELedge, lbnd->ELpm, v); endpoint(rbnd->ELedge, rbnd->ELpm, v); ELdelete(lbnd); PQdelete(rbnd); ELdelete(rbnd); pm = le; if (bot->coord.y > top->coord.y) { temp = bot; bot = top; top = temp; pm = re; } e = gvbisect(bot, top); bisector = HEcreate(e, pm); ELinsert(llbnd, bisector); endpoint(e, re - pm, v); deref(v); if ((p = hintersect(llbnd, bisector)) != (struct Site *) NULL) { PQdelete(llbnd); PQinsert(llbnd, p, dist(p, bot)); } if ((p = hintersect(bisector, rrbnd)) != (struct Site *) NULL) { PQinsert(bisector, p, dist(p, bot)); } } else break; } for (lbnd = ELright(ELleftend); lbnd != ELrightend; lbnd = ELright(lbnd)) { e = lbnd->ELedge; clip_line(e); #ifdef STANDALONE out_ep(e); #endif } }