⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 graph.c

📁 [Game.Programming].Academic - Graphics Gems (6 books source code)
💻 C
📖 第 1 页 / 共 2 页
字号:
/**************************************************************************    TEST FILE FOR graph (Dynamic Layout Alg)****    MODUL - MANIPULATION OF THE GRAPH DATA STRUCTURE**** Author: dr. Szirmay-Kalos Laszlo (szirmay@fsz.bme.hu)**	   Technical University of Budapest, Hungary*************************************************************************/#ifdef MSWINDOWS#include "fileio.hxx"#else#include "fileio.hxx"#endif/************************************************************************//*    NODE								*//************************************************************************//*-------------------	node constructor      ------------------*//* Constructs node   object and initializes			*//* IN  : name and type (MOVEABLE or FIXED) of node		*//* OUT : -							*//*--------------------------------------------------------------*/Node :: Node(pchar newname, TYPE ntype){    newname[MAXNAME] = '\0';    strcpy(name,newname);    type  = ntype;    force = vector(0.0, 0.0);    pos	  = vector(0.0, 0.0);    speed = vector(0.0, 0.0);}/************************************************************************//*    RELATION								*//************************************************************************//*------------------- relation constructor    ------------------*//* Constructs relation object and initializes			*//* IN  : name , related node, intensity,			*//*--------------------------------------------------------------*/Relation :: Relation( pchar nname, Node * np, double r ){    SetRelation( nname, r );    relation_to = np;}/*-------------------  SetRelation     -------------------------*//* Change the name intensity and relation of a constructed rel	*//* IN  : name, intensity					*//*--------------------------------------------------------------*/void Relation :: SetRelation( pchar nname, double r ){    strcpy( name, nname );    intensity = r;}/************************************************************************//*    NODE ELEM								*//************************************************************************//*------------------- NodeElem	 constructor  ------------------*//* Constructs a node elem of a list object and initializes	*//* IN  : name and type (MOVEABLE or FIXED) of node		*//*--------------------------------------------------------------*/NodeElem :: NodeElem( pchar name, TYPE type )	  : Node( name, type ){    next_node = NULL;    relation = NULL;}/************************************************************************//*    RELATION ELEM							*//************************************************************************//*------------------- RelationNode constructor	----------------*//* Constructs relation node of a list object and initializes	*//* IN  : name , related node, intensity,		       *//*--------------------------------------------------------------*/RelationElem :: RelationElem( pchar name, Node * p, double r )	      : Relation( name, p, r ){    next_relation = NULL;}/************************************************************************//*    GRAPH = NODE - RELATION DATA					*//*									*//*    The Graph data structure is a dynamic structure.			*//*									*//*    The nodes are placed on a singly linked list, where fix nodes	*//*    are on the beginning, and moveable nodes are on the end.		*//*    The nodes are also identified by serial numbers, the moveable	*//*    nodes are having positive while fixed nodes negative numbers.	*//*    Control pointers : currnode - points to the actual node		*//*			 relatenode - other node which forms a pair	*//*					with currnode for relation ops	*//*			 start_node - the beginning of the list		*//*			 last_node - the end of the list		*//*									*//*    The relations of a given node are stored on an other linked list	*//*    connected to the node of the given node. The relation node	*//*    contains name, type, intensity parameters and a pointer to the	*//*    related node. The relation of two node is stored on the		*//*    relation list of the node having smaller serial number!		*//*    Control pointers : currelation -points to the actual relation node*//*			 prevrelation - points to the relation just	*//*			    before currelation on the actual relation	*//*			    list.					*//*									*//*  STRUCTURE OVERVIEW: P = Node, R = RelationNode			*//*									*//*  start_node				lastnode			*//*     P ---> P ---> P ---> P ---> P ---> P ---> NULL			*//*     |	     ^	    |	   ^	  ^				*//*     R ------------|	    R------|	  |				*//*     |		    |		  |				*//*    NULL		    R-------------|				*//*			    |						*//*			   NULL						*//************************************************************************//*------------------ Graph Constructor -------------------------*//* Initializes Graph data structure				*//*--------------------------------------------------------------*/Graph :: Graph(){    start_node = NULL;    last_node  = NULL;    currnode   = NULL;    relatenode = NULL;    currelation	 = NULL;    prevrelation = NULL;    nfixnode   = nmovnode = 0;}/*------------------ RestoreNodes ----------------------------*//* Restores the node-relation data structure from a file	*//* The file type is TEXT.					*//* IN  : file name						*//* SIDE EFFECT: - node-relation data structure is destroyed	*//*		  then it is restored from the given file	*//*--------------------------------------------------------------*/void Graph :: RestoreNodes ( pchar file_name ){    char    s[MAXLINE + 1];    char    node_name[MAXNAME + 1];    char    rel_node_name[MAXNAME + 1];    char    relation_name[MAXNAME + 1];    double  x, y;    double  relation;    FileIO  fi ( "r" );    BOOL    first_rel;    if ( !fi.OpenFile ( file_name ) ) app.Error("Input file does not exists");/**    RESTORE NODES*/    for ( ; ; ) {/**    TRY TO INPUT NODE NAME*/	if ( !fi.GetKeyWord ( "NAME" ) ) {/**    FAILED -> END OF NODE LIST*/	    first_rel = TRUE;	    break;	} else {	    if ( !fi.GetOperator ( '=' ) ) app.Error( "= expected", fi.GetLineNum() );	    if ( !fi.GetString(node_name,MAXNAME) ) app.Error( "Name expected", fi.GetLineNum() );/**    TRY TO INPUT NODE POSITION*/	    if ( !fi.GetKeyWord("POSITION") ) {/**    FAILED -> ASSUME NO POSITION, GENERATE RANDOMLY*/		x = (OVERWINDOW_X - WALL_MARGIN * 2.0) /		    (double)RAND_MAX * (double)rand() + WALL_MARGIN;		y = (OVERWINDOW_Y - WALL_MARGIN * 2.0) /		    (double)RAND_MAX * (double)rand() + WALL_MARGIN;		if ( !fi.GetKeyAgain("TYPE") ) app.Error( "TYPE expected", fi.GetLineNum() );	    } else {		if ( !fi.GetOperator ( '=' ) ) app.Error( "= expected", fi.GetLineNum() );		if ( !fi.GetVariable( &x, 0.0, OVERWINDOW_X ) || !fi.GetVariable( &y, 0.0, OVERWINDOW_Y ) )			app.Error( "Coordinate out of space", fi.GetLineNum() );		if ( !fi.GetKeyWord("TYPE") )  app.Error( "TYPE expected", fi.GetLineNum() );	    }/**    TRY TO INPUT TYPE PARAMETERS*/	    if ( !fi.GetOperator ( '=' ) ) app.Error( "= expected", fi.GetLineNum() );	    if ( !fi.GetString( s, MAXLINE ) ) app.Error("Line too long", fi.GetLineNum() );/**    ADD NEW NODE TO THE DATA STRUCTURE AND CHECK THE NAME IF UNIQUE*/	    if ( strcmp( s, "FIXED" ) == 0 ) {		if ( !AddNode(node_name, FIXED_NODE) )	  app.Error("Not unique node name", fi.GetLineNum() );	    } else if ( strcmp( s, "MOVEABLE" ) == 0 ) {		if ( !AddNode(node_name, MOVEABLE_NODE) ) app.Error("Not unique node name", fi.GetLineNum() );	    } else					  app.Error("Invalid Node type", fi.GetLineNum() );	    currnode -> Position( ) = vector( x, y );	}    }/**    RESTORE RELATIONS*/    for( ; ; ) {/**    TRY TO GET RELATION LIST HEAD, IF FAIL -> END OF INPUT*/	if ( first_rel ) {	    if ( !fi.GetKeyAgain ( "RELATIONS" ) )  break;	    first_rel = FALSE;	} else {	    if ( !fi.GetKeyWord ( "RELATIONS" ) )  break;	}	if ( !fi.GetKeyWord("OF") )  app.Error("OF expected", fi.GetLineNum() );	if ( !fi.GetString( node_name, MAXNAME ) ) app.Error("Name too long", fi.GetLineNum() );	if ( !fi.GetKeyWord ( "NODE" ) ) app.Error("NODE expected", fi.GetLineNum() );/**    IDENTIFY NODE*/	if ( !SearchNode( node_name ) ) app.Error("Not declared Node", fi.GetLineNum() );/**    TRY TO INPUT RELATION LIST*/	for( ; ; ) {		// get the whole relation list of this node/**    TRY TO GET RELATION NAME*/	    if ( !fi.GetKeyWord ( "RELATION" ) ) {/**    FAILED -> CHECK END OF RELATION MARKER*/		if ( !fi.GetKeyAgain ( "END" ) ) app.Error("END expected", fi.GetLineNum() );		else break;	    }	    if ( !fi.GetString( relation_name, MAXNAME ) ) app.Error("Name too long", fi.GetLineNum() );/**    CHECK IF NO-NAME RELATION*/	    if ( strcmp( relation_name, "*" ) == 0 ) relation_name[0] = '\0';	    if ( !fi.GetOperator ( ':' ) ) app.Error(": expected", fi.GetLineNum() );/**    TRY TO GET RELATED NODE WITH RELATION PARAMETERS*/	    if ( !fi.GetKeyWord("RELATED") )   app.Error("RELATED expected", fi.GetLineNum() );	    if ( !fi.GetKeyWord("TO") )	       app.Error("TO expected", fi.GetLineNum() );	    if ( !fi.GetString( rel_node_name, MAXNAME ) ) app.Error("Name expected", fi.GetLineNum() );	    if ( !fi.GetKeyWord("WITH") )      app.Error("WIDTH expected", fi.GetLineNum() );	    if ( !fi.GetKeyWord("INTENSITY") ) app.Error("INTENSITY expected", fi.GetLineNum() );	    if ( !fi.GetVariable( &relation, -MAXRELATION, MAXRELATION ) )		app.Error("Relation is out of range", fi.GetLineNum() );/**    BUILD THE NEW RELATION INTO THE DATA STRUCTURE*/	    NodeElem * tmpnode = currnode;	    if ( !RelSearchNode( rel_node_name ) ) app.Error("Not declared Node", fi.GetLineNum() );	    AddRelation( relation_name, relation );	    currnode = tmpnode;	}    }    fi.CloseFile();}/*------------------  SaveNodes	  ----------------------------*//* Saves the node-relation data structure to a file name      *//* The file type is TEXT.					*//* IN  : file name						*//*--------------------------------------------------------------*/BOOL Graph :: SaveNodes ( pchar file_name ){    char s[MAXLINE];    FileIO fo ( "w" );    if ( !fo.OpenFile (file_name) ) return FALSE;/**    SAVE NODES*/    if ( !FirstNode() ) {	fo.CloseFile( );	return TRUE;    }    do {	sprintf(s,		"NAME = %s POSITION =  %6.3lf %6.3lf TYPE = %s\n",		currnode -> GetName(),		currnode -> Position().X(),		currnode -> Position().Y(),		(currnode -> GetType() == FIXED_NODE ? "FIXED" : "MOVEABLE"));	fo.PutString( s );    } while ( NextNode() );/**    SAVE RELATIONS*/    FirstNode();    do {	   sprintf(s,		    "\nRELATIONS OF %s NODE\n",		  currnode -> GetName());	  fo.PutString( s );	  if ( !FirstRelation() ) {	    fo.PutString( "END\n" );	    // END OF RELATION MARKER	      continue;	  }	  do {	      if ( strlen( currelation -> GetName() ) != 0 )		 sprintf(s, "RELATION %s : ", currelation -> GetName() );	      else		 sprintf(s, "RELATION * : ");	      fo.PutString( s );	      sprintf(s,		      "RELATED TO %s WITH INTENSITY %6.3lf \n",		      currelation -> GetOtherNode() -> GetName(),		      currelation -> GetRelation() );	      fo.PutString( s );	  } while ( NextRelation() );	  fo.PutString( "END\n" );	  // END OF RELATION MARKER    } while ( NextNode() );    fo.CloseFile( );    return TRUE;}/*-------------------	  SetNodePos	  --------------------*//* Sets the position of a node				      *//* IN  : new position						*//*--------------------------------------------------------------*/void Graph :: SetNodePos ( vector p ){    if ( currnode != NULL ) currnode -> Position( ) = p;}/*------------------------ GetRelation	 -----------------------*//* Gets the relation intensity of the actual relation		*//* IN  : -							*//* OUT : intensity ( -MAXRELATION -> MAXRELATION )		*//*--------------------------------------------------------------*/double Graph :: GetRelation( ){    if (currelation != NULL) return currelation -> GetRelation( );    else		     return 0.0;}/*------------------------ GetRelationName ---------------------*//* Gets the name of the actual relation				*//* OUT : name of NULL if no relation				*//*--------------------------------------------------------------*/pchar Graph :: GetRelationName( ){    if ( currelation != NULL ) return currelation -> GetName( );    else		       return NULL;}/*------------------------   AddNode   -----------------------*//* Checks if a node having the same name exist and if not new *//* node is allocated and added to the beginning of the list if*//* the node is FIXED or to the end if it is MOVEABLE	      *//* IN  : name and type of the new node			      *//* OUT : is this name unique ?				      *//* SIDE EFFECT: currnode is set to the new node.	      *//*		if FIXED node				      *//*		  start_node adjusted, nfixnode incremented   *//*		if MOVEABLE NODE			      *//*		  last_node adjusted, nmovnode incremented    *//*------------------------------------------------------------*/BOOL Graph :: AddNode ( pchar name, char type ){/**    DECIDE IF THIS NAME IS UNIQUE, IF NOT RETURN ERROR*/    if ( SearchNode( name ) ) return FALSE;    currnode = new NodeElem(name, type);    if (start_node == NULL) {/**    IF THIS IS THE FIRST NODE*/	start_node = last_node = currnode;    } else {	if ( type == FIXED_NODE ) {/**    IF FIXED NODE -> ADD TO THE BEGINNING OF THE LIST*/	    currnode -> SetNext( start_node );	    start_node = currnode;	} else {/**    IF MOVEABLE NODE -> ADD TO THE END OF THE LIST*/	    last_node -> SetNext( currnode );	    last_node = currnode;	}    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -