/*# --------------------------------------------------------------------- # # Copyright (c) CREATIS (Centre de Recherche en Acquisition et Traitement de l'Image # pour la Sant�) # Authors : Eduardo Davila, Frederic Cervenansky, Claire Mouton # Previous Authors : Laurent Guigues, Jean-Pierre Roux # CreaTools website : www.creatis.insa-lyon.fr/site/fr/creatools_accueil # # This software is governed by the CeCILL-B license under French law and # abiding by the rules of distribution of free software. You can use, # modify and/ or redistribute the software under the terms of the CeCILL-B # license as circulated by CEA, CNRS and INRIA at the following URL # http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html # or in the file LICENSE.txt. # # As a counterpart to the access to the source code and rights to copy, # modify and redistribute granted by the license, users are provided only # with a limited warranty and the software's author, the holder of the # economic rights, and the successive licensors have only limited # liability. # # The fact that you are presently reading this means that you have had # knowledge of the CeCILL-B license and that you accept its terms. # ------------------------------------------------------------------------ */ //---------------------------------------------------------------------------- // Class definition include //---------------------------------------------------------------------------- #include "pLogicalFunction.h" #include #include #include // ---------------------------------------------------------------------------- // WX headers inclusion. // For compilers that support precompilation, includes . // ---------------------------------------------------------------------------- #ifndef WX_PRECOMP #include #endif //---------------------------------------------------------------------------- // Class implementation //---------------------------------------------------------------------------- IMPLEMENT_CLASS(pLogicalFunction, wxObject) //---------------------------------------------------------------------------- // Constructors //---------------------------------------------------------------------------- pLogicalFunction:: pLogicalFunction( ) { realPoints.DeleteContents(TRUE); validPointRange = 5; leftToRigthDef = true; _maxX=0; _maxY=0; _minX=0; _minY=0; } /** * Is the destructor!!! */ pLogicalFunction:: ~pLogicalFunction () { realPoints.DeleteContents(TRUE); } /* * validate if the function has that point in a sensible area returning the index where the point was found or -1 if is in not part of the function: define the sensible area is * x1-validPointRangeGetData(); int x = point->getRealX(); int y = point->getRealY(); double vx=SENSIBLE_REGION/_scaleX; double vy=SENSIBLE_REGION/_scaleY; bool isInXRange= realPoint.x <= x + vx + SENSIBLE_REGION && realPoint.x >= x - vx-SENSIBLE_REGION; bool isInYRange= realPoint.y <= y + vy + SENSIBLE_REGION && realPoint.y >= y - vy-SENSIBLE_REGION; if(isInXRange && isInYRange) pointIndex = realPoints.IndexOf(point); node = node->GetNext(); } return pointIndex; } /* * returns the index in the list of the point */ int pLogicalFunction::getIndexOf(wxPoint realpoint) { wxNode* node= realPoints.GetFirst(); while(node) { pFunctionPoint* point=(pFunctionPoint*)node->GetData(); if(point->getRealX()==realpoint.x && point->getRealY()==realpoint.y ) { return realPoints.IndexOf(point); } node= node->GetNext(); } return -1; } /* * This metohd returns the node of the point that is the movingPointIndex position in the list of points. * @param: int movingPointIndex, Is the index value of the searched node. * @return: Return a pointer to the node corresponding to the index value by parameter. */ wxNode* pLogicalFunction::GetPointAt( int movingPointIndex ) { if(!realPoints.IsEmpty()) { wxNode* node= realPoints.Item(movingPointIndex); return node; } else return NULL; } /* * Includes a point between two existing points of this function. The new point (x,y) was not defined when the function was created. * @return Returns true is the point was succcesfully added to the funcion. */ bool pLogicalFunction:: AddNewPoint(int x,int y) { pFunctionPoint * newPoint = new pFunctionPoint ( x, y); bool includedPoint = realPoints.Append(newPoint)!=NULL; if(includedPoint) { bool order=true; if(realPoints.size()>1){ order=orderPoints(); } return order; } return includedPoint; } /* * This method orders the list of points taking into account that the last appended node in the list (realPoint) is the only one disordered. * @return Returns true if the last point included has a valid value for x and was ordered, according to the definition of function. */ bool pLogicalFunction::orderPoints() { bool lastOrdered = false; bool validToContinue = false; wxNode* lastNodeIncluded = realPoints.GetLast(); wxNode* node = realPoints.GetFirst(); pFunctionPoint* lastPointIncluded = (pFunctionPoint*)lastNodeIncluded -> GetData(); int xToOrder = lastPointIncluded -> getRealX(); int actualX; int nextX; // Used for validating 'leftToRigthDef' pFunctionPoint* ordFirstPoint = NULL; pFunctionPoint* ordLastPoint = NULL; if(node!=NULL){ ordFirstPoint = (pFunctionPoint*)realPoints.GetFirst()-> GetData(); } if(lastNodeIncluded->GetPrevious()!=NULL){ ordLastPoint = (pFunctionPoint*)(lastNodeIncluded->GetPrevious())-> GetData(); } // Normal drawing if (leftToRigthDef) { validToContinue = ordFirstPoint->getRealX() < xToOrder; } else { //validToContinue =ordFirstPoint->getRealX() > xToOrder; validToContinue =ordLastPoint->getRealX() > xToOrder; } if ( validToContinue) { while( node && !lastOrdered ) { pFunctionPoint* prevPoint =(pFunctionPoint*)node->GetData(); actualX = prevPoint ->getRealX(); if( actualX == xToOrder) { realPoints.DeleteNode(lastNodeIncluded); lastOrdered = false; } else if ( actualX < xToOrder ) { //firstNode wxNode* nextNode = node->GetNext(); pFunctionPoint* nextPoint; if( nextNode != lastNodeIncluded ) { nextPoint = (pFunctionPoint*)nextNode -> GetData(); nextX = nextPoint->getRealX(); int nextIndex = realPoints.IndexOf(nextPoint); if( nextX > xToOrder ) { //we need to change the direction in memory of our node pFunctionPoint* pointToInsert=new pFunctionPoint(lastPointIncluded->getRealX(),lastPointIncluded->getRealY()); // The last inserted point is ordered like: prevPoint - lastPointIncluded - nextPoint lastOrdered = (realPoints.Insert(nextIndex, pointToInsert))!= NULL; bool lastNodeDeleted=realPoints.DeleteNode(lastNodeIncluded); return lastOrdered && lastNodeDeleted; } } else { lastOrdered = true; } } else { //firstNode wxNode* prevNode = node->GetPrevious(); int insertIndex=realPoints.IndexOf(prevPoint); pFunctionPoint* prPoint; if(prevNode) { prPoint = (pFunctionPoint*)prevNode -> GetData(); int beforeX =prPoint->getRealX(); if( beforeX < xToOrder) { //we need to change the direction in memory of our node pFunctionPoint* pointToInsert=new pFunctionPoint(lastPointIncluded->getRealX(),lastPointIncluded->getRealY()); // The last inserted point is ordered like: prevPoint - lastPointIncluded - nextPoint lastOrdered = (realPoints.Insert(insertIndex, pointToInsert))!= NULL; bool lastNodeDeleted=realPoints.DeleteNode(lastNodeIncluded); return lastOrdered && lastNodeDeleted; } } //is just the second point else { //we need to change the direction in memory of our node pFunctionPoint* pointToInsert=new pFunctionPoint(lastPointIncluded->getRealX(),lastPointIncluded->getRealY()); // The last inserted point is ordered like: prevPoint - lastPointIncluded - nextPoint lastOrdered = (realPoints.Insert(insertIndex, pointToInsert))!= NULL; bool lastNodeDeleted=realPoints.DeleteNode(lastNodeIncluded); return lastOrdered && lastNodeDeleted; } } node = node->GetNext(); } } else { bool lastNodeDeleted = realPoints.DeleteNode(lastNodeIncluded); lastOrdered = lastOrdered && lastNodeDeleted; } return lastOrdered; } /* * This tries to Add a point to the function if possible it returns true. * @pre: The list of existing points is ordered. * @param: int aX, The x value of the point. * @param: int aY, The y value of the point. * @param: return Returns TRUE if the point was succesfuly included in the realPoints list. */ bool pLogicalFunction::AddPoint(int aX, int aY,bool order) { pFunctionPoint * newPoint = new pFunctionPoint (aX, aY); wxNode* lastNode = realPoints.GetLast(); bool addedPoint = false; if (lastNode) { pFunctionPoint* lastPoint = (pFunctionPoint*)lastNode->GetData(); if( lastPoint->getRealX() != aX ) { addedPoint = realPoints.Append(newPoint)!=NULL; //In case that the definition of points is being done backwards. if( (aX < (lastPoint->getRealX()) ) && addedPoint ) { if( realPoints.GetCount() == 2 ) { leftToRigthDef = false; } if(order) addedPoint = orderPoints(); } else { if( realPoints.GetCount() == 2 ) { leftToRigthDef = true; } } } } else { addedPoint = realPoints.Append(newPoint)!=NULL; } return addedPoint; } /* * Set Up startPoint, endPoint, maxY,maxX points */ void pLogicalFunction::setUp() { //sets the start point of the function setStartPoints(); //set the Last point of the function setEndPoints(); //set the min value in x and y between all the points of the function setMinPoints(); //set the max value in x and y between all the points of the function setMaxPoints(); } /* * sets the start point of the function */ void pLogicalFunction:: setStartPoints() { wxNode* first=realPoints.GetFirst(); if(first) { pFunctionPoint* startPoint=(pFunctionPoint*)first->GetData(); setStartX(startPoint->getRealX()); setStartY(startPoint->getRealY()); } else { setStartX(-1); setStartY(-1); } } /* * sets the end point of the function */ void pLogicalFunction:: setEndPoints() { wxNode* last=realPoints.GetLast(); if(last) { pFunctionPoint* lastPoint=(pFunctionPoint*)last->GetData(); setEndX(lastPoint->getRealX()); setEndY(lastPoint->getRealY()); } else { setEndX(-1); setEndY(-1); } } /* * set the min value in x and y between all the points of the function */ void pLogicalFunction::setMinPoints() { int minX,minY; wxNode* node=realPoints.GetFirst(); if(node) { pFunctionPoint* point=(pFunctionPoint*)node->GetData(); minX=point->getRealX(); minY=point->getRealY(); wxNode* nextNode=node->GetNext(); while(nextNode) { point=(pFunctionPoint*)nextNode->GetData(); int x=point->getRealX(); int y=point->getRealY(); if(xGetNext(); } setMinX(minX); setMinY(minY); } else { setMinX(0); setMinY(0); } } /* * set the max value in x and y between all the points of the function */ void pLogicalFunction::setMaxPoints() { int maxX,maxY; wxNode* node=realPoints.GetFirst(); if(node) { pFunctionPoint* point=(pFunctionPoint*)node->GetData(); maxX=point->getRealX(); maxY=point->getRealY(); wxNode* nextNode=node->GetNext(); while(nextNode) { point=(pFunctionPoint*)nextNode->GetData(); int x=point->getRealX(); int y=point->getRealY(); if(x>maxX) maxX=x; if(y>maxY) maxY=y; nextNode=nextNode->GetNext(); } setMaxX(maxX); setMaxY(maxY); } else { setMaxX(0); setMaxY(0); } } /** * deletes the point given by the user from the collection of logical points of the function * IS NOT USE */ bool pLogicalFunction::DeletePoint(int aX, int aY) { wxNode* node= realPoints.GetFirst(); while(node) { pFunctionPoint* point=(pFunctionPoint*)node->GetData(); if(point->getRealX()==aX && point->getRealY()==aY) { realPoints.Erase(node); return true; } node= node->GetNext(); } return false; } /** * deletes a point of the functio given its index */ bool pLogicalFunction::deletePointAt(int index) { if(index!=-1) { wxNode* node=GetPointAt(index); if(node)//point!=NULL) { //pFunctionPoint* point=(pFunctionPoint*)node->GetData(); // JPRx bool deleted=realPoints.DeleteNode(node); //delete point; //delete node; /* if(index==0) realPoints=realPoints.; */ return deleted; } } return false; } /** * Change de coordinates of the given index point to the newCoords, if it is possible and return the result of the invoked action. * @retun Return TRUE if it was possible to do the change. A valid change is when the new x value of the point is still between the previous and next point, when condition. */ bool pLogicalFunction::changePoint(wxPoint newCoords, int movingIndexPoint) { wxNode* changingNode = GetPointAt(movingIndexPoint); bool validChange = false; int newX = newCoords.x; int newY = newCoords.y; pFunctionPoint* changingPoint = (pFunctionPoint*)changingNode -> GetData(); bool hasPrevious = movingIndexPoint>0; bool hasNext = movingIndexPoint < realPoints.size()-1; wxNode* prevNode = hasPrevious ? changingNode ->GetPrevious() : NULL; wxNode* nextNode = hasNext ? changingNode -> GetNext() : NULL; if( hasPrevious ) { pFunctionPoint* prevPoint = (pFunctionPoint*)prevNode -> GetData(); if ( hasNext ) { pFunctionPoint* nextPoint = (pFunctionPoint*) nextNode -> GetData(); validChange = ((prevPoint->getRealX()) < newX) && ((nextPoint->getRealX()) > newX); if ( (prevPoint->getRealX()) > newX ) { newX = prevPoint->getRealX()+1; validChange = true; } else if ( (nextPoint->getRealX()) < newX ) { newX = nextPoint->getRealX()-1; validChange = true; } } else { // Is the last point of the function. if ( (prevPoint->getRealX()) < newX ) { validChange = true; } else { newX = prevPoint->getRealX(); validChange = true; } } } else { if ( hasNext ) { // Is the first point of the function. pFunctionPoint* nextPoint = (pFunctionPoint*) nextNode -> GetData(); if ((nextPoint->getRealX()) > newX ) { validChange = true; } else { newX = nextPoint->getRealX(); validChange = true; } } } if( validChange ) { changingPoint -> setRealX( newX ); changingPoint -> setRealY( newY ); } return validChange; } /** * Evaluates if the given point belongs to the function. */ /* bool pLogicalFunction::hasPoint(wxPoint aPoint) { bool existPoint = false; wxNode *nextNode = realPoints.GetFirst(); while (nextNode && !existPoint) { pFunctionPoint* nextPoint = (pFunctionPoint*)nextNode->GetData(); if( nextPoint -> getRealX() == aPoint.x && nextPoint-> getRealY() == aPoint.y) { existPoint = true; } nextNode = nextNode->GetNext(); } return existPoint; } */ /** * Returns the real x values of the control points of the function. It dont includes the points calculated by interpolation. */ double* pLogicalFunction::getX_RealValues() { wxNode *nextNode = realPoints.GetFirst(); int size = realPoints.GetCount(); double * x_Values; int i=0; x_Values= new double[size]; while (nextNode) { pFunctionPoint* nextPoint = (pFunctionPoint*)nextNode->GetData(); x_Values[i] = nextPoint-> getRealX(); nextNode = nextNode->GetNext(); i++; } return x_Values; } /** * Returns the real y values of the control points of the function. It dont includes the points calculated by interpolation. */ double * pLogicalFunction::getY_RealValues() { wxNode *nextNode = realPoints.GetFirst(); int i =0; int size = realPoints.GetCount(); double * y_Values; y_Values= new double[size]; while (nextNode) { pFunctionPoint* nextPoint = (pFunctionPoint*)nextNode->GetData(); y_Values[i] = nextPoint-> getRealY(); nextNode = nextNode->GetNext(); i++; } return y_Values; } //----------------------- // Persistence //----------------------- /* Save the points of the function format: #number of points x<<"\t"<GetData(); file <getRealX()<<"\t"<getRealY()<GetNext(); } } file.close(); } /* Load the points of a function */ void pLogicalFunction::load(wxString fileName) { std::string line; std::ifstream file; file.open( (const char*)(fileName.mb_str()) ); if(file.is_open()) { std::getline(file,line); int nPoints=atoi(line.c_str()); int i=0; while(!file.eof() && i_startX = aStartX; } double pLogicalFunction::getStartX() { return this->_startX; } void pLogicalFunction::setStartY(double aStartY) { this->_startY = aStartY; } double pLogicalFunction::getStartY() { return this->_startY; } /* * ENDS */ void pLogicalFunction::setEndX(double aEndX) { this->_endX = aEndX; } double pLogicalFunction::getEndX() { return this->_endX; } void pLogicalFunction::setEndY(double aEndY) { this->_endY = aEndY; } double pLogicalFunction::getEndY() { return this->_endY; } /* * SCALES */ void pLogicalFunction::setScaleX(double aScaleX) { this->_scaleX = aScaleX; } double pLogicalFunction::getScaleX() { return this->_scaleX; } void pLogicalFunction::setScaleY(double aScaleY) { this->_scaleY = aScaleY; } double pLogicalFunction::getScaleY() { return this->_scaleY; } /* * MINS */ void pLogicalFunction::setMinX(double aMinX) { this->_minX = aMinX; } double pLogicalFunction::getMinX() { return this->_minX; } void pLogicalFunction::setMinY(double aMinY) { this->_minY = aMinY; } double pLogicalFunction::getMinY() { return this->_minY; } /* * MAXS */ void pLogicalFunction::setMaxX(double aMaxX) { this->_maxX = aMaxX; } double pLogicalFunction::getMaxX() { return this->_maxX; } void pLogicalFunction::setMaxY(double aMaxY) { this->_maxY = aMaxY; } double pLogicalFunction::getMaxY() { return this->_maxY; } /* * OFFSETS */ void pLogicalFunction::setOffsetX(double aOffsetX) { this->_offsetX = aOffsetX; } double pLogicalFunction:: getOffsetX() { return this->_offsetX; } void pLogicalFunction:: setOffsetY(double aOffsetY) { this->_offsetY = aOffsetY; } double pLogicalFunction:: getOffsetY() { return this->_offsetY; } /* * TYPE */ void pLogicalFunction:: setType(int aType) { this->_type = aType; } int pLogicalFunction :: getType() { return this->_type; } /* * ValidPoint */ int pLogicalFunction :: getValidPointRange() { return validPointRange; } void pLogicalFunction :: setValidPointRange(int theRange) { validPointRange = theRange; } /* * Returns the number of points that the function * has */ int pLogicalFunction::getSizePoints() { return realPoints.GetCount(); } void pLogicalFunction::getDirection(bool &dir) { dir = leftToRigthDef; }