// Description: data input functions // Revision history: 7/8/99/LY // 14/8/99/LY #include #include #include #include #include #include #include #include "decl.h" #include "graphics.h" namespace Input { using namespace std; InputVertices* ivPtr; InputEdges* iePtr; InputFaces* ifPtr; } // function reads D-CEL input data from file named file_name, formats it appropriately // and stores it in the three containers referenced by arguments InputVertices, InputEdges and InputFaces bool read_dcel_data(InputVertices& v, InputEdges& e, InputFaces& f, string file_name) { ifstream input_file(file_name.c_str()); if (!input_file) { return false; } // read set of vertex coordinate data on the form: x1,y1 x2,y2 ... xn,yn and terminated by -1 ( // negative coordinate values are disallowed). string x_s,y_s; double x,y; while (input_file >> x_s >> y_s) { x = atof(x_s.c_str()); if (x == -1) { break; } y = atof(y_s.c_str()); v.push_back(Coordinates(x,y)); } // skip whitespace till beginning of next block of data which should be a list of integers denoting a cycle of vertices // (indexed by their order of input). // The block of data should be terminated by -1, and the value immediately after that should either // be the beginning of a new block of cycle data or another -1 value to indicate the end of all boundary // cycle input. Example: 0,1,2,3,4,0,-1,0,4,3,2,1,0,-1,-1 (two cycles) input_file >> skipws; InputEdge ie; string c_s; long cycle_node; while (input_file >> c_s) { cycle_node = atol(c_s.c_str()); if (cycle_node == -1) { break; } ie.clear(); do { cycle_node = atol(c_s.c_str()); if (cycle_node == -1) { break; } ie.push_back(cycle_node); } while (input_file >> c_s); e.push_back(ie); } // skip whitespace and start reading face input information. // Format should be as follows: first item is a half-edge on the outer boundary of the face, denoted // by its endpoints. Second item is a list of half-edges, one from the boundary of each inner component // of the face; the list is terminated by -1. If another -1 follows immediately after that first -1, then all // face information has been processed. Example: 0,1,0,1,-1,1,0,6,4,-1,4,6,-1,-1 input_file >> skipws; InputFace iface; string f_s; long he; while (input_file >> f_s) { he = atol(f_s.c_str()); if (he == -1) { break; } iface.clear(); do { he = atol(f_s.c_str()); if (he == -1) { break; } iface.push_back(he); } while (input_file >> f_s); f.push_back(iface); } return true; } // function reads data from window ow by retrieving mouse pointer coordinates each time the left mouse button is // clicked. Each set of coordinates is stored in v, and drawn in ow as a vertex. Successive vertex entries are // connected by edges whose endpoints are stored in e to make up the cycles that form the boundaries of the D-CEL. // Right clicking the mouse ends the cycle in progress, and connects the last mouse pointer position to the first, // thus completing the cycle. // The cycle demarcates a face, and a half-edge (or rather, its endpoints) are inserted into an InputFace which // is then stored in f. Next, the user is prompted for the number of face containing the newly entered cycle so // that the InputFace entry in f for that face can be updated with its new inner component. bool read_dcel_data_from_mouse(InputVertices& v, InputEdges& e, InputFaces& f) { /* Input::ivPtr = &v; Input::iePtr = &e; Input::ifPtr = &f; OverlayWindow ow; ow.init(); ow.set_show_coordinates(true); ow.display(); // ow.set_redraw(redraw_window); double x1,y1,x2,y2,x_first,y_first; Coordinates leftmost_coordinates; // for positioning face text label char itoa_buf[std::numeric_limits::digits10]; InputEdge cycle, twin_cycle; InputFace face; int face_input; long v_count = 0, f_count = 1; // counters to keep track of current vertex and face numbers face.push_back(0); face.push_back(1); f.push_back(face); // insert entry for unbounded face do { if (ow.read_mouse(x1,y1) == MOUSE_BUTTON(3)) { break; } // end on double-click of rightmost mouse button x_first = x1; y_first = y1; v.push_back(Coordinates(x1,y1)); leftmost_coordinates = Coordinates(x1,y1); cycle.clear(); cycle.push_back(f_count); // first entry in cycle should be the face to which the cycle edges are incident // while rightmost button on the mouse hasn't been pressed while (ow.read_mouse_seg(x1,y1,x2,y2) != MOUSE_BUTTON(3)) { leftmost_coordinates = leftmost_coordinates.first < x2 ? leftmost_coordinates : Coordinates(x2,y2); v.push_back(Coordinates(x2,y2)); cycle.push_back(v_count++); ow.draw_node(x1,y1); ow.draw_edge(x1,y1,x2,y2); x1 = x2; y1 = y2; } cycle.push_back(v_count++); ow.draw_node(x1,y1); ow.draw_arrow(x1,y1,x_first,y_first); ow.draw_text(leftmost_coordinates.first + ow.get_node_width()*2, leftmost_coordinates.second + ow.get_node_width()*2, itoa(f_count++, itoa_buf, 10)); cycle.push_back(cycle[1]); // last vertex of cycle should == first vertex of cycle e.push_back(cycle); face.clear(); face.push_back(cycle[1]); // insert endpoints of half-edge on outer boundary of newly created face face.push_back(cycle[2]); f.push_back(face); face_input = ow.read_int("Input number of the face containing this cycle (0 if the unbounded face)"); twin_cycle.clear(); twin_cycle.push_back(face_input); reverse_copy(cycle.begin()+1, cycle.end(), inserter(twin_cycle, twin_cycle.begin()+1)); e.push_back(twin_cycle); f[face_input].push_back(twin_cycle[1]); // add inner component to face entered by user (input assumed valid) f[face_input].push_back(twin_cycle[2]); } while (true); */ return true; }