📄 graph.c
字号:
if ( type == FIXED_NODE ) { nfixnode++; currnode -> SetSerNum( -nfixnode ); } else { nmovnode++; currnode -> SetSerNum( nmovnode ); } return TRUE;}/*------------------------ SearchNode --------------------*//* Searches node by name *//* IN : searched name *//* OUT : is there node having this name ? *//* SIDE EFFECT: currnode is set to the found node. *//*------------------------------------------------------------*/BOOL Graph :: SearchNode ( pchar name ){ if ( !FirstNode() ) return FALSE; do { if ( strcmp( currnode -> GetName(), name) == 0 ) return TRUE; } while ( NextNode () ); return FALSE;}/*------------------------ RelSearchNode --------------------*//* Searches relate node by name *//* IN : picked position *//* OUT : is there node in the pick aperture ? *//* SIDE EFFECT: *//* To ensure that relatenode has greater serial number than *//* currnode: *//* IF found node has smaller serial number than currnode*//* relatenode is set to currnode *//* currnode is set to the found node *//* ELSE *//* relatenode is set to the found node. *//* Initializes currelation to the relation of currnode and *//* relatenode. *//*--------------------------------------------------------------*/BOOL Graph :: RelSearchNode ( pchar name ){ NodeElem * oldcurrnode = currnode; BOOL found = SearchNode( name ); if ( found ) { relatenode = currnode; currnode = oldcurrnode; SwapRelation( ); SearchRelation( ); } else { currelation = NULL; currnode = oldcurrnode; } return found;}/*------------------ SearchRelation ----------------------------*//* Search for a relation between currnode and relatenode. *//* If this relation doesnot exist currelation is NULL and *//* prevrelation points to the end of the relation list of *//* currnode. *//* IN : - *//* OUT : EMPTY_LIST - No relation list *//* FIRST_FOUND - The first relation node found *//* FOUND - Not the first node found *//* NOT_FOUND - No such relation *//* SIDE EFFECT: currelation= searched relation or NULL *//* prevrelation= the previous relation or the last *//* node of the relation list or NULL *//* if no node at all *//*--------------------------------------------------------------*/int Graph :: SearchRelation ( ){ currelation = currnode -> GetRelation( ); prevrelation = currnode -> GetRelation( ); if (currelation == NULL) return EMPTY_LIST; if (currelation -> GetOtherNode() == relatenode) return FIRST_FOUND; currelation = prevrelation -> GetNext(); for ( ; ; ) { if (currelation == NULL) return NOT_FOUND; if (currelation -> GetOtherNode() == relatenode) return FOUND; prevrelation = currelation; currelation = prevrelation -> GetNext(); }}/*------------------------ SwapRelation --------------------*//* To ensure that relatenode has greater serial number than *//* currnode: *//* IF relatenode node has smaller serial number than *//* relatenode and currnode are swapped *//* IN : - *//* OUT : - *//*--------------------------------------------------------------*/void Graph :: SwapRelation ( ){ NodeElem * tmpnode; if ( currnode == NULL || relatenode == NULL ) return; if ( currnode -> GetSerNum() > relatenode -> GetSerNum() ) { tmpnode = currnode; currnode = relatenode; relatenode = tmpnode; }}/*--------------------- AddRelation ----------------------------*//* Adds new or changes the parameters of an existing relation. *//* If this is a new relation RelationNode is allocated and *//* placed on the end of relation list of currnode. *//* The parameters are set according to the explicit parameters *//* and the implicit relatenode par. *//* IN : name,intensity, type *//* OUT : - *//* SIDE EFFECT: currelation= new or changed relation *//*--------------------------------------------------------------*/void Graph :: AddRelation ( pchar name, double rel ){/** CHECK IF THIS RELATION EXISTS OR FIND THE END OF RELATION LIST*/ switch ( SearchRelation( ) ) { case FIRST_FOUND: // THIS RELATION HAS BEEN ALREADY DEFINED case FOUND : currelation -> SetRelation( name, rel ); return; case NOT_FOUND: // NOT FIRST ADD NEW RELATION TO THE END OF LIST currelation = new RelationElem ( name, relatenode, rel ); prevrelation -> SetNext ( currelation ); return; case EMPTY_LIST: // THIS IS GOING TO BE THE FIRST currelation = new RelationElem ( name, relatenode, rel ); currnode -> SetRelation( currelation ); return; }}/*--------------------- FirstNode ----------------------------*//* Select currnode as start_node (beginning of the list *//* IN : - *//* OUT : Are nodes on the list *//*--------------------------------------------------------------*/BOOL Graph :: FirstNode ( ){ if ( (currnode = start_node) == NULL ) return FALSE; else return TRUE;}/*--------------------- FirstMoveNode --------------------------*//* Select currnode as first moveable node on the list *//* IN : - *//* OUT : Are moveable nodes on the list *//*--------------------------------------------------------------*/BOOL Graph :: FirstMoveNode ( ){ if ( (currnode = start_node) == NULL ) return FALSE; while ( currnode -> GetType() != MOVEABLE_NODE ) { currnode = currnode -> GetNext(); if ( currnode == NULL ) return FALSE; } return TRUE;}/*--------------------- NextNode ----------------------------*//* Let currnode be the next after currnode *//* IN : maximal serial number to be considered of ALL_NODES *//* OUT : Was it the last node? *//* SIDE EFFECT: currnode = NULL if no more nodes *//*------------------------------------------------------------*/BOOL Graph :: NextNode ( int maxsernum ){ if ( maxsernum == ALL_NODES ) { if (( currnode = currnode -> GetNext() ) == NULL ) return FALSE; } else { if (( currnode = currnode -> GetNext() ) == NULL || currnode -> GetSerNum() > maxsernum ) return FALSE; } return TRUE ;}/*--------------------- FirstRelation ------------------------*//* Select currrelation as first relation of the relation list *//* of currnode. *//* IN : - *//* OUT : Has the currnode any relation? *//*--------------------------------------------------------------*/BOOL Graph :: FirstRelation ( ){ if ( (currelation = currnode -> GetRelation()) == NULL ) { relatenode = NULL; return FALSE; } else { relatenode = (NodeElem *)( currelation -> GetOtherNode() ); return TRUE; }}/*--------------------- NextRelation --------------------------*//* Let currelation the next after currelation *//* IN : - *//* OUT : Was it the last relation of the list? *//*--------------------------------------------------------------*/BOOL Graph :: NextRelation ( ){ if ( (currelation = currelation -> GetNext()) == NULL ) { relatenode = NULL; return FALSE; } else { relatenode = (NodeElem *)( currelation -> GetOtherNode() ); return TRUE; }}/*------------------ RandomArrange ---------------------------*//* Random arrangement of nodes *//*--------------------------------------------------------------*/void Graph :: RandomArrange( ){/** SKIP FIXED NODES*/ if ( !FirstMoveNode() ) return;/** MAIN CYCLE OF PLACING MOVEABLE NODES RANDOMLY*/ do { currnode -> Position( ) = vector((OVERWINDOW_X - WALL_MARGIN * 2.0) / (double)RAND_MAX * (double)rand() + WALL_MARGIN, (OVERWINDOW_Y - WALL_MARGIN * 2.0) / (double)RAND_MAX * (double)rand() + WALL_MARGIN ); } while ( NextNode() );}/************************************************************************//* OBJECT SPACE *//************************************************************************//*----------------- ObjectSpace Constructor --------------------*//* Initializes object space window *//* IN : - *//* OUT : - *//*--------------------------------------------------------------*/ObjectSpace :: ObjectSpace( ) :vwindow( 0, 0, (CoOrd)OVERWINDOW_Y, (CoOrd)OVERWINDOW_X ), viewport( 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT ){}/*------------------------ SetScale ----------------------------*//* Initializes window -> viewport transform *//* IN : - *//* OUT : - *//*--------------------------------------------------------------*/void ObjectSpace :: SetScale(){ scale_x = (double)viewport.Width() / (double)vwindow.Width(); scale_y = (double)viewport.Height() / (double)vwindow.Height();}/*--------------------- SetViewPort ----------------------------*//* Sets viewport (Canvas RectAngle) *//* IN : new viewport *//* OUT : - *//* SIDE EFFECT: Recalculates window->viewport transform *//*--------------------------------------------------------------*/void ObjectSpace :: SetViewPort( RectAngle v ){ viewport = v; SetScale();}/*--------------------- ScreenPos ------------------------------*//* Transform a point from object space to screen space *//* IN : object space position *//* OUT : screen space coordinates of point *//*--------------------------------------------------------------*/Point ObjectSpace :: ScreenPos( vector p ){ CoOrd x = (CoOrd)((p.X()-(double)vwindow.HorPos()) * scale_x); CoOrd y = (CoOrd)((p.Y()-(double)vwindow.VerPos()) * scale_y); return Point(x,y);}/*--------------------- ScreenPos ------------------------------*//* Gets the position of a NODE in screen coordinate system *//* IN : pointer to the NODE *//* OUT : screen space coordinates of NODE position *//*--------------------------------------------------------------*/Point ObjectSpace :: ScreenPos( NodeElem * pnode ){ return ScreenPos( pnode -> Position() );}/************************************************************************//* GRAPH WINDOW *//************************************************************************//*----------------- GraphWindow constructor ------------------*//* Reads the input file defined in argv[1] *//*--------------------------------------------------------------*/GraphWindow :: GraphWindow( int argc, char * argv[] ) : AppWindow( argc, argv ){ if ( argc > 1 ) { graph.RestoreNodes( argv[1] ); } else app.Error( "Input file missing" );}/*------------------------ ExposeAll ----------------------*//* Redraw the graph on the screen *//*--------------------------------------------------------------*/void GraphWindow :: ExposeAll( ExposeEvent * event ){ Text( "<L> = Layout Algorithm", Point(20, 20) ); Text( "<R> = Random Arrange", Point(20, 40) ); Text( "<Q> = Quit & Save", Point(20, 60) );/** SET WINDOW - VIEWPORT TRANSFORM*/ if ( event ) graph.SetViewPort( Canvas() );/** DISPLAY RELATIONS*/ graph.FirstNode(); do { if ( graph.FirstRelation() ) { do ShowRelation(); while ( graph.NextRelation() ); } } while ( graph.NextNode() );/** DISPLAY NODES*/ if ( !graph.FirstNode() ) return; do ShowNode( ); while ( graph.NextNode() );}/*--------------------- MouseButtonDn ----------------------*//* React to Mouse button down event! *//*--------------------------------------------------------------*/void GraphWindow :: KeyPressed( KeyEvent * event ){ switch ( event -> GetASCII() ) { case 'L': case 'l': switch ( graph.Placement() ) { case STOPPED: RePaint(); break; case INSTABLE:app.Warning("Instable system"); break; case TOO_LONG:app.Warning("Solution takes too long"); break; } break; case 'R': case 'r': graph.RandomArrange(); RePaint(); break; case 'Q': case 'q': graph.SaveNodes( "ggg.dat" ); app.Quit(); }}/*--------------------- ShowNode ------------------------*//* Shows current node as a rectangle and a text *//*------------------------------------------------------------*/void GraphWindow :: ShowNode( ){ DrawRectangle( RectAngle( graph.ScreenPos().X() - NODESIZE_X / 2, graph.ScreenPos().Y() - NODESIZE_Y / 2, NODESIZE_X, NODESIZE_Y) ); Text( graph.GetNode() -> GetName(), graph.ScreenPos() );}/*--------------------- ShowRelation ----------------------*//* Shows the current relation as a line and a text *//*--------------------------------------------------------------*/void GraphWindow :: ShowRelation( ){ MoveTo( graph.ScreenPos() ); LineTo( graph.RelScreenPos() ); Text( graph.GetRelationName(), Point( (graph.ScreenPos().X() + graph.RelScreenPos().X()) / 2, (graph.ScreenPos().Y() + graph.RelScreenPos().Y()) / 2 ) );}/************************************************************************//* WINDOW MANAGER INDEPENDENT ENTRY POINT *//************************************************************************/void App :: Start( int argc, char * argv[] ){ GraphWindow graphwindow( argc, argv ); graphwindow.MessageLoop( );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -