//---------------------------------------------------------------------------- // Class definition include //---------------------------------------------------------------------------- #include "pGraphicalFunction.h" #include "math.h" #include #include #include #include // ---------------------------------------------------------------------------- // WX headers inclusion. // For compilers that support precompilation, includes . // ---------------------------------------------------------------------------- #ifndef WX_PRECOMP #include #endif //---------------------------------------------------------------------------- // Class implementation //---------------------------------------------------------------------------- IMPLEMENT_CLASS(pGraphicalFunction, pPlotterLayer) pGraphicalFunction:: pGraphicalFunction(wxString name, int flags) { SetName(name); showPointsF = false; validPointRange = 5; logicFunction = new pLogicalFunction (); fromWindow=false; factorZoom=1; drawing=false; editable=true; ifActual=false; zoomIn=false; setOffsetX(0); setOffsetY(0); initialDrawingPoint=NULL; finalDrawingPoint=NULL; //type=1 means that is going to be a piecewise function _type=1; xKSpline=NULL; yKSpline=NULL; offsetPixelX=0; offsetPixelY=0; xTraslation=0; mType=DEFAULT; } /** * Is the destructor!!! */ pGraphicalFunction :: ~ pGraphicalFunction () { } //set if the function has to draw the points void pGraphicalFunction::SetShowPoints(bool showPoints) { showPointsF = showPoints; } //get the paramater showPointsF bool pGraphicalFunction::getShowPoints() { return showPointsF; } /* * Set Up startPoint, endPoint, maxY,maxX points */ void pGraphicalFunction::setUp() { logicFunction->setUp(); setMaxX(logicFunction->getMaxX()); setMinX(logicFunction->getMinX()); setMaxY(logicFunction->getMaxY()); setMinY(logicFunction->getMinY()); setStartX(logicFunction->getStartX()); setEndX(logicFunction->getEndX()); setStartY(logicFunction->getStartY()); setEndY(logicFunction->getEndY()); } /* * 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-validPointRange validPointOnFunction (realPoint)); } /* * returns the index in the list of the point */ int pGraphicalFunction::getIndexOf(wxPoint realpoint) { return logicFunction -> getIndexOf( realpoint ); } /* * 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* pGraphicalFunction::GetPointAt( int movingPointIndex ) { return logicFunction -> GetPointAt ( movingPointIndex ); } /* * Set the scales of the function in x and y * */ void pGraphicalFunction::setScales() { //int dx= logicFunction->getMaxX()-logicFunction->getMinX(); //int dy= logicFunction->getMaxY()-logicFunction->getMinY(); int dx= maxShowedX-minShowedX; int dy= maxShowedY-minShowedY; if(dx!=0 && dy!=0) { double scaleX=(((float)(screenX-100))/dx)*factorZoom; double scaleY=(((float)(screenY-50))/dy)*factorZoom; setScaleX(scaleX); setScaleY(scaleY); logicFunction->setScaleX(scaleX); logicFunction->setScaleY(scaleY); } } /* * 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 pGraphicalFunction:: AddNewPoint(int x,int y) { bool added= logicFunction -> AddNewPoint ( x, y ); if(!fromWindow) setUp(); else { logicFunction->setEndPoints(); logicFunction->setStartPoints(); } return added; } /* * 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 pGraphicalFunction::AddPoint(int aX, int aY,bool order) { bool added=false; if (logicFunction!=NULL){ added=logicFunction -> AddPoint( aX, aY,order ); if(!fromWindow) setUp(); else { logicFunction->setEndPoints(); logicFunction->setStartPoints(); } // if fromWindow } // if logicFunction return added; } /** * deletes the point given by the user from the collection of logical points of the function * is not used */ bool pGraphicalFunction::DeletePoint(int aX, int aY) { bool added= logicFunction -> DeletePoint( aX, aY ); if(!fromWindow) setUp(); else { logicFunction->setEndPoints(); logicFunction->setStartPoints(); } return added; } /** * deletes a point of the functio given its index */ bool pGraphicalFunction::deletePointAt(int index) { bool added=logicFunction -> deletePointAt( index ); if(!fromWindow) setUp(); else { logicFunction->setEndPoints(); logicFunction->setStartPoints(); } return added; } /** * 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 pGraphicalFunction::changePoint(wxPoint newCoords, int movingIndexPoint) { bool added= (logicFunction -> changePoint( newCoords, movingIndexPoint )); if(!fromWindow) setUp(); else { logicFunction->setEndPoints(); logicFunction->setStartPoints(); } return added; } /** * Evaluates if the given point belongs to the function. */ /* bool pGraphicalFunction::hasPoint(wxPoint aPoint) { return logicFunction -> hasPoint( aPoint ); } */ /** * Returns the real x values of the control points of the function. It dont includes the points calculated by interpolation. */ double* pGraphicalFunction::getX_RealValues() { return (logicFunction -> getX_RealValues( )); } /** * Returns the real y values of the control points of the function. It dont includes the points calculated by interpolation. */ double * pGraphicalFunction::getY_RealValues() { return (logicFunction -> getY_RealValues()); } //---------------------------------- // Asking if it has a point (x,y) //---------------------------------- /* * returns true if the point is along the function * false otherway */ bool pGraphicalFunction:: isInFunction(int x, int y) { wxNode* before; wxNode* next; pFunctionPoint* point= new pFunctionPoint(x,y); bool inLine; before=getBefore(point); if(before && before->GetNext()) { next = before->GetNext(); //next = (before->GetNext())->GetNext(); inLine= isInLine((pFunctionPoint*)before->GetData(),(pFunctionPoint*)next->GetData(),point); } else inLine=false; return inLine; } /* * give us the point that is in the function and is exactly before * the point we are giving */ wxNode* pGraphicalFunction:: getBefore(pFunctionPoint* point) { int minDiference=10000000; wxNode* node=logicFunction->GetPointAt(0); wxNode* before=NULL; while(node) { pFunctionPoint* before1=(pFunctionPoint*)node->GetData(); int beforeX=before1->getRealX(); int pointX=point->getRealX(); if(beforeXGetNext(); } return before; } /* * Returns true if the point is in the line */ bool pGraphicalFunction::isInLine(pFunctionPoint* before,pFunctionPoint* next, pFunctionPoint* point) { int x1,x2,x,y1,y2,y; x1=(float)before->getRealX(); x2=(float)next->getRealX(); y1=(float)before->getRealY(); y2=(float)next->getRealY(); x=(float)point->getRealX(); y=(float)point->getRealY(); float d1= (float)sqrt(pow(float(x1-x),2)+ pow(float(y1-y),2)); float d2= (float)sqrt(pow(float(x2-x),2)+ pow(float(y2-y),2)); float d=(float)sqrt(pow(float(x2-x1),2)+ pow(float(y2-y1),2)); if(d1+d2<=(d*1.1) && d1<=d && d2<=d) return true; return false; } /** * give us the value of y in the line define by the arguments */ double pGraphicalFunction::interpolateY(double m, int x1,int y1,int x) { return m*(x-x1)+y1; } //---------------------------- //NEW METHODS //---------------------------- //---------------------------- // Spline Methods //---------------------------- /* * clear the spline vectors */ void pGraphicalFunction:: clearSplineVectors() { xSpline.clear(); ySpline.clear(); } /* Initiliaze xSpline and ySpline vectors */ void pGraphicalFunction:: initializeSplines() { if(xKSpline==NULL) xKSpline = vtkKochanekSpline::New(); if(yKSpline==NULL) yKSpline= vtkKochanekSpline::New(); addSplinesPoints(); } /* Add the (x,y) points of the function to the spline */ void pGraphicalFunction::addSplinesPoints() { xKSpline->RemoveAllPoints(); yKSpline->RemoveAllPoints(); wxNode *node= logicFunction->GetPointAt(0); pFunctionPoint* p; int i=0; while(node) { p=(pFunctionPoint*)node->GetData(); xKSpline->AddPoint(i,p->getRealX()); yKSpline->AddPoint(i,p->getRealY()); i++; node=node->GetNext(); } } /* This Method adds the point calculated by the splines to the vectors */ void pGraphicalFunction:: initializeSplineVectors() { double x=0,y=0,t,delta; int i,np,nps; //realPoints.DeleteC np = logicFunction->getSizePoints(); nps = 200; delta=( double ) ( np ) / ( double ) ( nps ); for( i = 0; i < nps; i++ ) { t = delta * (double)i; GetSplinePoint(t,x,y); xSpline.push_back(x); ySpline.push_back(y); } } /* get the spline point for t, in xKSpline and yKSpline */ void pGraphicalFunction::GetSplinePoint(double t, double &x, double &y) { if (logicFunction->getSizePoints()==0) { x = 0; y = 0; } if (logicFunction->getSizePoints()>=2) { x = xKSpline->Evaluate(t); y = yKSpline->Evaluate(t); } } //------------------------------ // Zoom Methods //------------------------------ /** This method set the initial point and the final point of drawing according with the width of the square around the point clicked @param clickedX @param clickedY @param width: width of the square Note: all the parameters are pixels Pre: screenX, screenY, zoom are set! with the actual data. DEPRECATED! */ void pGraphicalFunction::zooming(int clickedX,int clickedY,int width) { int xS,yS,x1,x2,y1,y2; setScales(); xS=clickedX/_scaleX+_offsetX; yS=clickedY/_scaleY+_offsetY; //square x1=(clickedX-width)/_scaleX+_offsetX; x2=(clickedX+width)/_scaleX+_offsetX; y1=(clickedY-width)/_scaleY+_offsetY; y2=(clickedY+width)/_scaleY+_offsetY; int numberPoints=getSizePoints(); pFunctionPoint* point; wxNode* p; bool inSquare=false,first=false; //if the user made a zoom if(zoomIn) { int i; for(i=0; iGetPointAt(i); point=(pFunctionPoint*)p->GetData(); int rx=point->getRealX(); int ry=point->getRealY(); inSquare= rx>=x1 && rx<=x2; //&& ry>=y1 && ry<=y2; if(inSquare) { if(!first) { initialDrawingPoint=point; _offsetX=rx; _offsetY=ry; first=true; } finalDrawingPoint=point; } } } else { //We extend the range of vision in x and y,20 and 10 respectively if((_offsetX-20)>=0) { _offsetX=_offsetX-20; } else _offsetX=0; if((_offsetY-10)>=0) { _offsetY=_offsetY-10; } else _offsetY=0; } } /* This method sets the offsets according with the point clicked on the window @param offx: x-value of the point clicked @param offx: y-value of the point clicked Note: all the parameters are pixels Pre: screenX, screenY are set! with the actual data. Pos: Sets the value of minXshowed,minYshowed */ void pGraphicalFunction::setOffsets(int offx,int offy) { int xS,yS; setScales(); xS=(offx-offsetPixelX)/_scaleX+_offsetX + minShowedX; yS=(offy-offsetPixelY)/_scaleY+_offsetY+ minShowedY; setOffsetX(xS); setOffsetY(yS); //setMinShowedX(xS); //setMinShowedY(yS); setOffsetPixelX(offx); setOffsetPixelY(offy); //setMinShowed(); } /* * This method sets the minShowedX * and the minShowedY, accordig to the offset in * x-axis and y-axis respectively * pre: _offsetX>=0,_offsetY>=0 * screenX and screenY are set with the actual size of the window * scaleX and scaleY are set to the actual size of the window * DEPRECATED! */ void pGraphicalFunction::setMinShowed() { bool firstX=false,firstY=false; wxNode* node=logicFunction->GetPointAt(0); pFunctionPoint* p; //float middleWX=(((float)(screenX-100))/2)/scaleX; // JPRx //float middleWY=(((float)(screenY-50))/2)/scaleY; // JPRx //node=node->GetNext(); while(node) { p=(pFunctionPoint*)node->GetData(); int px=p->getRealX(); int py=p->getRealY(); int x=(px-_offsetX);//+middleWX; int y=(py-_offsetY);//+middleWY; if(!firstX && x>=0) { firstX=true; setMinShowedX(px); } if(!firstY && y>=0) { firstY=true; setMinShowedY(py); } node=node->GetNext(); } } //----------------------- // Persistence //----------------------- /* Save the points of the function */ void pGraphicalFunction::save(wxString fileName) { logicFunction->save(fileName); } /* Load the points of a function */ void pGraphicalFunction::load(wxString fileName) { logicFunction->load(fileName); logicFunction->setUp(); setMaxShowedX(logicFunction->getMaxX()); setMinShowedX(logicFunction->getMinX()); setMaxShowedY(logicFunction->getMaxY()); setMinShowedY(logicFunction->getMinY()); } //-------------------------- //GETTERS AND SETTERS //--------------------------- /** * actual */ void pGraphicalFunction::setActual(bool act) { ifActual=act; } bool pGraphicalFunction:: getActual() { return ifActual; } /** * SCALE WAY * DEFECT_SCALE 1 * MAX_SCALE 2 * USER_SCALE 3 */ void pGraphicalFunction::setScaleWay(int typeS) { scaleWay=typeS; } int pGraphicalFunction:: getScaleWay() { return scaleWay; } /* * SCREEN */ void pGraphicalFunction::setScreenX(int scrX) { this->screenX=scrX; } int pGraphicalFunction::getScreenX() { return this->screenX; } void pGraphicalFunction::setScreenY(int scrY) { this->screenY=scrY; } int pGraphicalFunction::getScreenY() { return this->screenY; } /* * STARTS */ void pGraphicalFunction::setStartX(double aStartX) { logicFunction->setStartX(aStartX); this->_startX =logicFunction->getStartX(); } double pGraphicalFunction::getStartX() { return logicFunction->getStartX(); } void pGraphicalFunction::setStartY(double aStartY) { logicFunction->setStartY(aStartY); this->_startY = aStartY; } double pGraphicalFunction::getStartY() { return logicFunction->getStartY(); } /* * ENDs */ void pGraphicalFunction::setEndX(double aEndX) { logicFunction->setEndX(aEndX); this->_endX = aEndX; } double pGraphicalFunction::getEndX() { return logicFunction->getEndX(); } void pGraphicalFunction::setEndY(double aEndY) { logicFunction->setEndY(aEndY); this->_endY = aEndY; } double pGraphicalFunction::getEndY() { return logicFunction->getEndY(); } /* * SCALES */ void pGraphicalFunction::setScaleX(double aScaleX) { logicFunction->setScaleX(aScaleX); this->_scaleX = aScaleX; } double pGraphicalFunction::getScaleX() { return this->_scaleX; } void pGraphicalFunction::setScaleY(double aScaleY) { logicFunction->setScaleY(aScaleY); this->_scaleY = aScaleY; } double pGraphicalFunction::getScaleY() { return this->_scaleY; } /* * Mins */ void pGraphicalFunction::setMinX(double aMinX) { logicFunction->setMinX(aMinX); this->_minX = aMinX; } double pGraphicalFunction::getMinX() { return logicFunction->getMinX(); } void pGraphicalFunction::setMinY(double aMinY) { logicFunction->setMinY(aMinY); this->_minY = aMinY; } double pGraphicalFunction::getMinY() { return logicFunction->getMinY(); } /* * MAXS */ void pGraphicalFunction::setMaxX(double aMaxX) { logicFunction->setMaxX(aMaxX); this->_maxX = aMaxX; } double pGraphicalFunction::getMaxX() { return logicFunction->getMaxX(); } void pGraphicalFunction::setMaxY(double aMaxY) { logicFunction->setMaxY(aMaxY); this->_maxY = aMaxY; } double pGraphicalFunction::getMaxY() { return logicFunction->getMaxY(); } /* * OFFSETS */ void pGraphicalFunction::setOffsetX(double aOffsetX) { logicFunction->setOffsetX(aOffsetX); this->_offsetX = aOffsetX; } double pGraphicalFunction:: getOffsetX() { return this->_offsetX; } void pGraphicalFunction:: setOffsetY(double aOffsetY) { logicFunction->setOffsetY(aOffsetY); this->_offsetY = aOffsetY; } double pGraphicalFunction:: getOffsetY() { return this->_offsetY; } /* * TYPE */ void pGraphicalFunction:: setType(int aType) { logicFunction->setType(aType); this->_type = aType; } int pGraphicalFunction :: getType() { return this->_type; } /* * validPoint */ int pGraphicalFunction :: getValidPointRange() { return validPointRange; } void pGraphicalFunction :: setValidPointRange(int theRange) { logicFunction->setValidPointRange(theRange); validPointRange = theRange; } /* * Returns the number of points that the function * has */ int pGraphicalFunction :: getSizePoints() { return logicFunction->getSizePoints(); } /* * Sets the color points of the function by teh given parameter * @param colorVector Is the color points vector to set */ void pGraphicalFunction :: setColorPoints(std::vector &colorVector) { f_colorPoints.clear(); int i = 0; while(i<(int)(colorVector.size())) { f_colorPoints.push_back(colorVector[i]); i++; } } /* * Gets the color points of the function in the given parameter * @param colorVector Is the color points list to get the points */ void pGraphicalFunction :: getColorPoints(std::vector &colorVector) { int i = 0; while(i<(int)(f_colorPoints.size())) { pColorPoint * originaslPoint = f_colorPoints[i]; pColorPoint * copyPoint = new pColorPoint(originaslPoint->getRealX(), originaslPoint->getColor(), originaslPoint->isTemporalColor()); colorVector.push_back(copyPoint); i++; } }