// Description: graphics facilities // Revision history: 28/6/99/LY // january 2000 - substantial revision to ensure compatibility with the MapDraw utility #include #include #include #include #include #include #include #include #include #include "graphics.h" #include "dcel.h" #include "decl.h" //using namespace std; OverlayWindow::OverlayWindow(double x, double y, const char* label): GraphWin(x,y,label), d_cel_ptr(0) { set_animation_steps(ANIM_STEPS); set_node_label_font(roman_font, FONT_SIZE); set_node_width(NODE_DIM); set_node_height(NODE_DIM); set_node_border_width(0); set_node_color(leda_grey2); set_node_border_color(leda_grey2); set_node_label_type(no_label); set_edge_width(EDGE_WIDTH); set_edge_color(leda_grey3); set_edge_direction(undirected_edge); set_edge_label_font(roman_font, FONT_SIZE); set_zoom_labels(false); } void OverlayWindow::draw_D_CEL() { get_window().set_show_coordinates(true); if (d_cel_ptr) { draw_D_CEL(*d_cel_ptr, DEFAULT_X_OFFSET, DEFAULT_Y_OFFSET); } } void OverlayWindow::draw_D_CEL(const D_CEL& d_cel, double x, double y) { set_flush(false); d_cel_ptr = const_cast(&d_cel); nodes.resize(d_cel_ptr->vertex_records.size()); // brug for_each i stedet for (VertexList::const_iterator v_iter = d_cel.vertex_records.begin(); v_iter != d_cel.vertex_records.end(); v_iter++) { draw_D_CEL_vertex(*v_iter); } for (HalfEdgeList::const_iterator he_iter = d_cel.half_edge_records.begin(); he_iter != d_cel.half_edge_records.end(); he_iter++) { draw_D_CEL_half_edge(he_iter->second); } for (FaceList::const_iterator f_iter = d_cel.face_records.begin(); f_iter != d_cel.face_records.end(); f_iter++) { draw_D_CEL_face(*f_iter); } //cout << "Number of faces: " << d_cel.face_records.size() << endl; set_flush(true); redraw(); } inline void OverlayWindow::draw_D_CEL_vertex(Vertex* v_ptr) { nodes[v_ptr->vertex % d_cel_ptr->vertex_records.size()] = new_node(leda_point(calc_x(v_ptr->coordinates.first), calc_y(v_ptr->coordinates.second))); } inline void OverlayWindow::draw_D_CEL_half_edge(HalfEdge* he_ptr) { long source_index = he_ptr->origin->vertex % d_cel_ptr->vertex_records.size(); long target_index = he_ptr->next->origin->vertex % d_cel_ptr->vertex_records.size(); if (source_index < target_index) // draw only one of the half-edges for representing each full edge { new_edge(nodes[source_index],nodes[target_index]); } leda_point mid1 = leda_point(calc_x(he_ptr->origin->coordinates.first), calc_y(he_ptr->origin->coordinates.second)); leda_point mid2 = leda_point(calc_x(he_ptr->prev->origin->coordinates.first), calc_y(he_ptr->prev->origin->coordinates.second)); leda_point mid3 = midpoint(mid1,mid2); // cout << he_ptr->origin->vertex << "," << he_ptr->next->origin->vertex << " "; // get_window().draw_arrow(mid1, mid2); // wait(); } inline void OverlayWindow::draw_D_CEL_face(Face* f_ptr) { HalfEdge* hePtr = f_ptr->outer_component; HalfEdge* leftmost_hePtr = hePtr; leda_point middle; if (hePtr != 0) { middle = leda_point(get_xmax(),0); leda_point candidate_middle; long source_index, target_index, leftmost_source_index, leftmost_target_index; do { source_index = hePtr->origin->vertex % d_cel_ptr->vertex_records.size(); target_index = hePtr->twin->origin->vertex % d_cel_ptr->vertex_records.size(); candidate_middle = midpoint(get_position(nodes[source_index]), get_position(nodes[target_index])); if (candidate_middle.xcoord() < middle.xcoord()) { middle = candidate_middle; leftmost_source_index = source_index; leftmost_target_index = target_index; } hePtr = hePtr->next; } while (hePtr != f_ptr->outer_component); if (leftmost_source_index >= leftmost_target_index) { swap(leftmost_source_index, leftmost_target_index); } leda_list le = get_graph().adj_edges(nodes[leftmost_source_index]); leda_edge e; forall(e,le) { if (target(e) == nodes[leftmost_target_index]) { break; } } set_label_type(e, user_label); set_user_label(e, f_ptr->face.c_str()); set_label_pos(e, central_pos); } // leda_edge e = new_edge(nodes[source_index], nodes[target_index]); // get_window().draw_text(calc_x(center_x), calc_y(center_y), f_ptr->face.c_str()); } inline double OverlayWindow::calc_x(double x) { return x + DEFAULT_X_OFFSET; } // calc_y puts the origo of the graphics coordinate system in the upper left corner rather than in the // lower left as is the LEDA drawing window default inline double OverlayWindow::calc_y(double y) { return get_ymax() - y - DEFAULT_Y_OFFSET; }