00001
00002
00003
00004
00005 #include "pLogicalFunction.h"
00006 #include <iostream>
00007 #include <fstream>
00008 #include <string>
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef WX_PRECOMP
00017 #include <wx/wx.h>
00018 #endif
00019
00020
00021
00022
00023
00024 IMPLEMENT_CLASS(pLogicalFunction, wxObject)
00025
00026
00027
00028
00029 pLogicalFunction:: pLogicalFunction( )
00030 {
00031
00032 realPoints.DeleteContents(TRUE);
00033 validPointRange = 5;
00034 leftToRigthDef = true;
00035 _maxX=0;
00036 _maxY=0;
00037 _minX=0;
00038 _minY=0;
00039 }
00043 pLogicalFunction:: ~pLogicalFunction ()
00044 {
00045 realPoints.DeleteContents(TRUE);
00046 }
00047
00048
00049
00050
00051 int pLogicalFunction::validPointOnFunction(wxPoint realPoint)
00052 {
00053 int pointIndex = -1;
00054 wxNode* node= realPoints.GetFirst();
00055 while(node && pointIndex==-1)
00056 {
00057 pFunctionPoint* point=(pFunctionPoint*)node->GetData();
00058 int x = point->getRealX();
00059 int y = point->getRealY();
00060 double vx=SENSIBLE_REGION/_scaleX;
00061 double vy=SENSIBLE_REGION/_scaleY;
00062
00063 bool isInXRange= realPoint.x <= x + vx + SENSIBLE_REGION && realPoint.x >= x - vx-SENSIBLE_REGION;
00064 bool isInYRange= realPoint.y <= y + vy + SENSIBLE_REGION && realPoint.y >= y - vy-SENSIBLE_REGION;
00065 if(isInXRange && isInYRange)
00066 pointIndex = realPoints.IndexOf(point);
00067
00068 node = node->GetNext();
00069 }
00070 return pointIndex;
00071 }
00072
00073
00074
00075
00076
00077
00078 int pLogicalFunction::getIndexOf(wxPoint realpoint)
00079 {
00080 wxNode* node= realPoints.GetFirst();
00081 while(node)
00082 {
00083 pFunctionPoint* point=(pFunctionPoint*)node->GetData();
00084 if(point->getRealX()==realpoint.x && point->getRealY()==realpoint.y )
00085 {
00086 return realPoints.IndexOf(point);
00087 }
00088
00089 node= node->GetNext();
00090 }
00091 return -1;
00092
00093 }
00094
00095
00096
00097
00098
00099
00100 wxNode* pLogicalFunction::GetPointAt( int movingPointIndex )
00101 {
00102 if(!realPoints.IsEmpty())
00103 {
00104 wxNode* node= realPoints.Item(movingPointIndex);
00105 return node;
00106 }
00107 else
00108 return NULL;
00109 }
00110
00111
00112
00113
00114
00115 bool pLogicalFunction:: AddNewPoint(int x,int y)
00116 {
00117 pFunctionPoint * newPoint = new pFunctionPoint ( x, y);
00118 bool includedPoint = realPoints.Append(newPoint)!=NULL;
00119 if(includedPoint)
00120 {
00121 bool order=orderPoints();
00122 return order;
00123 }
00124 return includedPoint;
00125 }
00126
00127
00128
00129
00130 bool pLogicalFunction::orderPoints()
00131 {
00132 bool lastOrdered = false;
00133 bool validToContinue = false;
00134
00135 wxNode* lastNodeIncluded = realPoints.GetLast();
00136
00137 wxNode* node = realPoints.GetFirst();
00138 pFunctionPoint* lastPointIncluded = (pFunctionPoint*)lastNodeIncluded -> GetData();
00139 int xToOrder = lastPointIncluded -> getRealX();
00140 int actualX;
00141 int nextX;
00142
00143
00144 pFunctionPoint* ordFirstPoint = (pFunctionPoint*)realPoints.GetFirst()-> GetData();
00145 pFunctionPoint* ordLastPoint = (pFunctionPoint*)(lastNodeIncluded->GetPrevious())-> GetData();
00146
00147
00148
00149 if (leftToRigthDef)
00150 {
00151 validToContinue = ordFirstPoint->getRealX() < xToOrder;
00152 }
00153 else
00154 {
00155
00156 validToContinue =ordLastPoint->getRealX() > xToOrder;
00157 }
00158
00159 if ( validToContinue)
00160 {
00161
00162 while( node && !lastOrdered )
00163 {
00164 pFunctionPoint* prevPoint =(pFunctionPoint*)node->GetData();
00165 actualX = prevPoint ->getRealX();
00166 if( actualX == xToOrder)
00167 {
00168 realPoints.DeleteNode(lastNodeIncluded);
00169 lastOrdered = false;
00170 }
00171 else if ( actualX < xToOrder )
00172 {
00173
00174 wxNode* nextNode = node->GetNext();
00175 pFunctionPoint* nextPoint;
00176 if( nextNode != lastNodeIncluded )
00177 {
00178 nextPoint = (pFunctionPoint*)nextNode -> GetData();
00179 nextX = nextPoint->getRealX();
00180 int nextIndex = realPoints.IndexOf(nextPoint);
00181 if( nextX > xToOrder )
00182 {
00183
00184 pFunctionPoint* pointToInsert=new pFunctionPoint(lastPointIncluded->getRealX(),lastPointIncluded->getRealY());
00185
00186 lastOrdered = (realPoints.Insert(nextIndex, pointToInsert))!= NULL;
00187 bool lastNodeDeleted=realPoints.DeleteNode(lastNodeIncluded);
00188 return lastOrdered && lastNodeDeleted;
00189
00190 }
00191
00192 }
00193 else
00194 {
00195 lastOrdered = true;
00196 }
00197 }
00198 else
00199 {
00200
00201 wxNode* prevNode = node->GetPrevious();
00202 int insertIndex=realPoints.IndexOf(prevPoint);
00203 pFunctionPoint* prPoint;
00204 if(prevNode)
00205 {
00206 prPoint = (pFunctionPoint*)prevNode -> GetData();
00207 int beforeX =prPoint->getRealX();
00208 if( beforeX < xToOrder)
00209 {
00210
00211 pFunctionPoint* pointToInsert=new pFunctionPoint(lastPointIncluded->getRealX(),lastPointIncluded->getRealY());
00212
00213 lastOrdered = (realPoints.Insert(insertIndex, pointToInsert))!= NULL;
00214 bool lastNodeDeleted=realPoints.DeleteNode(lastNodeIncluded);
00215 return lastOrdered && lastNodeDeleted;
00216 }
00217 }
00218
00219 else
00220 {
00221
00222 pFunctionPoint* pointToInsert=new pFunctionPoint(lastPointIncluded->getRealX(),lastPointIncluded->getRealY());
00223
00224 lastOrdered = (realPoints.Insert(insertIndex, pointToInsert))!= NULL;
00225 bool lastNodeDeleted=realPoints.DeleteNode(lastNodeIncluded);
00226 return lastOrdered && lastNodeDeleted;
00227 }
00228 }
00229
00230 node = node->GetNext();
00231 }
00232
00233 }
00234 else
00235 {
00236 bool lastNodeDeleted = realPoints.DeleteNode(lastNodeIncluded);
00237 lastOrdered = lastOrdered && lastNodeDeleted;
00238 }
00239 return lastOrdered;
00240 }
00241
00242
00243
00244
00245
00246
00247
00248 bool pLogicalFunction::AddPoint(int aX, int aY,bool order)
00249 {
00250 pFunctionPoint * newPoint = new pFunctionPoint (aX, aY);
00251 wxNode* lastNode = realPoints.GetLast();
00252 bool addedPoint = false;
00253 if (lastNode)
00254 {
00255 pFunctionPoint* lastPoint = (pFunctionPoint*)lastNode->GetData();
00256 if( lastPoint->getRealX() != aX )
00257 {
00258 addedPoint = realPoints.Append(newPoint)!=NULL;
00259
00260 if( (aX < (lastPoint->getRealX()) ) && addedPoint )
00261 {
00262 if( realPoints.GetCount() == 2 )
00263 {
00264 leftToRigthDef = false;
00265 }
00266 if(order)
00267 addedPoint = orderPoints();
00268
00269 }
00270 else
00271 {
00272 if( realPoints.GetCount() == 2 )
00273 {
00274 leftToRigthDef = true;
00275 }
00276 }
00277 }
00278 }
00279 else
00280 {
00281 addedPoint = realPoints.Append(newPoint)!=NULL;
00282 }
00283
00284 return addedPoint;
00285 }
00286
00287
00288
00289
00290 void pLogicalFunction::setUp()
00291 {
00292
00293 setStartPoints();
00294
00295 setEndPoints();
00296
00297 setMinPoints();
00298
00299 setMaxPoints();
00300 }
00301
00302
00303
00304
00305
00306 void pLogicalFunction:: setStartPoints()
00307 {
00308 wxNode* first=realPoints.GetFirst();
00309 if(first)
00310 {
00311 pFunctionPoint* startPoint=(pFunctionPoint*)first->GetData();
00312 setStartX(startPoint->getRealX());
00313 setStartY(startPoint->getRealY());
00314 }
00315 else
00316 {
00317 setStartX(-1);
00318 setStartY(-1);
00319 }
00320 }
00321
00322
00323
00324 void pLogicalFunction:: setEndPoints()
00325 {
00326 wxNode* last=realPoints.GetLast();
00327 if(last)
00328 {
00329 pFunctionPoint* lastPoint=(pFunctionPoint*)last->GetData();
00330 setEndX(lastPoint->getRealX());
00331 setEndY(lastPoint->getRealY());
00332 }
00333 else
00334 {
00335 setEndX(-1);
00336 setEndY(-1);
00337
00338 }
00339 }
00340
00341
00342
00343
00344 void pLogicalFunction::setMinPoints()
00345 {
00346 int minX,minY;
00347 wxNode* node=realPoints.GetFirst();
00348 if(node)
00349 {
00350 pFunctionPoint* point=(pFunctionPoint*)node->GetData();
00351 minX=point->getRealX();
00352 minY=point->getRealY();
00353 wxNode* nextNode=node->GetNext();
00354 while(nextNode)
00355 {
00356 point=(pFunctionPoint*)nextNode->GetData();
00357 int x=point->getRealX();
00358 int y=point->getRealY();
00359 if(x<minX)
00360 minX=x;
00361 if(y<minY)
00362 minY=y;
00363 nextNode=nextNode->GetNext();
00364 }
00365 setMinX(minX);
00366 setMinY(minY);
00367 }
00368 else
00369 {
00370 setMinX(0);
00371 setMinY(0);
00372 }
00373
00374 }
00375
00376
00377
00378 void pLogicalFunction::setMaxPoints()
00379 {
00380 int maxX,maxY;
00381 wxNode* node=realPoints.GetFirst();
00382 if(node)
00383 {
00384 pFunctionPoint* point=(pFunctionPoint*)node->GetData();
00385 maxX=point->getRealX();
00386 maxY=point->getRealY();
00387 wxNode* nextNode=node->GetNext();
00388 while(nextNode)
00389 {
00390 point=(pFunctionPoint*)nextNode->GetData();
00391 int x=point->getRealX();
00392 int y=point->getRealY();
00393 if(x>maxX)
00394 maxX=x;
00395 if(y>maxY)
00396 maxY=y;
00397 nextNode=nextNode->GetNext();
00398 }
00399 setMaxX(maxX);
00400 setMaxY(maxY);
00401 }
00402 else
00403 {
00404 setMaxX(0);
00405 setMaxY(0);
00406 }
00407 }
00408
00414 bool pLogicalFunction::DeletePoint(int aX, int aY)
00415 {
00416 wxNode* node= realPoints.GetFirst();
00417 while(node)
00418 {
00419 pFunctionPoint* point=(pFunctionPoint*)node->GetData();
00420 if(point->getRealX()==aX && point->getRealY()==aY)
00421 {
00422 realPoints.Erase(node);
00423 return true;
00424 }
00425 node= node->GetNext();
00426 }
00427
00428 return false;
00429 }
00430
00434 bool pLogicalFunction::deletePointAt(int index)
00435 {
00436 if(index!=-1)
00437 {
00438 wxNode* node=GetPointAt(index);
00439
00440 if(node)
00441 {
00442
00443 bool deleted=realPoints.DeleteNode(node);
00444
00445
00446
00447
00448
00449
00450 return deleted;
00451 }
00452 }
00453 return false;
00454 }
00455
00460 bool pLogicalFunction::changePoint(wxPoint newCoords, int movingIndexPoint)
00461 {
00462 wxNode* changingNode = GetPointAt(movingIndexPoint);
00463 bool validChange = false;
00464 int newX = newCoords.x;
00465 int newY = newCoords.y;
00466 pFunctionPoint* changingPoint = (pFunctionPoint*)changingNode -> GetData();
00467 bool hasPrevious = movingIndexPoint>0;
00468 bool hasNext = movingIndexPoint < realPoints.size()-1;
00469
00470 wxNode* prevNode = hasPrevious ? changingNode ->GetPrevious() : NULL;
00471 wxNode* nextNode = hasNext ? changingNode -> GetNext() : NULL;
00472
00473 if( hasPrevious )
00474 {
00475 pFunctionPoint* prevPoint = (pFunctionPoint*)prevNode -> GetData();
00476 if ( hasNext )
00477 {
00478 pFunctionPoint* nextPoint = (pFunctionPoint*) nextNode -> GetData();
00479 validChange = ((prevPoint->getRealX()) < newX) && ((nextPoint->getRealX()) > newX);
00480 if ( (prevPoint->getRealX()) > newX )
00481 {
00482 newX = prevPoint->getRealX()+1;
00483 validChange = true;
00484 }
00485 else if ( (nextPoint->getRealX()) < newX )
00486 {
00487 newX = nextPoint->getRealX()-1;
00488 validChange = true;
00489 }
00490 }
00491 else
00492 {
00493
00494 if ( (prevPoint->getRealX()) < newX )
00495 {
00496 validChange = true;
00497 }
00498 else
00499 {
00500 newX = prevPoint->getRealX();
00501 validChange = true;
00502 }
00503 }
00504 }
00505 else
00506 {
00507 if ( hasNext )
00508 {
00509
00510 pFunctionPoint* nextPoint = (pFunctionPoint*) nextNode -> GetData();
00511 if ((nextPoint->getRealX()) > newX )
00512 {
00513 validChange = true;
00514 }
00515 else
00516 {
00517 newX = nextPoint->getRealX();
00518 validChange = true;
00519 }
00520 }
00521 }
00522 if( validChange )
00523 {
00524 changingPoint -> setRealX( newX );
00525 changingPoint -> setRealY( newY );
00526 }
00527 return validChange;
00528 }
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00553 double* pLogicalFunction::getX_RealValues()
00554 {
00555 wxNode *nextNode = realPoints.GetFirst();
00556 int size = realPoints.GetCount();
00557 double * x_Values;
00558 int i=0;
00559
00560 x_Values= new double[size];
00561
00562 while (nextNode)
00563 {
00564 pFunctionPoint* nextPoint = (pFunctionPoint*)nextNode->GetData();
00565 x_Values[i] = nextPoint-> getRealX();
00566 nextNode = nextNode->GetNext();
00567 i++;
00568 }
00569 return x_Values;
00570 }
00571
00575 double * pLogicalFunction::getY_RealValues()
00576 {
00577 wxNode *nextNode = realPoints.GetFirst();
00578 int i =0;
00579 int size = realPoints.GetCount();
00580 double * y_Values;
00581
00582 y_Values= new double[size];
00583
00584 while (nextNode)
00585 {
00586 pFunctionPoint* nextPoint = (pFunctionPoint*)nextNode->GetData();
00587 y_Values[i] = nextPoint-> getRealY();
00588 nextNode = nextNode->GetNext();
00589 i++;
00590 }
00591 return y_Values;
00592 }
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605 void pLogicalFunction::save(wxString fileName)
00606 {
00607
00608 std::ofstream file;
00609 file.open( (const char*)(fileName.mb_str()) );
00610 if(file.is_open())
00611 {
00612 file << getSizePoints()<< std::endl;
00613 wxNode* node= realPoints.GetFirst();
00614 pFunctionPoint* p;
00615 while(node)
00616 {
00617 p=(pFunctionPoint*)node->GetData();
00618 file <<p->getRealX()<<"\t"<<p->getRealY()<<std::endl;
00619 node=node->GetNext();
00620 }
00621 }
00622 file.close();
00623 }
00624
00625
00626
00627 void pLogicalFunction::load(wxString fileName)
00628 {
00629 std::string line;
00630 std::ifstream file;
00631 file.open( (const char*)(fileName.mb_str()) );
00632
00633 if(file.is_open())
00634 {
00635 std::getline(file,line);
00636 int nPoints=atoi(line.c_str());
00637 int i=0;
00638 while(!file.eof() && i<nPoints)
00639 {
00640 std::getline(file,line);
00641 int pos=line.find("\t");
00642 int size=line.size();
00643 std::string x=line.substr(0,pos);
00644 std::string y=line.substr(pos+1,size);
00645 int x0=atoi(x.c_str());
00646 int y0=atoi(y.c_str());
00647 AddPoint(x0,y0);
00648 i++;
00649
00650 }
00651 }
00652 }
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662 void pLogicalFunction::setStartX(double aStartX) {
00663 this->_startX = aStartX;
00664 }
00665
00666 double pLogicalFunction::getStartX() {
00667 return this->_startX;
00668 }
00669
00670 void pLogicalFunction::setStartY(double aStartY) {
00671 this->_startY = aStartY;
00672 }
00673
00674 double pLogicalFunction::getStartY() {
00675 return this->_startY;
00676 }
00677
00678
00679
00680
00681 void pLogicalFunction::setEndX(double aEndX) {
00682 this->_endX = aEndX;
00683 }
00684
00685 double pLogicalFunction::getEndX() {
00686 return this->_endX;
00687 }
00688
00689 void pLogicalFunction::setEndY(double aEndY) {
00690 this->_endY = aEndY;
00691 }
00692
00693 double pLogicalFunction::getEndY() {
00694 return this->_endY;
00695 }
00696
00697
00698
00699 void pLogicalFunction::setScaleX(double aScaleX) {
00700 this->_scaleX = aScaleX;
00701 }
00702
00703 double pLogicalFunction::getScaleX() {
00704 return this->_scaleX;
00705 }
00706
00707 void pLogicalFunction::setScaleY(double aScaleY) {
00708 this->_scaleY = aScaleY;
00709 }
00710
00711 double pLogicalFunction::getScaleY() {
00712 return this->_scaleY;
00713 }
00714
00715
00716
00717 void pLogicalFunction::setMinX(double aMinX) {
00718 this->_minX = aMinX;
00719 }
00720
00721 double pLogicalFunction::getMinX() {
00722 return this->_minX;
00723 }
00724
00725 void pLogicalFunction::setMinY(double aMinY) {
00726 this->_minY = aMinY;
00727 }
00728
00729 double pLogicalFunction::getMinY() {
00730 return this->_minY;
00731 }
00732
00733
00734
00735 void pLogicalFunction::setMaxX(double aMaxX) {
00736 this->_maxX = aMaxX;
00737 }
00738
00739 double pLogicalFunction::getMaxX() {
00740 return this->_maxX;
00741 }
00742
00743 void pLogicalFunction::setMaxY(double aMaxY) {
00744 this->_maxY = aMaxY;
00745 }
00746
00747 double pLogicalFunction::getMaxY() {
00748 return this->_maxY;
00749 }
00750
00751
00752
00753
00754 void pLogicalFunction::setOffsetX(double aOffsetX) {
00755 this->_offsetX = aOffsetX;
00756 }
00757
00758 double pLogicalFunction:: getOffsetX() {
00759 return this->_offsetX;
00760 }
00761
00762 void pLogicalFunction:: setOffsetY(double aOffsetY) {
00763 this->_offsetY = aOffsetY;
00764 }
00765
00766 double pLogicalFunction:: getOffsetY() {
00767 return this->_offsetY;
00768 }
00769
00770
00771
00772
00773 void pLogicalFunction:: setType(int aType) {
00774 this->_type = aType;
00775 }
00776
00777 int pLogicalFunction :: getType() {
00778 return this->_type;
00779 }
00780
00781
00782
00783
00784 int pLogicalFunction :: getValidPointRange()
00785 {
00786 return validPointRange;
00787 }
00788
00789 void pLogicalFunction :: setValidPointRange(int theRange)
00790 {
00791 validPointRange = theRange;
00792 }
00793
00794
00795
00796
00797 int pLogicalFunction::getSizePoints()
00798 {
00799 return realPoints.GetCount();
00800 }
00801 void pLogicalFunction::getDirection(bool &dir)
00802 {
00803 dir = leftToRigthDef;
00804 }
00805
00806