2 //----------------------------------------------------------------------------
3 // Class definition include
4 //----------------------------------------------------------------------------
5 #include "pLogicalFunction.h"
11 // ----------------------------------------------------------------------------
12 // WX headers inclusion.
13 // For compilers that support precompilation, includes <wx/wx.h>.
14 // ----------------------------------------------------------------------------
20 //----------------------------------------------------------------------------
21 // Class implementation
22 //----------------------------------------------------------------------------
24 IMPLEMENT_CLASS(pLogicalFunction, wxObject)
26 //----------------------------------------------------------------------------
28 //----------------------------------------------------------------------------
29 pLogicalFunction:: pLogicalFunction( )
32 realPoints.DeleteContents(TRUE);
34 leftToRigthDef = true;
41 * Is the destructor!!!
43 pLogicalFunction:: ~pLogicalFunction ()
45 realPoints.DeleteContents(TRUE);
48 * 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
49 * x1-validPointRange<x<x1+validPointRange y1-validPointRange<y<y1+validPointRange
51 int pLogicalFunction::validPointOnFunction(wxPoint realPoint)
54 wxNode* node= realPoints.GetFirst();
55 while(node && pointIndex==-1)
57 pFunctionPoint* point=(pFunctionPoint*)node->GetData();
58 int x = point->getRealX();
59 int y = point->getRealY();
60 double vx=SENSIBLE_REGION/_scaleX;
61 double vy=SENSIBLE_REGION/_scaleY;
63 bool isInXRange= realPoint.x <= x + vx + SENSIBLE_REGION && realPoint.x >= x - vx-SENSIBLE_REGION;
64 bool isInYRange= realPoint.y <= y + vy + SENSIBLE_REGION && realPoint.y >= y - vy-SENSIBLE_REGION;
65 if(isInXRange && isInYRange)
66 pointIndex = realPoints.IndexOf(point);
68 node = node->GetNext();
76 * returns the index in the list of the point
78 int pLogicalFunction::getIndexOf(wxPoint realpoint)
80 wxNode* node= realPoints.GetFirst();
83 pFunctionPoint* point=(pFunctionPoint*)node->GetData();
84 if(point->getRealX()==realpoint.x && point->getRealY()==realpoint.y )
86 return realPoints.IndexOf(point);
89 node= node->GetNext();
96 * This metohd returns the node of the point that is the movingPointIndex position in the list of points.
97 * @param: int movingPointIndex, Is the index value of the searched node.
98 * @return: Return a pointer to the node corresponding to the index value by parameter.
100 wxNode* pLogicalFunction::GetPointAt( int movingPointIndex )
102 if(!realPoints.IsEmpty())
104 wxNode* node= realPoints.Item(movingPointIndex);
112 * Includes a point between two existing points of this function. The new point (x,y) was not defined when the function was created.
113 * @return Returns true is the point was succcesfully added to the funcion.
115 bool pLogicalFunction:: AddNewPoint(int x,int y)
117 pFunctionPoint * newPoint = new pFunctionPoint ( x, y);
118 bool includedPoint = realPoints.Append(newPoint)!=NULL;
122 if(realPoints.size()>1){
128 return includedPoint;
131 * This method orders the list of points taking into account that the last appended node in the list (realPoint) is the only one disordered.
132 * @return Returns true if the last point included has a valid value for x and was ordered, according to the definition of function.
134 bool pLogicalFunction::orderPoints()
136 bool lastOrdered = false;
137 bool validToContinue = false;
139 wxNode* lastNodeIncluded = realPoints.GetLast();
141 wxNode* node = realPoints.GetFirst();
142 pFunctionPoint* lastPointIncluded = (pFunctionPoint*)lastNodeIncluded -> GetData();
143 int xToOrder = lastPointIncluded -> getRealX();
147 // Used for validating 'leftToRigthDef'
148 pFunctionPoint* ordFirstPoint = NULL;
149 pFunctionPoint* ordLastPoint = NULL;
151 ordFirstPoint = (pFunctionPoint*)realPoints.GetFirst()-> GetData();
153 if(lastNodeIncluded->GetPrevious()!=NULL){
154 ordLastPoint = (pFunctionPoint*)(lastNodeIncluded->GetPrevious())-> GetData();
161 validToContinue = ordFirstPoint->getRealX() < xToOrder;
165 //validToContinue =ordFirstPoint->getRealX() > xToOrder;
166 validToContinue =ordLastPoint->getRealX() > xToOrder;
169 if ( validToContinue)
172 while( node && !lastOrdered )
174 pFunctionPoint* prevPoint =(pFunctionPoint*)node->GetData();
175 actualX = prevPoint ->getRealX();
176 if( actualX == xToOrder)
178 realPoints.DeleteNode(lastNodeIncluded);
181 else if ( actualX < xToOrder )
184 wxNode* nextNode = node->GetNext();
185 pFunctionPoint* nextPoint;
186 if( nextNode != lastNodeIncluded )
188 nextPoint = (pFunctionPoint*)nextNode -> GetData();
189 nextX = nextPoint->getRealX();
190 int nextIndex = realPoints.IndexOf(nextPoint);
191 if( nextX > xToOrder )
193 //we need to change the direction in memory of our node
194 pFunctionPoint* pointToInsert=new pFunctionPoint(lastPointIncluded->getRealX(),lastPointIncluded->getRealY());
195 // The last inserted point is ordered like: prevPoint - lastPointIncluded - nextPoint
196 lastOrdered = (realPoints.Insert(nextIndex, pointToInsert))!= NULL;
197 bool lastNodeDeleted=realPoints.DeleteNode(lastNodeIncluded);
198 return lastOrdered && lastNodeDeleted;
211 wxNode* prevNode = node->GetPrevious();
212 int insertIndex=realPoints.IndexOf(prevPoint);
213 pFunctionPoint* prPoint;
216 prPoint = (pFunctionPoint*)prevNode -> GetData();
217 int beforeX =prPoint->getRealX();
218 if( beforeX < xToOrder)
220 //we need to change the direction in memory of our node
221 pFunctionPoint* pointToInsert=new pFunctionPoint(lastPointIncluded->getRealX(),lastPointIncluded->getRealY());
222 // The last inserted point is ordered like: prevPoint - lastPointIncluded - nextPoint
223 lastOrdered = (realPoints.Insert(insertIndex, pointToInsert))!= NULL;
224 bool lastNodeDeleted=realPoints.DeleteNode(lastNodeIncluded);
225 return lastOrdered && lastNodeDeleted;
228 //is just the second point
231 //we need to change the direction in memory of our node
232 pFunctionPoint* pointToInsert=new pFunctionPoint(lastPointIncluded->getRealX(),lastPointIncluded->getRealY());
233 // The last inserted point is ordered like: prevPoint - lastPointIncluded - nextPoint
234 lastOrdered = (realPoints.Insert(insertIndex, pointToInsert))!= NULL;
235 bool lastNodeDeleted=realPoints.DeleteNode(lastNodeIncluded);
236 return lastOrdered && lastNodeDeleted;
240 node = node->GetNext();
246 bool lastNodeDeleted = realPoints.DeleteNode(lastNodeIncluded);
247 lastOrdered = lastOrdered && lastNodeDeleted;
252 * This tries to Add a point to the function if possible it returns true.
253 * @pre: The list of existing points is ordered.
254 * @param: int aX, The x value of the point.
255 * @param: int aY, The y value of the point.
256 * @param: return Returns TRUE if the point was succesfuly included in the realPoints list.
258 bool pLogicalFunction::AddPoint(int aX, int aY,bool order)
260 pFunctionPoint * newPoint = new pFunctionPoint (aX, aY);
261 wxNode* lastNode = realPoints.GetLast();
262 bool addedPoint = false;
265 pFunctionPoint* lastPoint = (pFunctionPoint*)lastNode->GetData();
266 if( lastPoint->getRealX() != aX )
268 addedPoint = realPoints.Append(newPoint)!=NULL;
269 //In case that the definition of points is being done backwards.
270 if( (aX < (lastPoint->getRealX()) ) && addedPoint )
272 if( realPoints.GetCount() == 2 )
274 leftToRigthDef = false;
277 addedPoint = orderPoints();
282 if( realPoints.GetCount() == 2 )
284 leftToRigthDef = true;
291 addedPoint = realPoints.Append(newPoint)!=NULL;
298 * Set Up startPoint, endPoint, maxY,maxX points
300 void pLogicalFunction::setUp()
302 //sets the start point of the function
304 //set the Last point of the function
306 //set the min value in x and y between all the points of the function
308 //set the max value in x and y between all the points of the function
314 * sets the start point of the function
316 void pLogicalFunction:: setStartPoints()
318 wxNode* first=realPoints.GetFirst();
321 pFunctionPoint* startPoint=(pFunctionPoint*)first->GetData();
322 setStartX(startPoint->getRealX());
323 setStartY(startPoint->getRealY());
332 * sets the end point of the function
334 void pLogicalFunction:: setEndPoints()
336 wxNode* last=realPoints.GetLast();
339 pFunctionPoint* lastPoint=(pFunctionPoint*)last->GetData();
340 setEndX(lastPoint->getRealX());
341 setEndY(lastPoint->getRealY());
352 * set the min value in x and y between all the points of the function
354 void pLogicalFunction::setMinPoints()
357 wxNode* node=realPoints.GetFirst();
360 pFunctionPoint* point=(pFunctionPoint*)node->GetData();
361 minX=point->getRealX();
362 minY=point->getRealY();
363 wxNode* nextNode=node->GetNext();
366 point=(pFunctionPoint*)nextNode->GetData();
367 int x=point->getRealX();
368 int y=point->getRealY();
373 nextNode=nextNode->GetNext();
386 * set the max value in x and y between all the points of the function
388 void pLogicalFunction::setMaxPoints()
391 wxNode* node=realPoints.GetFirst();
394 pFunctionPoint* point=(pFunctionPoint*)node->GetData();
395 maxX=point->getRealX();
396 maxY=point->getRealY();
397 wxNode* nextNode=node->GetNext();
400 point=(pFunctionPoint*)nextNode->GetData();
401 int x=point->getRealX();
402 int y=point->getRealY();
407 nextNode=nextNode->GetNext();
420 * deletes the point given by the user from the collection of logical points of the function
424 bool pLogicalFunction::DeletePoint(int aX, int aY)
426 wxNode* node= realPoints.GetFirst();
429 pFunctionPoint* point=(pFunctionPoint*)node->GetData();
430 if(point->getRealX()==aX && point->getRealY()==aY)
432 realPoints.Erase(node);
435 node= node->GetNext();
442 * deletes a point of the functio given its index
444 bool pLogicalFunction::deletePointAt(int index)
448 wxNode* node=GetPointAt(index);
450 if(node)//point!=NULL)
452 //pFunctionPoint* point=(pFunctionPoint*)node->GetData(); // JPRx
453 bool deleted=realPoints.DeleteNode(node);
458 realPoints=realPoints.;
467 * Change de coordinates of the given index point to the newCoords, if it is possible and return the result of the invoked action.
468 * @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.
470 bool pLogicalFunction::changePoint(wxPoint newCoords, int movingIndexPoint)
472 wxNode* changingNode = GetPointAt(movingIndexPoint);
473 bool validChange = false;
474 int newX = newCoords.x;
475 int newY = newCoords.y;
476 pFunctionPoint* changingPoint = (pFunctionPoint*)changingNode -> GetData();
477 bool hasPrevious = movingIndexPoint>0;
478 bool hasNext = movingIndexPoint < realPoints.size()-1;
480 wxNode* prevNode = hasPrevious ? changingNode ->GetPrevious() : NULL;
481 wxNode* nextNode = hasNext ? changingNode -> GetNext() : NULL;
485 pFunctionPoint* prevPoint = (pFunctionPoint*)prevNode -> GetData();
488 pFunctionPoint* nextPoint = (pFunctionPoint*) nextNode -> GetData();
489 validChange = ((prevPoint->getRealX()) < newX) && ((nextPoint->getRealX()) > newX);
490 if ( (prevPoint->getRealX()) > newX )
492 newX = prevPoint->getRealX()+1;
495 else if ( (nextPoint->getRealX()) < newX )
497 newX = nextPoint->getRealX()-1;
503 // Is the last point of the function.
504 if ( (prevPoint->getRealX()) < newX )
510 newX = prevPoint->getRealX();
519 // Is the first point of the function.
520 pFunctionPoint* nextPoint = (pFunctionPoint*) nextNode -> GetData();
521 if ((nextPoint->getRealX()) > newX )
527 newX = nextPoint->getRealX();
534 changingPoint -> setRealX( newX );
535 changingPoint -> setRealY( newY );
540 * Evaluates if the given point belongs to the function.
543 bool pLogicalFunction::hasPoint(wxPoint aPoint)
545 bool existPoint = false;
546 wxNode *nextNode = realPoints.GetFirst();
548 while (nextNode && !existPoint)
550 pFunctionPoint* nextPoint = (pFunctionPoint*)nextNode->GetData();
551 if( nextPoint -> getRealX() == aPoint.x && nextPoint-> getRealY() == aPoint.y)
555 nextNode = nextNode->GetNext();
561 * Returns the real x values of the control points of the function. It dont includes the points calculated by interpolation.
563 double* pLogicalFunction::getX_RealValues()
565 wxNode *nextNode = realPoints.GetFirst();
566 int size = realPoints.GetCount();
570 x_Values= new double[size];
574 pFunctionPoint* nextPoint = (pFunctionPoint*)nextNode->GetData();
575 x_Values[i] = nextPoint-> getRealX();
576 nextNode = nextNode->GetNext();
583 * Returns the real y values of the control points of the function. It dont includes the points calculated by interpolation.
585 double * pLogicalFunction::getY_RealValues()
587 wxNode *nextNode = realPoints.GetFirst();
589 int size = realPoints.GetCount();
592 y_Values= new double[size];
596 pFunctionPoint* nextPoint = (pFunctionPoint*)nextNode->GetData();
597 y_Values[i] = nextPoint-> getRealY();
598 nextNode = nextNode->GetNext();
604 //-----------------------
606 //-----------------------
609 Save the points of the function
613 for all (x,y) in the function
615 void pLogicalFunction::save(wxString fileName)
619 file.open( (const char*)(fileName.mb_str()) );
622 file << getSizePoints()<< std::endl;
623 wxNode* node= realPoints.GetFirst();
627 p=(pFunctionPoint*)node->GetData();
628 file <<p->getRealX()<<"\t"<<p->getRealY()<<std::endl;
629 node=node->GetNext();
635 Load the points of a function
637 void pLogicalFunction::load(wxString fileName)
641 file.open( (const char*)(fileName.mb_str()) );
645 std::getline(file,line);
646 int nPoints=atoi(line.c_str());
648 while(!file.eof() && i<nPoints)
650 std::getline(file,line);
651 int pos=line.find("\t");
652 int size=line.size();
653 std::string x=line.substr(0,pos);
654 std::string y=line.substr(pos+1,size);
655 int x0=atoi(x.c_str());
656 int y0=atoi(y.c_str());
665 //---------------------
666 //Getters and Setters
667 //---------------------
672 void pLogicalFunction::setStartX(double aStartX) {
673 this->_startX = aStartX;
676 double pLogicalFunction::getStartX() {
677 return this->_startX;
680 void pLogicalFunction::setStartY(double aStartY) {
681 this->_startY = aStartY;
684 double pLogicalFunction::getStartY() {
685 return this->_startY;
691 void pLogicalFunction::setEndX(double aEndX) {
695 double pLogicalFunction::getEndX() {
699 void pLogicalFunction::setEndY(double aEndY) {
703 double pLogicalFunction::getEndY() {
709 void pLogicalFunction::setScaleX(double aScaleX) {
710 this->_scaleX = aScaleX;
713 double pLogicalFunction::getScaleX() {
714 return this->_scaleX;
717 void pLogicalFunction::setScaleY(double aScaleY) {
718 this->_scaleY = aScaleY;
721 double pLogicalFunction::getScaleY() {
722 return this->_scaleY;
727 void pLogicalFunction::setMinX(double aMinX) {
731 double pLogicalFunction::getMinX() {
735 void pLogicalFunction::setMinY(double aMinY) {
739 double pLogicalFunction::getMinY() {
745 void pLogicalFunction::setMaxX(double aMaxX) {
749 double pLogicalFunction::getMaxX() {
753 void pLogicalFunction::setMaxY(double aMaxY) {
757 double pLogicalFunction::getMaxY() {
764 void pLogicalFunction::setOffsetX(double aOffsetX) {
765 this->_offsetX = aOffsetX;
768 double pLogicalFunction:: getOffsetX() {
769 return this->_offsetX;
772 void pLogicalFunction:: setOffsetY(double aOffsetY) {
773 this->_offsetY = aOffsetY;
776 double pLogicalFunction:: getOffsetY() {
777 return this->_offsetY;
783 void pLogicalFunction:: setType(int aType) {
787 int pLogicalFunction :: getType() {
794 int pLogicalFunction :: getValidPointRange()
796 return validPointRange;
799 void pLogicalFunction :: setValidPointRange(int theRange)
801 validPointRange = theRange;
804 * Returns the number of points that the function
807 int pLogicalFunction::getSizePoints()
809 return realPoints.GetCount();
811 void pLogicalFunction::getDirection(bool &dir)
813 dir = leftToRigthDef;