00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "parametricgraph.h"
00019
00020 #include <sstream>
00021
00022 #include <qpainter.h>
00023
00024 #include "expression.h"
00025 #include "fungparser.h"
00026 #include "arclengthfunction.h"
00027
00028 ParametricGraph::ParametricGraph(QWidget *parent, const char *name) : ExpressionGraph (parent, name)
00029 {
00030 tMin = -15;
00031 tMax = 15;
00032 tStep = 0.1;
00033 }
00034
00035 ParametricGraph::~ParametricGraph()
00036 {
00037 }
00038
00039 void ParametricGraph::load_key( const char *key, const char *value )
00040 {
00041 if (strcmp(key,"Function=") == 0)
00042 {
00043 char alpha[256];
00044 std::stringstream stream(value);
00045
00046 stream.get(alpha,sizeof(alpha),':');
00047 QString sx(alpha);
00048 stream.ignore(sizeof(char));
00049
00050 stream.get(alpha,sizeof(alpha),':');
00051 QString sy(alpha);
00052 stream.ignore(sizeof(char));
00053 stream>>alpha;
00054
00055 QColor color(alpha);
00056 stream>>alpha;
00057 bool show;
00058 if ( strcmp( alpha,"0" ) == 0 )
00059 show = false;
00060 else
00061 show = true;
00062
00063 addExpression(Expression(sx,sy,show,color));
00064 nextExpression();
00065
00066 return;
00067 }
00068
00069 ExpressionGraph::load_key(key,value);
00070
00071 if (strcmp(key,"tMin=") == 0)
00072 {
00073 setTMin(QString(value).toDouble());
00074 }
00075 else if (strcmp(key,"tMax=") == 0)
00076 {
00077 setTMax(QString(value).toDouble());
00078 }
00079 else if (strcmp(key,"tStep=") == 0)
00080 {
00081 setTStep(QString(value).toDouble());
00082 }
00083 }
00084
00085 void ParametricGraph::installMathFunctions()
00086 {
00087 BasicGraph::installMathFunctions();
00088
00089 addMathFunction(new ArcLengthFunction(this,2),"Arc Length");
00090 }
00091
00092 int ParametricGraph::execMathFunction( const char * id )
00093 {
00094 MathFunction *mf = getMathFunction(id);
00095 if ( mf )
00096 {
00097 switch ( mf->expressionsRequired() )
00098 {
00099 case 0: return BasicGraph::execMathFunction(id); break;
00100 case 1:
00101 case 2:
00102 {
00103 FungParser *fpx = getParsedCurrentExpression(X_VAR);
00104 FungParser *fpy = getParsedCurrentExpression(Y_VAR);
00105 if (fpx && fpy)
00106 {
00107 mf->exec(fpx,fpy);
00108 return 0;
00109 }
00110 return -1;
00111 }
00112 default: break;
00113 }
00114 }
00115 return -1;
00116 }
00117
00118 void ParametricGraph::sendCustomClick(QMouseEvent *e, MathFunction *m, double, double)
00119 {
00120 qDebug("custom click: %f",traceDepX(toGraphXCoord(e->x())));
00121 m->sendClick(e,traceDepX(toGraphXCoord(e->x())));
00122 }
00123
00124 void ParametricGraph::putUndefinedMessage(double x, double)
00125 {
00126 emit activeCoordinateChanged( QString("%1 = %2").arg(independent_vars()).arg(traceDepX(x)),
00127 QString("%1 = Undefined").arg(dependent_var(X_VAR)),
00128 QString("%1 = Undefined").arg(dependent_var(Y_VAR)) );
00129 }
00130
00131 void ParametricGraph::updateCoords()
00132 {
00133 if (isTracing())
00134 {
00135 emit activeCoordinateChanged( QString("%1 = %2").arg(independent_vars()).arg(t_trace),
00136 QString("%1 = %2").arg(dependent_var(X_VAR)).arg(getMouseX()),
00137 QString("%1 = %2").arg(dependent_var(Y_VAR)).arg(getMouseY()) );
00138
00139 }
00140 else
00141 BasicGraph::updateCoords();
00142 }
00143
00144 void ParametricGraph::drawExpression(QPainter* painter, Expression & expression)
00145 {
00146 for (double t = tMin; t < tMax; t+=tStep)
00147 {
00148 FungParser *xfp = expression.getParsedExpression(dependent_var(X_VAR));
00149 FungParser *yfp = expression.getParsedExpression(dependent_var(Y_VAR));
00150
00151 double d[] = {t,animatorValue()};
00152
00153 double xevaluated = xfp->Eval(d);
00154 double yevaluated = yfp->Eval(d);
00155 if (xfp->EvalError() || yfp->EvalError()){continue;}
00156
00157 if (isDrawConnected())
00158 {
00159 double nexttval = t+tStep;
00160
00161 double dnext[] = {nexttval,animatorValue()};
00162
00163 double nextxevaluated = xfp->Eval(dnext);
00164 double nextyevaluated = yfp->Eval(dnext);
00165 if (xfp->EvalError() || yfp->EvalError()){continue;}
00166
00167 painter->drawLine(toPixelXCoord(xevaluated),toPixelYCoord(yevaluated),toPixelXCoord(nextxevaluated),toPixelYCoord(nextyevaluated));
00168 }
00169 else
00170 painter->drawPoint(toPixelXCoord(xevaluated),toPixelYCoord(yevaluated));
00171 }
00172
00173
00174 }
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190 int ParametricGraph::setTMin(double _tMin)
00191 {
00192 if (_tMin < tMax)
00193 {
00194 tMin = _tMin;
00195 repaint(false);
00196 return 0;
00197 }
00198 else
00199 return 1;
00200 }
00201
00202 int ParametricGraph::setTMax(double _tMax)
00203 {
00204 if (_tMax > tMin)
00205 {
00206 tMax = _tMax;
00207 repaint(false);
00208 return 0;
00209 }
00210 else
00211 return 1;
00212 }
00213
00214 int ParametricGraph::setTStep(double _tStep)
00215 {
00216 if (_tStep > 0)
00217 {
00218 tStep = _tStep;
00219 repaint(false);
00220 return 0;
00221 }
00222 else
00223 return 1;
00224 }
00225
00226 int ParametricGraph::setXYForTrace(const double mousex, const double, double *x, double *y, Expression &expression)
00227 {
00228 FungParser *fpx = expression.getParsedExpression(dependent_var(X_VAR));
00229 FungParser *fpy = expression.getParsedExpression(dependent_var(Y_VAR));
00230
00231 double d[] = {mousex,animatorValue()};
00232
00233 *x = fpx->Eval(d);
00234 *y = fpy->Eval(d);
00235
00236 t_trace = mousex;
00237
00238 return (fpx->EvalError() || fpy->EvalError());
00239 }
00240
00241
00242
00243
00244
00245
00246