1 /*# ---------------------------------------------------------------------
3 # Copyright (c) CREATIS (Centre de Recherche en Acquisition et Traitement de l'Image
5 # Authors : Eduardo Davila, Frederic Cervenansky, Claire Mouton
6 # Previous Authors : Laurent Guigues, Jean-Pierre Roux
7 # CreaTools website : www.creatis.insa-lyon.fr/site/fr/creatools_accueil
9 # This software is governed by the CeCILL-B license under French law and
10 # abiding by the rules of distribution of free software. You can use,
11 # modify and/ or redistribute the software under the terms of the CeCILL-B
12 # license as circulated by CEA, CNRS and INRIA at the following URL
13 # http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
14 # or in the file LICENSE.txt.
16 # As a counterpart to the access to the source code and rights to copy,
17 # modify and redistribute granted by the license, users are provided only
18 # with a limited warranty and the software's author, the holder of the
19 # economic rights, and the successive licensors have only limited
22 # The fact that you are presently reading this means that you have had
23 # knowledge of the CeCILL-B license and that you accept its terms.
24 # ------------------------------------------------------------------------ */
27 //----------------------------------------------------------------------------
28 // Class definition include
29 //----------------------------------------------------------------------------
30 #include "pLogicalFunction.h"
36 // ----------------------------------------------------------------------------
37 // WX headers inclusion.
38 // For compilers that support precompilation, includes <wx/wx.h>.
39 // ----------------------------------------------------------------------------
45 //----------------------------------------------------------------------------
46 // Class implementation
47 //----------------------------------------------------------------------------
49 IMPLEMENT_CLASS(pLogicalFunction, wxObject)
51 //----------------------------------------------------------------------------
53 //----------------------------------------------------------------------------
54 pLogicalFunction:: pLogicalFunction( )
57 realPoints.DeleteContents(TRUE);
59 leftToRigthDef = true;
66 * Is the destructor!!!
68 pLogicalFunction:: ~pLogicalFunction ()
70 realPoints.DeleteContents(TRUE);
73 * 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
74 * x1-validPointRange<x<x1+validPointRange y1-validPointRange<y<y1+validPointRange
76 int pLogicalFunction::validPointOnFunction(wxPoint realPoint)
79 wxNode* node= realPoints.GetFirst();
80 while(node && pointIndex==-1)
82 pFunctionPoint* point=(pFunctionPoint*)node->GetData();
83 int x = point->getRealX();
84 int y = point->getRealY();
85 double vx=SENSIBLE_REGION/_scaleX;
86 double vy=SENSIBLE_REGION/_scaleY;
88 bool isInXRange= realPoint.x <= x + vx + SENSIBLE_REGION && realPoint.x >= x - vx-SENSIBLE_REGION;
89 bool isInYRange= realPoint.y <= y + vy + SENSIBLE_REGION && realPoint.y >= y - vy-SENSIBLE_REGION;
90 if(isInXRange && isInYRange)
91 pointIndex = realPoints.IndexOf(point);
93 node = node->GetNext();
101 * returns the index in the list of the point
103 int pLogicalFunction::getIndexOf(wxPoint realpoint)
105 wxNode* node= realPoints.GetFirst();
108 pFunctionPoint* point=(pFunctionPoint*)node->GetData();
109 if(point->getRealX()==realpoint.x && point->getRealY()==realpoint.y )
111 return realPoints.IndexOf(point);
114 node= node->GetNext();
121 * This metohd returns the node of the point that is the movingPointIndex position in the list of points.
122 * @param: int movingPointIndex, Is the index value of the searched node.
123 * @return: Return a pointer to the node corresponding to the index value by parameter.
125 wxNode* pLogicalFunction::GetPointAt( int movingPointIndex )
127 if(!realPoints.IsEmpty())
129 wxNode* node= realPoints.Item(movingPointIndex);
137 * Includes a point between two existing points of this function. The new point (x,y) was not defined when the function was created.
138 * @return Returns true is the point was succcesfully added to the funcion.
140 bool pLogicalFunction:: AddNewPoint(int x,int y)
142 pFunctionPoint * newPoint = new pFunctionPoint ( x, y);
143 bool includedPoint = realPoints.Append(newPoint)!=NULL;
147 if(realPoints.size()>1){
153 return includedPoint;
156 * This method orders the list of points taking into account that the last appended node in the list (realPoint) is the only one disordered.
157 * @return Returns true if the last point included has a valid value for x and was ordered, according to the definition of function.
159 bool pLogicalFunction::orderPoints()
161 bool lastOrdered = false;
162 bool validToContinue = false;
164 wxNode* lastNodeIncluded = realPoints.GetLast();
166 wxNode* node = realPoints.GetFirst();
167 pFunctionPoint* lastPointIncluded = (pFunctionPoint*)lastNodeIncluded -> GetData();
168 int xToOrder = lastPointIncluded -> getRealX();
172 // Used for validating 'leftToRigthDef'
173 pFunctionPoint* ordFirstPoint = NULL;
174 pFunctionPoint* ordLastPoint = NULL;
176 ordFirstPoint = (pFunctionPoint*)realPoints.GetFirst()-> GetData();
178 if(lastNodeIncluded->GetPrevious()!=NULL){
179 ordLastPoint = (pFunctionPoint*)(lastNodeIncluded->GetPrevious())-> GetData();
186 validToContinue = ordFirstPoint->getRealX() < xToOrder;
190 //validToContinue =ordFirstPoint->getRealX() > xToOrder;
191 validToContinue =ordLastPoint->getRealX() > xToOrder;
194 if ( validToContinue)
197 while( node && !lastOrdered )
199 pFunctionPoint* prevPoint =(pFunctionPoint*)node->GetData();
200 actualX = prevPoint ->getRealX();
201 if( actualX == xToOrder)
203 realPoints.DeleteNode(lastNodeIncluded);
206 else if ( actualX < xToOrder )
209 wxNode* nextNode = node->GetNext();
210 pFunctionPoint* nextPoint;
211 if( nextNode != lastNodeIncluded )
213 nextPoint = (pFunctionPoint*)nextNode -> GetData();
214 nextX = nextPoint->getRealX();
215 int nextIndex = realPoints.IndexOf(nextPoint);
216 if( nextX > xToOrder )
218 //we need to change the direction in memory of our node
219 pFunctionPoint* pointToInsert=new pFunctionPoint(lastPointIncluded->getRealX(),lastPointIncluded->getRealY());
220 // The last inserted point is ordered like: prevPoint - lastPointIncluded - nextPoint
221 lastOrdered = (realPoints.Insert(nextIndex, pointToInsert))!= NULL;
222 bool lastNodeDeleted=realPoints.DeleteNode(lastNodeIncluded);
223 return lastOrdered && lastNodeDeleted;
236 wxNode* prevNode = node->GetPrevious();
237 int insertIndex=realPoints.IndexOf(prevPoint);
238 pFunctionPoint* prPoint;
241 prPoint = (pFunctionPoint*)prevNode -> GetData();
242 int beforeX =prPoint->getRealX();
243 if( beforeX < xToOrder)
245 //we need to change the direction in memory of our node
246 pFunctionPoint* pointToInsert=new pFunctionPoint(lastPointIncluded->getRealX(),lastPointIncluded->getRealY());
247 // The last inserted point is ordered like: prevPoint - lastPointIncluded - nextPoint
248 lastOrdered = (realPoints.Insert(insertIndex, pointToInsert))!= NULL;
249 bool lastNodeDeleted=realPoints.DeleteNode(lastNodeIncluded);
250 return lastOrdered && lastNodeDeleted;
253 //is just the second point
256 //we need to change the direction in memory of our node
257 pFunctionPoint* pointToInsert=new pFunctionPoint(lastPointIncluded->getRealX(),lastPointIncluded->getRealY());
258 // The last inserted point is ordered like: prevPoint - lastPointIncluded - nextPoint
259 lastOrdered = (realPoints.Insert(insertIndex, pointToInsert))!= NULL;
260 bool lastNodeDeleted=realPoints.DeleteNode(lastNodeIncluded);
261 return lastOrdered && lastNodeDeleted;
265 node = node->GetNext();
271 bool lastNodeDeleted = realPoints.DeleteNode(lastNodeIncluded);
272 lastOrdered = lastOrdered && lastNodeDeleted;
277 * This tries to Add a point to the function if possible it returns true.
278 * @pre: The list of existing points is ordered.
279 * @param: int aX, The x value of the point.
280 * @param: int aY, The y value of the point.
281 * @param: return Returns TRUE if the point was succesfuly included in the realPoints list.
283 bool pLogicalFunction::AddPoint(int aX, int aY,bool order)
285 pFunctionPoint * newPoint = new pFunctionPoint (aX, aY);
286 wxNode* lastNode = realPoints.GetLast();
287 bool addedPoint = false;
290 pFunctionPoint* lastPoint = (pFunctionPoint*)lastNode->GetData();
291 if( lastPoint->getRealX() != aX )
293 addedPoint = realPoints.Append(newPoint)!=NULL;
294 //In case that the definition of points is being done backwards.
295 if( (aX < (lastPoint->getRealX()) ) && addedPoint )
297 if( realPoints.GetCount() == 2 )
299 leftToRigthDef = false;
302 addedPoint = orderPoints();
307 if( realPoints.GetCount() == 2 )
309 leftToRigthDef = true;
316 addedPoint = realPoints.Append(newPoint)!=NULL;
323 * Set Up startPoint, endPoint, maxY,maxX points
325 void pLogicalFunction::setUp()
327 //sets the start point of the function
329 //set the Last point of the function
331 //set the min value in x and y between all the points of the function
333 //set the max value in x and y between all the points of the function
339 * sets the start point of the function
341 void pLogicalFunction:: setStartPoints()
343 wxNode* first=realPoints.GetFirst();
346 pFunctionPoint* startPoint=(pFunctionPoint*)first->GetData();
347 setStartX(startPoint->getRealX());
348 setStartY(startPoint->getRealY());
357 * sets the end point of the function
359 void pLogicalFunction:: setEndPoints()
361 wxNode* last=realPoints.GetLast();
364 pFunctionPoint* lastPoint=(pFunctionPoint*)last->GetData();
365 setEndX(lastPoint->getRealX());
366 setEndY(lastPoint->getRealY());
377 * set the min value in x and y between all the points of the function
379 void pLogicalFunction::setMinPoints()
382 wxNode* node=realPoints.GetFirst();
385 pFunctionPoint* point=(pFunctionPoint*)node->GetData();
386 minX=point->getRealX();
387 minY=point->getRealY();
388 wxNode* nextNode=node->GetNext();
391 point=(pFunctionPoint*)nextNode->GetData();
392 int x=point->getRealX();
393 int y=point->getRealY();
398 nextNode=nextNode->GetNext();
411 * set the max value in x and y between all the points of the function
413 void pLogicalFunction::setMaxPoints()
416 wxNode* node=realPoints.GetFirst();
419 pFunctionPoint* point=(pFunctionPoint*)node->GetData();
420 maxX=point->getRealX();
421 maxY=point->getRealY();
422 wxNode* nextNode=node->GetNext();
425 point=(pFunctionPoint*)nextNode->GetData();
426 int x=point->getRealX();
427 int y=point->getRealY();
432 nextNode=nextNode->GetNext();
445 * deletes the point given by the user from the collection of logical points of the function
449 bool pLogicalFunction::DeletePoint(int aX, int aY)
451 wxNode* node= realPoints.GetFirst();
454 pFunctionPoint* point=(pFunctionPoint*)node->GetData();
455 if(point->getRealX()==aX && point->getRealY()==aY)
457 realPoints.Erase(node);
460 node= node->GetNext();
467 * deletes a point of the functio given its index
469 bool pLogicalFunction::deletePointAt(int index)
473 wxNode* node=GetPointAt(index);
475 if(node)//point!=NULL)
477 //pFunctionPoint* point=(pFunctionPoint*)node->GetData(); // JPRx
478 bool deleted=realPoints.DeleteNode(node);
483 realPoints=realPoints.;
492 * Change de coordinates of the given index point to the newCoords, if it is possible and return the result of the invoked action.
493 * @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.
495 bool pLogicalFunction::changePoint(wxPoint newCoords, int movingIndexPoint)
497 wxNode* changingNode = GetPointAt(movingIndexPoint);
498 bool validChange = false;
499 int newX = newCoords.x;
500 int newY = newCoords.y;
501 pFunctionPoint* changingPoint = (pFunctionPoint*)changingNode -> GetData();
502 bool hasPrevious = movingIndexPoint>0;
503 bool hasNext = movingIndexPoint < realPoints.size()-1;
505 wxNode* prevNode = hasPrevious ? changingNode ->GetPrevious() : NULL;
506 wxNode* nextNode = hasNext ? changingNode -> GetNext() : NULL;
510 pFunctionPoint* prevPoint = (pFunctionPoint*)prevNode -> GetData();
513 pFunctionPoint* nextPoint = (pFunctionPoint*) nextNode -> GetData();
514 validChange = ((prevPoint->getRealX()) < newX) && ((nextPoint->getRealX()) > newX);
515 if ( (prevPoint->getRealX()) > newX )
517 newX = prevPoint->getRealX()+1;
520 else if ( (nextPoint->getRealX()) < newX )
522 newX = nextPoint->getRealX()-1;
528 // Is the last point of the function.
529 if ( (prevPoint->getRealX()) < newX )
535 newX = prevPoint->getRealX();
544 // Is the first point of the function.
545 pFunctionPoint* nextPoint = (pFunctionPoint*) nextNode -> GetData();
546 if ((nextPoint->getRealX()) > newX )
552 newX = nextPoint->getRealX();
559 changingPoint -> setRealX( newX );
560 changingPoint -> setRealY( newY );
565 * Evaluates if the given point belongs to the function.
568 bool pLogicalFunction::hasPoint(wxPoint aPoint)
570 bool existPoint = false;
571 wxNode *nextNode = realPoints.GetFirst();
573 while (nextNode && !existPoint)
575 pFunctionPoint* nextPoint = (pFunctionPoint*)nextNode->GetData();
576 if( nextPoint -> getRealX() == aPoint.x && nextPoint-> getRealY() == aPoint.y)
580 nextNode = nextNode->GetNext();
586 * Returns the real x values of the control points of the function. It dont includes the points calculated by interpolation.
588 double* pLogicalFunction::getX_RealValues()
590 wxNode *nextNode = realPoints.GetFirst();
591 int size = realPoints.GetCount();
595 x_Values= new double[size];
599 pFunctionPoint* nextPoint = (pFunctionPoint*)nextNode->GetData();
600 x_Values[i] = nextPoint-> getRealX();
601 nextNode = nextNode->GetNext();
608 * Returns the real y values of the control points of the function. It dont includes the points calculated by interpolation.
610 double * pLogicalFunction::getY_RealValues()
612 wxNode *nextNode = realPoints.GetFirst();
614 int size = realPoints.GetCount();
617 y_Values= new double[size];
621 pFunctionPoint* nextPoint = (pFunctionPoint*)nextNode->GetData();
622 y_Values[i] = nextPoint-> getRealY();
623 nextNode = nextNode->GetNext();
629 //-----------------------
631 //-----------------------
634 Save the points of the function
638 for all (x,y) in the function
640 void pLogicalFunction::save(wxString fileName)
644 file.open( (const char*)(fileName.mb_str()) );
647 file << getSizePoints()<< std::endl;
648 wxNode* node= realPoints.GetFirst();
652 p=(pFunctionPoint*)node->GetData();
653 file <<p->getRealX()<<"\t"<<p->getRealY()<<std::endl;
654 node=node->GetNext();
660 Load the points of a function
662 void pLogicalFunction::load(wxString fileName)
666 file.open( (const char*)(fileName.mb_str()) );
670 std::getline(file,line);
671 int nPoints=atoi(line.c_str());
673 while(!file.eof() && i<nPoints)
675 std::getline(file,line);
676 int pos=line.find("\t");
677 int size=line.size();
678 std::string x=line.substr(0,pos);
679 std::string y=line.substr(pos+1,size);
680 int x0=atoi(x.c_str());
681 int y0=atoi(y.c_str());
690 //---------------------
691 //Getters and Setters
692 //---------------------
697 void pLogicalFunction::setStartX(double aStartX) {
698 this->_startX = aStartX;
701 double pLogicalFunction::getStartX() {
702 return this->_startX;
705 void pLogicalFunction::setStartY(double aStartY) {
706 this->_startY = aStartY;
709 double pLogicalFunction::getStartY() {
710 return this->_startY;
716 void pLogicalFunction::setEndX(double aEndX) {
720 double pLogicalFunction::getEndX() {
724 void pLogicalFunction::setEndY(double aEndY) {
728 double pLogicalFunction::getEndY() {
734 void pLogicalFunction::setScaleX(double aScaleX) {
735 this->_scaleX = aScaleX;
738 double pLogicalFunction::getScaleX() {
739 return this->_scaleX;
742 void pLogicalFunction::setScaleY(double aScaleY) {
743 this->_scaleY = aScaleY;
746 double pLogicalFunction::getScaleY() {
747 return this->_scaleY;
752 void pLogicalFunction::setMinX(double aMinX) {
756 double pLogicalFunction::getMinX() {
760 void pLogicalFunction::setMinY(double aMinY) {
764 double pLogicalFunction::getMinY() {
770 void pLogicalFunction::setMaxX(double aMaxX) {
774 double pLogicalFunction::getMaxX() {
778 void pLogicalFunction::setMaxY(double aMaxY) {
782 double pLogicalFunction::getMaxY() {
789 void pLogicalFunction::setOffsetX(double aOffsetX) {
790 this->_offsetX = aOffsetX;
793 double pLogicalFunction:: getOffsetX() {
794 return this->_offsetX;
797 void pLogicalFunction:: setOffsetY(double aOffsetY) {
798 this->_offsetY = aOffsetY;
801 double pLogicalFunction:: getOffsetY() {
802 return this->_offsetY;
808 void pLogicalFunction:: setType(int aType) {
812 int pLogicalFunction :: getType() {
819 int pLogicalFunction :: getValidPointRange()
821 return validPointRange;
824 void pLogicalFunction :: setValidPointRange(int theRange)
826 validPointRange = theRange;
829 * Returns the number of points that the function
832 int pLogicalFunction::getSizePoints()
834 return realPoints.GetCount();
836 void pLogicalFunction::getDirection(bool &dir)
838 dir = leftToRigthDef;