void getFlights(Graph g, int * dfsOrdered){ int nDiffCountries = 1; int nFlights = 0; int currCountry = 0; while (nDiffCountries < numV(g)){ Edge nextFlight = getNextFlight(g, dfsOrdered, &nDiffCountries, currCountry); nFlights++; printf("Flight %d %s %s\n", nFlights, getVertexLabel(g,nextFlight.v), getVertexLabel(g,nextFlight.w)); currCountry = nextFlight.w; } }
void pigalePaint::DrawText(QPainter *p,Tpoint &a,tvertex v,int col,int center) // draw text centered at a, with a surrounding rectangle // center=1 center // center=0 horizontal {QString t = getVertexLabel(GCP,v); QPen pn = p->pen();pn.setWidth(1);pn.setColor(color[Black]);p->setPen(pn); QSize size = QFontMetrics(p->font()).size(Qt::AlignCenter,t); double nx = size.width() + 4; double ny = size.height(); if(t.length() == 0)nx = ny= 8; QRect rect; //if pn.setWidth() > 1 => rect increase if(center) rect = QRect((int)(to_x(a.x())-nx/2+.5),(int)(to_y(a.y())-ny/2+.5),(int)(nx+.5),(int)(ny+.5)); else rect = QRect((int)(to_x(a.x())-nx/2+.5),(int)(to_y(a.y())-ny+1.),(int)(nx+.5),(int)(ny+.5)); QBrush pb = p->brush(); pb.setStyle(Qt::SolidPattern); pb.setColor(color[bound(col,0,16)]); //pb.setColor(color[White]); p->setBrush(pb); //pn.setColor(color[col]);pn.setWidth(1);p->setPen(pn); pn.setWidth(1);pn.setColor(color[Black]);p->setPen(pn); p->drawRect(rect); if(ny < 6)return; p->drawText(rect,Qt::AlignCenter,t); }
void pigalePaint::DrawText(QPainter *p,double x,double y,double nx,double ny,tvertex v,int col) // draw centered text in rectangle left at x,y of size: nx,ny {QPen pn = p->pen();pn.setColor(color[Black]); nx *= xscale; ny *= yscale; QRect rect = QRect(to_x(x),to_y(y),(int)(nx+.5),(int)(ny+.5)); QBrush pb = p->brush();pb.setStyle(Qt::SolidPattern); pb.setColor(color[bound(col,1,16)]);p->setBrush(pb); pn.setWidth(1);p->setPen(pn); p->drawRect(rect); pn.setWidth(1);p->setPen(pn); QString t = getVertexLabel(GCP,v); p->drawText(rect,Qt::AlignCenter,t); }
void GraphEditor::mousePressEvent(QMouseEvent* e) {GeometricGraph & G = *(gwp->pGG); QPoint p((int)e->pos().x(),(int)e->pos().y()); setFocus(); // as we might loose the focus ColorItem *coloritem; if(FindItem(p,coloritem) != 0) {if(e->button() == Qt::LeftButton) {if(coloritem->node) {gwp->NodeColorItem[color_node]->SetPenColor(White); coloritem->SetPenColor(coloritem->brush_color); color_node = coloritem->brush_color; G.vcolor.definit(color_node); } else {gwp->EdgeColorItem[color_edge]->SetPenColor(White); coloritem->SetPenColor(coloritem->brush_color); color_edge = coloritem->brush_color; G.ecolor.definit(color_edge); } return; } else if(e->button() == Qt::RightButton) {QString t; if(coloritem->node) t.sprintf("Vertex color:%s",ColorName[coloritem->brush_color]); else t.sprintf("Edge color:%s",ColorName[coloritem->brush_color]); gwp->info_item = CreateInfoItem(gwp,t,p); setCursor(QCursor(Qt::WhatsThisCursor)); return; } } ThickItem *thickitem; if(FindItem(p,thickitem) != 0) {if(e->button() == Qt::LeftButton) {gwp->EdgeThickItem[width_edge]->SetBrushColor(White); thickitem->SetBrushColor(Yellow); width_edge = thickitem->width; G.ewidth.definit(width_edge); return; } else if(e->button() == Qt::RightButton) {QString t; t.sprintf("Edge width:%d",thickitem->width); gwp->info_item = CreateInfoItem(gwp,t,p); setCursor(QCursor(Qt::WhatsThisCursor)); return; } } if(e->button() == Qt::RightButton ) {NodeItem* node; EdgeItem *edge; QString t; int rtt = FindItem(p,node,edge); if(rtt == 0)rtt = FindItem(p,edge);//augment the collision zone if(rtt == node_rtti) if (G.Set().exist(PROP_VSLABEL) && G.Set(tvertex()).exist(PROP_SLABEL)) {QString tt; Prop1<svector<tstring *> >vslabel(G.Set(),PROP_VSLABEL); Prop<int> slabel(G.Set(tvertex()),PROP_SLABEL,0); if (vslabel()[slabel[node->v]]==(tstring *)0) tt="(null)"; else tt=~(*(vslabel()[slabel[node->v]])); t.sprintf("vertex:%d Label:%d (%s)",(node->v)(),G.vlabel[node->v],(const char *)tt.toLatin1()); } else t.sprintf("vertex:%d Label:%d",(node->v)(),G.vlabel[node->v]); else if(rtt == edge_rtti) {double d = Distance(G.vcoord[G.vin[edge->e]],G.vcoord[G.vin[-(edge->e)]])+.5; t.sprintf("edge:%d Label:%d len:%d",(edge->e)(),G.elabel[edge->e],(int)d); } else {t.sprintf("(%d,%d)",(int)e->pos().x(),(int)e->pos().y()); setCursor(QCursor(Qt::BlankCursor)); } gwp->info_item = CreateInfoItem(gwp,t,p); return; } //GetMouseAction_1 returns the active radio button (0,5) int MouseAction = GetMouseAction_1(); bool Shift = e->modifiers() == Qt::ShiftModifier; bool Control = e->modifiers() == Qt::ControlModifier; bool SControl = e->modifiers() == (Qt::ShiftModifier | Qt::ControlModifier); if(e->button() == Qt::MidButton) //move MouseAction = (Shift) ? -3 : 3; else if(Shift && MouseAction == 1) //add MouseAction = -1; // delete vertex or edge else if(Control && MouseAction == 1) MouseAction = 10; //duplicate graph else if(SControl && MouseAction == 1) MouseAction = 11; //duplicate + else if(Shift && MouseAction == 2) //Orient or reorient if oriented MouseAction = -2; //disorient else if(Shift && MouseAction == 3) //move vertices MouseAction = -3; //move colored vertices else if(Shift && MouseAction == 4) //bissect MouseAction = -4; //contract else if(Shift && MouseAction == 5) //define exterior face MouseAction = -5; //define extbrin else if(Shift && MouseAction == 6) //define a label MouseAction = -6; //reset all labels to indices if(MouseAction == 0) // color {NodeItem* node; EdgeItem *edge; int rtt = FindItem(p,node,edge); if(rtt == 0) //augment the collision zone {rtt = FindItem(p,edge); if(rtt == 0)return; } if(rtt == node_rtti) {mywindow->UndoTouch(false); G.vcolor[node->v] = color_node; node->SetColor(color[color_node]); } else if(rtt == edge_rtti) {mywindow->UndoTouch(false); G.ecolor[edge->e] = color_edge; G.ewidth[edge->e] = width_edge; if(edge->lower) edge->SetColor(color[color_edge]); else edge->opp->SetColor(color[color_edge]); } return; } else if(MouseAction == 1) // Start create an edge {mywindow->UndoTouch(false); Prop<NodeItem *> nodeitem(G.Set(tvertex()),PROP_CANVAS_ITEM); NodeItem* node; EdgeItem *edge; tvertex v; int h = (int)gwp->canvas->height(); int rtt = FindItem(p,node,edge); if(rtt != node_rtti)// add a vertex {Tpoint pp((double)p.x(),(double)(h - p.y())); v = G.NewVertex(pp); ToGrid(v); nodeitem[v] = node = CreateNodeItem(v,gwp); mywindow->mouse_actions->ButtonUndoGrid->setDisabled(true); } else v = node->v; start_position = QPoint((int)G.vcoord[v].x(),h-(int)G.vcoord[v].y()); node->SetColor(Qt::red); gwp->curs_item = new CursItem(v,start_position,gwp); } else if(MouseAction == -1) // Delete {NodeItem* node; EdgeItem *edge; int rtt = FindItem(p,node,edge); if(rtt == 0) //augment the collision zone {rtt = FindItem(p,edge); if(rtt == 0)return; } if(rtt == node_rtti) {mywindow->UndoTouch(true); G.DeleteVertex(node->v); mywindow->mouse_actions->ButtonUndoGrid->setDisabled(true); } else {mywindow->UndoTouch(true); G.DeleteEdge(edge->e); } load(false); mywindow->information();// Informations PrintSizeGrid(); return; } else if(MouseAction == 3) // Start moving a vertex {NodeItem* node; EdgeItem *edge; int rtt = FindItem(p,node,edge); if(rtt != node_rtti)return; mywindow->UndoTouch(false); gwp->moving_item = node; start_position = p; return; } else if(MouseAction == -3) // Start moving a subgraph {mywindow->UndoTouch(false); gwp->moving_subgraph = true; start_position = p; return; } else if(MouseAction == 4) // Bissect an edge {mywindow->UndoTouch(true); if(FitToGrid)//and we are sure that ButtonFitGrid exists mywindow->mouse_actions->ButtonFitGrid->setChecked(false); mywindow->mouse_actions->ButtonUndoGrid->setDisabled(true); EdgeItem *edge; int rtt = FindItem(p,edge); if(rtt != edge_rtti)return; G.BissectEdge(edge->e); DoNormalise = false; load(true); DoNormalise = true; mywindow->information();// Informations return; } else if(MouseAction == -4) // Contract an edge {EdgeItem *edge; int rtt = FindItem(p,edge); if(rtt != edge_rtti)return; mywindow->UndoTouch(true); // provisoire if(edge->lower)G.ReverseEdge(edge->e); // end provisoire G.ContractEdge(edge->e); load(false); mywindow->information();// Informations return; } else if(MouseAction == 5) // Color Exterior face {GeometricGraph & G = *(gwp->pGG); Prop<EdgeItem *> edgeitem(G.Set(tedge()),PROP_CANVAS_ITEM); Tpoint pp((double)p.x(),(double)(gwp->canvas->height()-p.y())); if(G.FindExteriorFace(pp) == 0)return; //ColorExteriorface tedge e; ForAllEdges(e,G)edgeitem[e]->SetColor(color[color_edge]); tbrin b0 = G.extbrin(); tbrin b = b0; do {e = b.GetEdge(); edgeitem[e]->SetColor(color[Red]); } while((b = G.cir[-b]) != b0); if(b0() > 0) edgeitem[b0.GetEdge()]->SetColor(color[Green],false); else edgeitem[b0.GetEdge()]->opp->SetColor(color[Green],false); return; } else if(MouseAction == -5) // Define Extbrin {EdgeItem *edge; int rtt = FindItem(p,edge); if(rtt != edge_rtti)return; Prop<EdgeItem *> edgeitem(G.Set(tedge()),PROP_CANVAS_ITEM); tedge je; ForAllEdges(je,G)edgeitem[je]->SetColor(color[color_edge]); GeometricGraph & G = *(gwp->pGG); je = edge->e; // Prop<NodeItem *> nodeitem(G.Set(tvertex()),PROP_CANVAS_ITEM); // NodeItem *n1 = nodeitem[G.vin[je]]; Tpoint p1(n1->x(),n1->y()); // NodeItem *n2 = nodeitem[G.vin[-je]]; Tpoint p2(n2->x(),n2->y()); // Tpoint pp((double)p.x(),(double)p.y()); // G.extbrin() = (Distance2(pp,p1) < Distance2(pp,p2)) ? je.firsttbrin() : je.secondtbrin(); G.extbrin() = (edge->lower ) ? je.firsttbrin() : je.secondtbrin(); edge->SetColor(color[Green],false); return; } else if(MouseAction == 6) // Modify label {NodeItem* node; EdgeItem *edge; int rtt = FindItem(p,node,edge); if(rtt != node_rtti)return; tvertex v = node->v; bool ok; //int res = QInputDialog::getInteger(this,"Pigale","Enter a number:",(int)G.vlabel[node->v],0,2147483647,1,&ok); int res = QInputDialog::getInt(this,"Pigale","Enter a number:",(int)G.vlabel[node->v],0,2147483647,1,&ok); if(!ok)return; G.vlabel[node->v] = res; QString t = getVertexLabel(G.Container(),v); node->SetText(t); return; } else if(MouseAction == -6) // Reset all labels {Prop<NodeItem *> nodeitem(G.Set(tvertex()),PROP_CANVAS_ITEM); for(tvertex v = 1; v <= G.nv();v++) {G.vlabel[v] = v(); nodeitem[v]->SetText(QString("%1").arg(v())); } for(tedge e = 1; e <= G.ne();e++) G.elabel[e] = e(); } else if(MouseAction == 2 || MouseAction == -2) // Orient/Reverse or deorient {Prop<bool> eoriented(G.Set(tedge()),PROP_ORIENTED,false); Prop<bool> reoriented(G.Set(tedge()),PROP_REORIENTED); Prop<EdgeItem *> edgeitem(G.Set(tedge()),PROP_CANVAS_ITEM); mywindow->setShowOrientation(true); EdgeItem *edge; int rtt = FindItem(p,edge); if(rtt != edge_rtti)return; mywindow->UndoTouch(true); if(MouseAction == 2) {if(eoriented[edge->e]) {G.ReverseEdge(edge->e); eoriented[edge->e] = true; reoriented[edge->e] = false; edgeitem[edge->e] = CreateEdgeItem(edge->e,gwp); if(edge->arrow) scene()->removeItem(edge->arrow); else scene()->removeItem(edge->opp->arrow); scene()->removeItem(edge->opp);scene()->removeItem(edge); mywindow->information();// Informations return; } else {eoriented[edge->e] = true; if(edge->lower) {G.ReverseEdge(edge->e);reoriented[edge->e] = false;} edgeitem[edge->e] = CreateEdgeItem(edge->e,gwp); if(edge->arrow) scene()->removeItem(edge->arrow); else scene()->removeItem(edge->opp->arrow); scene()->removeItem(edge->opp);scene()->removeItem(edge); mywindow->information();// Informations return; } } else {eoriented[edge->e] = false; edgeitem[edge->e] = CreateEdgeItem(edge->e,gwp); if(edge->arrow) scene()->removeItem(edge->arrow); else scene()->removeItem(edge->opp->arrow); scene()->removeItem(edge->opp);scene()->removeItem(edge); mywindow->information();// Informations return; } } else if(MouseAction == 10)// Duplicate the sugraph of the current color {mywindow->UndoTouch(true); if(FitToGrid)//and we are sure that ButtonFitGrid exists mywindow->mouse_actions->ButtonFitGrid->setChecked(false); mywindow->mouse_actions->ButtonUndoGrid->setDisabled(true); short vcol=0; G.vcolor.getinit(vcol); G.vcolor.definit((short)((vcol+1)%16)); GeometricGraph & G = *(gwp->pGG); Tpoint translate(this->width()/2.,0); int n = G.nv(); svector<tvertex> newvertex(1,n); tvertex v; for(v = 1; v <= n;v++)//translate all the graph G.vcoord[v] /= 2.; for(v = 1; v <= n;v++) {if(G.vcolor[v] != vcol)continue; newvertex[v] = G.NewVertex(G.vcoord[v] + translate); } int m = G.ne(); tvertex v1,v2; for(tedge e = 1; e <= m;e++) {v1 = G.vin[e];v2 = G.vin[-e]; if(G.vcolor[v1] == vcol && G.vcolor[v2] == vcol) G.NewEdge(newvertex[v1],newvertex[v2]); } load(true); mywindow->information();// Informations } else if(MouseAction == 11) //Duplicate the sugraph of the current color // and add edges between a new vertex and its father {mywindow->UndoTouch(true); if(FitToGrid)//and we are sure that ButtonFitGrid exists mywindow->mouse_actions->ButtonFitGrid->setChecked(false); mywindow->mouse_actions->ButtonUndoGrid->setDisabled(true); mywindow->mouse_actions->ButtonFitGrid->setChecked(false); short vcol=0; G.vcolor.getinit(vcol); G.vcolor.definit((short)((vcol+1)%16)); GeometricGraph & G = *(gwp->pGG); Tpoint translate(this->width()/2.,0); int n = G.nv(); svector<tvertex> newvertex(1,n); tvertex v; for(v = 1; v <= n;v++)//translate all the graph G.vcoord[v] /= 2.; for(v = 1; v <= n;v++) {if(G.vcolor[v] != vcol)continue; newvertex[v] = G.NewVertex(G.vcoord[v] + translate); } int m = G.ne(); tvertex v1,v2; for(tedge e = 1; e <= m;e++) {v1 = G.vin[e];v2 = G.vin[-e]; if(G.vcolor[v1] == vcol && G.vcolor[v2] == vcol) G.NewEdge(newvertex[v1],newvertex[v2]); } for(v = 1; v <= n;v++) {if(G.vcolor[v] != vcol)continue; G.NewEdge(v,newvertex[v]); } load(true); mywindow->information();// Informations } }
void DrawBipContact(QPainter *p,pigalePaint *paint) {GraphContainer GC = paint->GCP; GeometricGraph G(paint->GCP); Prop<int> h(G.Set(tvertex()),PROP_DRAW_INT_1); Prop<int> h1(G.Set(tvertex()),PROP_DRAW_INT_2); Prop<int> h2(G.Set(tvertex()),PROP_DRAW_INT_3); Prop1<Tpoint> pmax(G.Set(),PROP_POINT_MAX); Prop1<Tpoint> pmin(G.Set(),PROP_POINT_MIN); QPen pn = p->pen();pn.setWidth(1); QBrush pb = p->brush(); pb.setStyle(Qt::SolidPattern); QPoint ps,pt,ps2,pt2; // Drawing the diagonal ps = QPoint(paint->to_x(pmin().x()),paint->to_y(pmin().y())); pt = QPoint(paint->to_x(pmax().x()),paint->to_y(pmax().y())); pn.setColor(color[Grey1]); p->setPen(pn); p->drawLine(ps,pt); // Drawing the vertices: horizontal and vertical segments for(tvertex v = 1;v <= G.nv();v++) {double delta = (h1[v] < h[v])?.45:-.45; pn.setColor(color[G.vcolor[v]]); pn.setWidth(1);p->setPen(pn); if(G.vcolor[v] == Red)//horizontales {ps = QPoint(paint->to_x(h1[v]),paint->to_y(h[v])); pt = QPoint(paint->to_x(h2[v]),paint->to_y(h[v])); if(h2[v] > h[v] && h1[v] > h[v]) {ps2 = QPoint(paint->to_x(h[v]),paint->to_y(h[v])); p->drawLine(ps2,pt); } else if(h2[v] < h[v] && h1[v] < h[v]) {pt2 = QPoint(paint->to_x(h[v]),paint->to_y(h[v])); p->drawLine(ps,pt2); } if(h1[v] == h2[v])// isthme {ps = QPoint(paint->to_x(h1[v]),paint->to_y(h[v])); pt = QPoint(paint->to_x(h2[v]+delta),paint->to_y(h[v])); } pn.setWidth(2);p->setPen(pn); p->drawLine(ps,pt); } else // verticales {ps = QPoint(paint->to_x(h[v]),paint->to_y(h1[v])); pt = QPoint(paint->to_x(h[v]),paint->to_y(h2[v])); if(h2[v] > h[v] && h1[v] > h[v]) {ps2 = QPoint(paint->to_x(h[v]),paint->to_y(h[v])); p->drawLine(ps2,pt); } else if(h2[v] < h[v] && h1[v] < h[v]) {pt2 = QPoint(paint->to_x(h[v]),paint->to_y(h[v])); p->drawLine(ps,pt2); } if(h1[v] == h2[v])// isthme {ps = QPoint(paint->to_x(h[v]),paint->to_y(h1[v])); pt = QPoint(paint->to_x(h[v]),paint->to_y(h2[v]+delta)); } pn.setWidth(2);p->setPen(pn); p->drawLine(ps,pt); } } //drawing labels int dy = Min(12,paint->height()/(pmax().y()+1)-2); QFont font = QFont("sans",dy); p->setFont(font); pb.setColor(color[White]); p->setBrush(pb); pn.setWidth(1); for(tvertex v = 1;v <= G.nv();v++) //trace des labels {double delta = (h1[v] < h[v])?.9:-.9; if(G.vcolor[v] == Red) {if(h1[v] != h2[v]) {ps = QPoint(paint->to_x(h1[v]),paint->to_y(h[v])); pt = QPoint(paint->to_x(h2[v]),paint->to_y(h[v])); } else {ps = QPoint(paint->to_x(h1[v]),paint->to_y(h[v])); pt = QPoint(paint->to_x(h2[v]+delta),paint->to_y(h[v])); } } else {if(h1[v] != h2[v]) {ps = QPoint(paint->to_x(h[v]),paint->to_y(h1[v])); pt = QPoint(paint->to_x(h[v]),paint->to_y(h2[v])); } else {ps = QPoint(paint->to_x(h[v]),paint->to_y(h1[v])); pt = QPoint(paint->to_x(h[v]),paint->to_y(h2[v]+delta)); } } QString t = getVertexLabel(GC,v); QSize size = QFontMetrics(font).size(Qt::AlignCenter,t); int dx =size.width() + 2; dy =size.height() + 2; if(t.length() == 0)dx = dy= 8; QRect rect = QRect((ps.x() + pt.x() - dx)/2,(ps.y() + pt.y() - dy)/2,dx,dy); pn.setColor(color[G.vcolor[v]]);p->setPen(pn); p->drawRect(rect); pn.setColor(color[Black]);p->setPen(pn); p->drawText(rect,Qt::AlignCenter,t); } }
void DrawBip2Pages(QPainter *p,pigalePaint *paint) {GraphContainer GC = paint->GCP; GeometricGraph G(paint->GCP); Prop<int> h(G.Set(tvertex()),PROP_DRAW_INT_1); Prop<int> h1(G.Set(tvertex()),PROP_DRAW_INT_2); Prop<int> h2(G.Set(tvertex()),PROP_DRAW_INT_3); Prop1<Tpoint> pmax(G.Set(),PROP_POINT_MAX); Prop1<Tpoint> pmin(G.Set(),PROP_POINT_MIN); QPen pn = p->pen();pn.setWidth(1); QPoint ps,pt,ps2,pt2; // horizontale int yh = pmin().y()+ pmax().y()/2; ps = QPoint(paint->to_x(pmin().x()),paint->to_y(yh)); pt = QPoint(paint->to_x(pmax().x()),paint->to_y(yh)); pn.setWidth(1);pn.setColor(color[Grey1]); p->setPen(pn); p->drawLine(ps,pt); pn.setColor(color[Black]); pn.setWidth(1);p->setPen(pn); // draw edges: 2 segments double x1,x2,dh; tvertex vmin,vmax; for(tedge e = 1; e < G.ne();e++) {tvertex v1 = G.vin[e]; tvertex v2 = G.vin[-e]; if(h[v1] <h[v2]) {vmin = v1;vmax = v2;} else {vmin = v2;vmax = v1;} x1 = (double)Min(h[v1],h[v2]); x2 = (double)Max(h[v1],h[v2]); dh = Min((x2-x1)*paint->xscale,(x2-x1)*paint->yscale)/2; QRect r = QRect(paint->to_x(x1),paint->to_y(yh)-dh/2,(int)((x2-x1)*paint->xscale),(int)dh); if(G.vcolor[vmax] == Red) p->drawArc(r,0,180*16); else p->drawArc(r,0,-180*16); } // Draw verticces QBrush pb = p->brush(); pb.setStyle(Qt::SolidPattern); pb.setColor(color[White]); p->setBrush(pb); int dy = Min(10,paint->height()/(pmax().y()+1)-2); QFont font = QFont("sans",dy); p->setFont(font); pn.setWidth(1); for(tvertex v = 1;v <= G.nv();v++) {ps = QPoint(paint->to_x(h[v]),paint->to_y(yh)); QString t = getVertexLabel(GC,v); QSize size = QFontMetrics(font).size(Qt::AlignCenter,t); int dx =size.width() + 2; dy =size.height();// + 2; if(t.length() == 0)dx = dy= 8; QRect rect = QRect(ps.x()-dx/2 ,ps.y()-dy/2,dx,dy); pn.setColor(color[G.vcolor[v]]);p->setPen(pn); p->drawRect(rect); pn.setColor(color[Black]);p->setPen(pn); p->drawText(rect,Qt::AlignCenter,t); } }