/****************************************************************** * * * Nest version 2 - 3D Wasp Nest Simulator * * Copyright (C) 1997 Sylvain GUERIN * * LIASC, ENST Bretagne & Santa Fe Institute * * * ****************************************************************** E-mail: Sylvain.Guerin@enst-bretagne.fr or: Sylvain Guerin 13 rue des Monts Lorgeaux, 51460 L'EPINE, FRANCE ****************************************************************** This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ****************************************************************** Name : EvalInt.c Component : evaluation interface Fonctionality : contains methods for objects refering to the evaluation interface ******************************************************************/ #include "EvalInt.h" #include "config.h" #include "graph.h" #include #define nodesDiameter 200 EvalInterface::EvalInterface (Interface* theMainInterface,int x0, int y0, char* windowLabel, char* iconLabel, Display* aDisplay, Simulation* aSimulation) : Interface (x0, y0, 820, 720, 1, windowLabel, iconLabel, aDisplay) { mainInterface = theMainInterface; closeButton = new Button (this, 10, 230, 110, 25, "Close", centerJustified, enabled); resizeButton = new Button (this, 10, 260, 110, 25, "Resize", centerJustified, enabled); showIndexOrRulesButton = new SwapButton (this, 10, 290, 110, 25, "Show index", "Show rules", centerJustified, enabled); hideNodesButton = new Button (this, 10, 320, 110, 25, "Hide nodes", centerJustified, enabled); clusteringButton = new Button (this, 10, 350, 110, 25, "Kohonen", centerJustified, enabled); cooccurencesButton = new Button (this, 10, 380, 110, 25, "Co-occurs", centerJustified, enabled); patternsButton = new Button (this, 10, 410, 110, 25, "Patterns", centerJustified, enabled); graphWindow = new GraphicWindow (this, 130, 210, 680, 500, enabled, ButtonPressMask | ExposureMask, Black); tempScreen = XCreatePixmap (display, graphWindow->win, graphWindow->width, graphWindow->height, defaultDepth); translatePanel = new RoundPanel (this, 13, height-110, 100, 100); leftButton = new LeftArrow (translatePanel, 7, 38, enabled); rightButton = new RightArrow (translatePanel, 66, 38, enabled); upButton = new UpArrow (translatePanel, 37, 7, enabled); downButton = new DownArrow (translatePanel, 37, 66, enabled); zoomUpButton = new UpSquare (this, 12, height-145, enabled); zoomDownButton = new DownSquare (this, 88, height-145, enabled); zoomText = new TextWidget (this, 47, height-140, "zoom"); fitness1Text = new TextWidget (this, 20, 15, "Fitness (UsedRulesFraction): --------"); fitness2Text = new TextWidget (this, 20, 35, "Fitness (GlobalUsedRules): --------"); fitness3Text = new TextWidget (this, 20, 55, "Fitness (Compacity): --------"); fitness4Text = new TextWidget (this, 20, 75, "Fitness (Complexity): --------"); fitness5Text = new TextWidget (this, 20, 95, "Fitness (Coherence): --------"); fitness6Text = new TextWidget (this, 20, 115,"Fitness (HybridMethod): --------"); rulesNbText = new TextWidget (this, 20, 140, "Rules number: ---"); nodesNbText = new TextWidget (this, 20, 160, "Nodes number: ----"); edgesNbText = new TextWidget (this, 20, 180, "Edges number: ----"); /* histoWindow = new GraphicWindow (this, 10, 130, 480, 320, enabled, ButtonPressMask | ExposureMask, LightGrey);*/ histoWindow = new GraphicWindow (this, 410, 10, 400, 190, enabled, ButtonPressMask | ExposureMask, LightGrey); simu = aSimulation; fitness1 = simu->evaluate (UsedRulesFraction); fitness2 = simu->evaluate (GlobalUsedRules); fitness3 = simu->evaluate (Compacity); if (simu->simulationArchitecture->graph->isComplexityComputed) { fitness4 = simu->evaluate (Complexity); if (simu->simulationArchitecture->graph->isCoherenceComputed) { fitness5 = simu->evaluate (Coherence); fitness6 = simu->evaluate (HybridMethod); } else { fitness5 = -1; fitness6 = -1; } } else { fitness4 = -1; fitness5 = -1; fitness6 = -1; } zoom = 0.0567; tx = 120; ty = 20; alreadyComputed = 0; showRulesNumber = 1; isPatternIntDisplayed = 0; displayTexts (); } EvalInterface::~EvalInterface () { XFreePixmap (display, tempScreen); delete closeButton; delete resizeButton; delete showIndexOrRulesButton; delete hideNodesButton; delete clusteringButton; delete cooccurencesButton; delete patternsButton; delete fitness1Text; delete fitness2Text; delete fitness3Text; delete fitness4Text; delete fitness5Text; delete fitness6Text; delete rulesNbText; delete nodesNbText; delete edgesNbText; delete zoomText; delete zoomDownButton; delete zoomUpButton; delete downButton; delete upButton; delete rightButton; delete leftButton; delete translatePanel; delete graphWindow; delete histoWindow; } actionType EvalInterface::manageInterface (XEvent report) { actionType action; int i; Graph* graph; graph = simu->simulationArchitecture->graph; if (isPatternIntDisplayed) { action = patternInterface->manageInterface (report); if (action == endInterface) { isPatternIntDisplayed = 0; delete patternInterface; } else if (action == simpleSignal) { /* on met a jour les fitness */ if (simu->simulationArchitecture->graph->isComplexityComputed) { fitness4 = simu->evaluate (Complexity); if (simu->simulationArchitecture->graph->isCoherenceComputed) { fitness5 = simu->evaluate (Coherence); fitness6 = simu->evaluate (HybridMethod); } displayTexts (); } return simpleSignal; } } if (closeButton->manageEvent (report) == buttonPressed) { if (isPatternIntDisplayed) { /* avant de quitter, on vire tous les patterns */ graph->freeAllPatterns (); delete patternInterface; } return endInterface; } fitness1Text->manageEvent (report); fitness2Text->manageEvent (report); fitness3Text->manageEvent (report); fitness4Text->manageEvent (report); fitness5Text->manageEvent (report); fitness6Text->manageEvent (report); rulesNbText->manageEvent (report); nodesNbText->manageEvent (report); edgesNbText->manageEvent (report); if (histoWindow->manageEvent (report) == mustBeRefreshed) { displayHisto (); } resizeButton->manageEvent (report); if (showIndexOrRulesButton->manageEvent (report) == buttonPressed) { if (showIndexOrRulesButton->isSwapped () == 0) showRulesNumber = 1; else showRulesNumber = 2; alreadyComputed = 0; displayGraph (); } if (hideNodesButton->manageEvent (report) == buttonPressed) { showRulesNumber = 0; alreadyComputed = 0; displayGraph (); } if (clusteringButton->manageEvent (report) == buttonPressed) { graph->resetKohonen (); displayAbortableInfoBox (mainInterface, 10, 10, "Kohonen algorithm", "Nest2", "Kohonen algorithm is running, please wait..."); for (i=0; icomputeKohonenIteration (); alreadyComputed = 0; displayGraph (); XSync (display, False); /* pour synchroniser l'ecran */ anInfoBox->setStatWindow ((double)(i)/(double)(defaultMaxIterations)); if (anInfoBox->refreshStatWindow () == 1) { break; } } freeInfoBox (); } if (cooccurencesButton->manageEvent (report) == buttonPressed) { graph->displayCooccurenceMatrix (simu->simulationRuleArray); } if (patternsButton->manageEvent (report) == buttonPressed) { /* graph->computePatterns (); */ if (isPatternIntDisplayed) { displayDialogBox (mainInterface, "Error", "Nest2", "Patterns interface already opened.", "Continue"); } else { patternInterface = new PatternInterface (mainInterface, 500, 100, "Patterns interface", "Nest2", this->display, simu); isPatternIntDisplayed = 1; } } zoomText->manageEvent (report); if (zoomDownButton->manageEvent (report) == buttonPressed) { zoom = zoom*0.9; alreadyComputed = 0; displayGraph (); } if (zoomUpButton->manageEvent (report) == buttonPressed) { zoom = zoom*1.1; alreadyComputed = 0; displayGraph (); } if (downButton->manageEvent (report) == buttonPressed) { ty -= 20; alreadyComputed = 0; displayGraph (); } if (upButton->manageEvent (report) == buttonPressed) { ty += 20; alreadyComputed = 0; displayGraph (); } if (rightButton->manageEvent (report) == buttonPressed) { tx -= 20; alreadyComputed = 0; displayGraph (); } if (leftButton->manageEvent (report) == buttonPressed) { tx += 20; alreadyComputed = 0; displayGraph (); } translatePanel->manageEvent (report); if (graphWindow->manageEvent (report) == mustBeRefreshed) { displayGraph (); } return noAction; } void EvalInterface::refresh () { closeButton->refresh (); resizeButton->refresh (); showIndexOrRulesButton->refresh (); hideNodesButton->refresh (); clusteringButton->refresh (); cooccurencesButton->refresh (); patternsButton->refresh (); translatePanel->refresh (); leftButton->refresh (); rightButton->refresh (); upButton->refresh (); downButton->refresh (); zoomUpButton->refresh (); zoomDownButton->refresh (); zoomText->refresh (); fitness1Text->refresh (); fitness2Text->refresh (); fitness3Text->refresh (); fitness4Text->refresh (); fitness5Text->refresh (); fitness6Text->refresh (); rulesNbText->refresh (); nodesNbText->refresh (); edgesNbText->refresh (); if (graphWindow->shouldBeRefreshed ()) displayGraph (); if (histoWindow->shouldBeRefreshed ()) displayHisto (); if (isPatternIntDisplayed) { patternInterface->refresh (); } } void EvalInterface::displayHisto () { int i; int rulesNb; int current, total; unsigned int barWidth, barHeight, posY; char text[20]; rulesNb = simu->simulationRuleArray->getElementsNb (); barWidth = (unsigned int)((histoWindow->width-60)/(double)rulesNb); total = simu->simulationArchitecture->cellsNumber; XSetBackground (display, *gc, color[LightGrey]); for (i=0; i<11; i++) { posY = (unsigned int)((10-i)*(histoWindow->height-40)/10+20); XSetForeground (display, *gc, color[Black]); XDrawLine (display, histoWindow->win, *gc, 40, posY, histoWindow->width-10, posY); XSetForeground (display, *gc, color[White]); XDrawLine (display, histoWindow->win, *gc, 40, posY+1, histoWindow->width-10, posY+1); if (i==10) { sprintf (text, "100"); } else if (i==0) { sprintf (text, " 0"); } else { sprintf (text, " %d", i*10); } XSetForeground (display, *gc, color[Black]); XDrawImageString (display, histoWindow->win, *gc, 5, posY+3, text, strlen(text)); } XSetForeground (display, *gc, color[Black]); XDrawLine (display, histoWindow->win, *gc, 40, 20, 40, histoWindow->height-20); XDrawLine (display, histoWindow->win, *gc, 40, histoWindow->height-20, histoWindow->width-10, histoWindow->height-20); for (i=0; isimulationArchitecture->ruleOccurs[i]; barHeight = (int)((double)(histoWindow->height-40) *(double)(current)/(double)(total)); XSetForeground (display, *gc, color[Red]); XFillRectangle (display, histoWindow->win, *gc, 45+i*barWidth, histoWindow->height-20-barHeight, barWidth, barHeight); XSetForeground (display, *gc, color[Red3]); XDrawRectangle (display, histoWindow->win, *gc, 45+i*barWidth, histoWindow->height-20-barHeight, barWidth, barHeight); } } void EvalInterface::displayTexts () { char text[256]; int rulesNb; rulesNb = simu->simulationRuleArray->getElementsNb (); sprintf (text, "Fitness (UsedRulesFraction): %f ", fitness1); fitness1Text->change (text); sprintf (text, "Fitness (GlobalUsedRules): %f ", fitness2); fitness2Text->change (text); sprintf (text, "Fitness (Compacity): %f ", fitness3); fitness3Text->change (text); if (fitness4 != -1) { sprintf (text, "Fitness (Complexity): %f ", fitness4); } else { sprintf (text, "Fitness (Complexity): unknown "); } fitness4Text->change (text); if (fitness5 != -1) { sprintf (text, "Fitness (Coherence): %f ", fitness5); } else { sprintf (text, "Fitness (Coherence): unknown "); } fitness5Text->change (text); if (fitness6 != -1) { sprintf (text, "Fitness (HybridMethod): %f ", fitness6); } else { sprintf (text, "Fitness (HybridMethod): unknown "); } fitness6Text->change (text); sprintf (text, "Rules number: %d ", rulesNb); rulesNbText->change (text); sprintf (text, "Nodes number: %d ", simu->simulationArchitecture->graph->getNodesNumber ()); nodesNbText->change (text); sprintf (text, "Edges number: %d ", simu->simulationArchitecture->graph->getEdgesNumber ()); edgesNbText->change (text); } void EvalInterface::displayGraph () { int i, j; Graph* graph; GraphNode* currentNode; GraphNode* startNode; GraphNode* endNode; if (alreadyComputed == 1) { displayTempScreen (); } else { /* on recalcule le pixmap */ graph = simu->simulationArchitecture->graph; clearTempScreen (); /* affichage des aretes */ for (i=0; igetNodesNumber (); i++) { startNode = graph->nodeAtIndex (i); for (j=0; joutputEdgesNumber (); j++) { endNode = graph->nodeAtIndex (startNode->indexOfOutputNeighbour (j)); drawEdge (startNode->getPx (), startNode->getPy (), endNode->getPx (), endNode->getPy ()); } } /* affichage des noeuds */ for (i=0; igetNodesNumber (); i++) { currentNode = graph->nodeAtIndex (i); if (showRulesNumber == 1) { drawNode (currentNode->getPx (), currentNode->getPy (), currentNode->getRuleId ()); } else { drawNode (currentNode->getPx (), currentNode->getPy (), currentNode->getNodeId ()); } } displayTempScreen (); alreadyComputed = 1; } } int EvalInterface::posX (double x) { return (int)(x*zoom+tx); } int EvalInterface::posY (double y) { return (int)(y*zoom+ty); } void EvalInterface::drawNode (double x, double y, int ruleId) { XTextItem textItem; char text[10]; XSetForeground (display, *gc, color[Black]); XFillArc (display, tempScreen, *gc, posX (x), posY (y), (int)(nodesDiameter*zoom), (int)(nodesDiameter*zoom), 0, 360*64); XSetForeground (display, *gc, color[Yellow]); XDrawArc (display, tempScreen, *gc, posX (x), posY (y), (int)(nodesDiameter*zoom), (int)(nodesDiameter*zoom), 0, 360*64); if (showRulesNumber) { XSetForeground (display, *gc, color[White]); sprintf (text, "%d", ruleId); textItem.chars = text; textItem.nchars = strlen (text); textItem.delta = 1; textItem.font = fontInfo->fid; if (nodesDiameter*zoom > 20) { XDrawText (display, tempScreen, *gc, posX (x)+(int)(nodesDiameter*zoom/2)-5, posY (y)+(int)(nodesDiameter*zoom/2)+5, &textItem, 1); } else { XDrawText (display, tempScreen, *gc, posX (x)+(int)(nodesDiameter*zoom), posY (y)+(int)(nodesDiameter*zoom), &textItem, 1); } } } void EvalInterface::drawEdge (double x1, double y1, double x2, double y2) { double x3, y3; double x4, y4; double x5, y5; double rho; double d; double alpha; XPoint pts[3]; alpha = M_PI/12; d = sqrt ((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); rho = 200/d; if (d>nodesDiameter/2) { /* sinon la fleche aurait un air bizarre */ x3 = x1+(x2-x1)*(d-nodesDiameter/2)/d; y3 = y1+(y2-y1)*(d-nodesDiameter/2)/d; x4 = rho*((x1-x3)*cos(alpha)-(y1-y3)*sin(alpha))+x3; y4 = rho*((y1-y3)*cos(alpha)+(x1-x3)*sin(alpha))+y3; x5 = rho*((x1-x3)*cos(alpha)+(y1-y3)*sin(alpha))+x3; y5 = rho*((y1-y3)*cos(alpha)-(x1-x3)*sin(alpha))+y3; XSetForeground (display, *gc, color[Red]); XDrawLine (display, tempScreen, *gc, posX (x1)+(int)(nodesDiameter*zoom/2), posY (y1)+(int)(nodesDiameter*zoom/2), posX (x2)+(int)(nodesDiameter*zoom/2), posY (y2)+(int)(nodesDiameter*zoom/2)); pts[0].x = (int)(posX (x3)+(int)(nodesDiameter*zoom/2)); pts[0].y = (int)(posY (y3)+(int)(nodesDiameter*zoom/2)); pts[1].x = (int)(posX (x4)+(int)(nodesDiameter*zoom/2)); pts[1].y = (int)(posY (y4)+(int)(nodesDiameter*zoom/2)); pts[2].x = (int)(posX (x5)+(int)(nodesDiameter*zoom/2)); pts[2].y = (int)(posY (y5)+(int)(nodesDiameter*zoom/2)); XFillPolygon (display, tempScreen, *gc, pts, 3, Convex, CoordModeOrigin); } } void EvalInterface::displayTempScreen () { XCopyArea (display, tempScreen, graphWindow->win, *gc, 0, 0, graphWindow->width, graphWindow->height, 0, 0); } void EvalInterface::clearTempScreen () { XSetForeground (display, *gc, color[Black]); XFillRectangle (display, tempScreen, *gc, 0, 0, graphWindow->width, graphWindow->height); }