30 #include <qtextstream.h>
31 #include <qmessagebox.h>
33 #include <qdatetime.h>
43 # define finite(x) _finite(x)
46 #if defined (__MINGW32__)
48 static double strtod_faster (
char * pPos,
char ** pEnd) {
50 while ((**pEnd) && (**pEnd >
' ') && (**pEnd !=
'j') && (**pEnd !=
'i'))
52 if ((**pEnd ==
'j') || (**pEnd ==
'i'))
54 QCString str = QCString (pPos, *pEnd - pPos + 1);
56 double x = str.toDouble (&ok);
57 if (!ok) *pEnd = pPos;
60 #define strtod(a,b) strtod_faster(a,b)
71 Bounding_x1 = Bounding_x2 = Bounding_y1 = Bounding_y2 = 0;
73 xAxis.numGraphs = yAxis.numGraphs = zAxis.numGraphs = 0;
74 xAxis.min = xAxis.low =
75 yAxis.min = yAxis.low = zAxis.min = zAxis.low = 0.0;
76 xAxis.max = xAxis.up =
77 yAxis.max = yAxis.up = zAxis.max = zAxis.up = 1.0;
78 xAxis.GridOn = yAxis.GridOn =
true;
80 xAxis.log = yAxis.log = zAxis.log =
false;
82 xAxis.limit_min = yAxis.limit_min = zAxis.limit_min = 0.0;
83 xAxis.limit_max = yAxis.limit_max = zAxis.limit_max = 1.0;
84 xAxis.step = yAxis.step = zAxis.step = 1.0;
85 xAxis.autoScale = yAxis.autoScale = zAxis.autoScale =
true;
94 GridPen = QPen(QPen::lightGray,0);
95 Graphs.setAutoDelete(
true);
96 Arcs.setAutoDelete(
true);
97 Lines.setAutoDelete(
true);
98 Texts.setAutoDelete(
true);
110 for(
Line *pl = Lines.first(); pl != 0; pl = Lines.next()) {
112 p->
drawLine(
cx+pl->x1, cy-pl->y1,
cx+pl->x2, cy-pl->y2);
116 for(
struct Arc *pa = Arcs.first(); pa != 0; pa = Arcs.next()) {
118 p->
drawArc(
cx+pa->x, cy-pa->y, pa->w, pa->h, pa->angle, pa->arclen);
123 for(pg = Graphs.first(); pg != 0; pg = Graphs.next())
128 QWMatrix wm = p->
Painter->worldMatrix();
129 for(
Text *pt = Texts.first(); pt != 0; pt = Texts.next()) {
131 QWMatrix(pt->mCos, -pt->mSin, pt->mSin, pt->mCos,
133 p->
DY +
float(cy-pt->y) * p->
Scale));
136 p->
Painter->drawText(0, 0, pt->s);
138 p->
Painter->setWorldMatrix(wm);
139 p->
Painter->setWorldXForm(
false);
142 for(pg = Graphs.first(); pg != 0; pg = Graphs.next())
144 pm->paint(p,
cx, cy);
150 p->
map(
cx, cy-y2, x_, y_);
151 fx_ = float(x2)*p->
Scale + 10;
152 fy_ = float(y2)*p->
Scale + 10;
154 p->
Painter->setPen(QPen(QPen::darkGray,3));
156 p->
Painter->setPen(QPen(QPen::darkRed,2));
167 p->drawRect(
cx, cy-y2, x2, y2);
175 int x, y, w, wmax = 0;
178 int LineSpacing = metrics.lineSpacing();
183 if(xAxis.Label.isEmpty()) {
185 for(pg = Graphs.first(); pg != 0; pg = Graphs.next()) {
190 w = metrics.width(pD->
Var) >> 1;
191 if(w > wmax) wmax = w;
192 Texts.append(
new Text(x-w, y, pD->
Var, pg->
Color, 12.0));
195 w = metrics.width(
"real("+pg->
Var+
")") >> 1;
196 if(w > wmax) wmax = w;
197 Texts.append(
new Text(x-w, y,
"real("+pg->
Var+
")",
205 w = metrics.width(Str) >> 1;
206 if(w > wmax) wmax = w;
207 Texts.append(
new Text(x-w, y, Str, Qt::black, 12.0));
210 Bounding_y1 = y - LineSpacing;
211 Bounding_x2 = wmax - (x2 >> 1);
212 if(Bounding_x2 < 0) Bounding_x2 = 0;
213 Bounding_x1 = Bounding_x2;
219 if(yAxis.Label.isEmpty()) {
221 for(pg = Graphs.first(); pg != 0; pg = Graphs.next()) {
225 w = metrics.width(pg->
Var) >> 1;
226 if(w > wmax) wmax = w;
227 Texts.append(
new Text(x, y-w, pg->
Var, pg->
Color, 12.0, 0.0, 1.0));
230 w = metrics.width(
"imag("+pg->
Var+
")") >> 1;
231 if(w > wmax) wmax = w;
232 Texts.append(
new Text(x, y-w,
"imag("+pg->
Var+
")",
233 pg->
Color, 12.0, 0.0, 1.0));
238 if(w > wmax) wmax = w;
240 pg->
Color, 12.0, 0.0, 1.0));
247 w = metrics.width(Str) >> 1;
248 if(w > wmax) wmax = w;
249 Texts.append(
new Text(x, y-w, Str, Qt::black, 12.0, 0.0, 1.0));
252 if(Bounding_x1 < -x) Bounding_x1 = -
x;
257 if(zAxis.Label.isEmpty()) {
259 for(pg = Graphs.first(); pg != 0; pg = Graphs.next()) {
263 w = metrics.width(pg->
Var) >> 1;
264 if(w > wmax) wmax = w;
265 Texts.append(
new Text(x, y+w, pg->
Var,
266 pg->
Color, 12.0, 0.0, -1.0));
269 w = metrics.width(
"imag("+pg->
Var+
")") >> 1;
270 if(w > wmax) wmax = w;
271 Texts.append(
new Text(x, y+w,
"imag("+pg->
Var+
")",
272 pg->
Color, 12.0, 0.0, -1.0));
277 if(w > wmax) wmax = w;
279 pg->
Color, 12.0, 0.0, -1.0));
286 w = metrics.width(Str) >> 1;
287 if(w > wmax) wmax = w;
288 Texts.append(
new Text(x, y+w, Str, Qt::black, 12.0, 0.0, -1.0));
291 if(Bounding_x2 < x) Bounding_x2 =
x;
297 if(wmax < Bounding_y1) Bounding_y1 = wmax;
307 else if(x >
float(x2))
312 else if(y >
float(y2))
322 float R = float(x2)/2.0 + 1.0;
325 return ((x*x + y*y) <= R*R);
333 float x=0, y=0, dx, dy;
334 float x_1 = *(p-4), y_1 = *(p-3);
335 float x_2 = *(p-2), y_2 = *(p-1);
337 int code1 = regionCode(x_1, y_1);
338 int code2 = regionCode(x_2, y_2);
339 if((code1 | code2) == 0)
return;
341 if(code1 != 0)
if(*(p-5) >= 0) {
357 if((code1 | code2) == 0)
break;
359 if(code1) code = code1;
365 y = y_1 - dy * x_1 / dx;
369 y = y_1 + dy * (x2-x_1) / dx;
373 x = x_1 - dx * y_1 / dy;
377 x = x_1 + dx * (y2-y_1) / dy;
384 code1 = regionCode(x, y);
389 code2 = regionCode(x, y);
412 float R = float(x2) / 2.0;
413 float x_1 = *(p-4) - R, y_1 = *(p-3) -
R;
414 float x_2 = *(p-2) - R, y_2 = *(p-1) -
R;
417 float dt2 = dt1 - x_2*x_2 - y_2*y_2;
418 dt1 -= x_1*x_1 + y_1*y_1;
420 if(dt1 >= 0.0)
if(dt2 >= 0.0)
return;
422 if(dt1 < 0.0)
if(*(p-5) >= 0.0) {
429 float C = x_1*x + y_1*y;
431 float F = C*C + dt1*
D;
447 if((dt1 > 0.0) && (dt1 < D)) {
448 *(p-4) = x_1 - x*dt1 / D;
449 *(p-3) = y_1 - y*dt1 / D;
458 if((dt2 > 0.0) && (dt2 <
D)) {
459 *(p-2) = x_1 - x*dt2 / D;
460 *(p-1) = y_1 - y*dt2 / D;
486 int i, z, tmp, Counter=2;
487 float dx, dy, xtmp, ytmp;
488 int Size = ((2*(g->
cPointsX.getFirst()->count) + 1) * g->
countY) + 10;
490 if(xAxis.autoScale)
if(yAxis.autoScale)
if(zAxis.autoScale)
496 float *p = (
float*)malloc( Size*
sizeof(
float) );
503 if(g->
yAxisNo == 0) pa = &yAxis;
506 double Stroke=10.0, Space=10.0;
509 for(i=g->
countY; i>0; i--) {
510 px = g->
cPointsX.getFirst()->Points;
511 calcCoordinate(px, pz, py, p, p+1, pa);
513 for(z=g->
cPointsX.getFirst()->count-1; z>0; z--) {
515 calcCoordinate(px, pz, py, p, p+1, pa);
523 if((*(p-2) < 0) || (*(p-1) < 0))
539 Stroke = 10.0; Space = 6.0;
542 Stroke = 2.0; Space = 4.0;
545 Stroke = 24.0; Space = 8.0;
549 for(i=g->
countY; i>0; i--) {
550 px = g->
cPointsX.getFirst()->Points;
551 for(z=g->
cPointsX.getFirst()->count; z>0; z--) {
552 calcCoordinate(px, pz, py, p, p+1, pa);
553 if(insideDiagram(*p, *(p+1)))
567 for(i=g->
countY; i>0; i--) {
570 px = g->
cPointsX.getFirst()->Points;
571 calcCoordinate(px, pz, py, &xtmp, &ytmp, pa);
575 for(z=g->
cPointsX.getFirst()->count-1; z>0; z--) {
578 calcCoordinate(px, pz, py, &xtmp, &ytmp, pa);
581 dist +=
sqrt(
double(dx*dx + dy*dy));
582 if(Flag == 1)
if(dist <= 0.0) {
587 if((++Counter) >= 2) clip(p);
590 alpha =
atan2(
double(dy),
double(dx));
594 *(p++) = xtmp -
float(dist*
cos(alpha));
595 *(p++) = ytmp -
float(dist*
sin(alpha));
596 if((++Counter) >= 2) clip(p);
603 if((++Counter) >= 2) clip(p);
608 if(*(p-3) < 0) p -= 2;
610 if(Counter < 0) Counter = -50000;
621 if((*(p-2) < 0) || (*(p-1) < 0))
639 _x1 =
cx - Bounding_x1;
640 _y1 = cy - y2 - Bounding_y2;
641 _x2 =
cx + x2 + Bounding_x2;
642 _y2 = cy - Bounding_y1;
648 if(x_ >=
cx-x1)
if(x_ <=
cx+x3)
if(y_ >= cy-y2)
if(y_ <= cy+y1)
659 float fCX = float(
cx), fCY = float(cy);
660 float fX2 = float(
cx+x2), fY2 = float(cy-y2);
661 if(fX < fCX-len)
return false;
662 if(fX > fX2+len)
return false;
663 if(fY < fY2-len)
return false;
664 if(fY > fCY+len)
return false;
667 if(fX < fCX+len) State = 1;
668 else if(fX <= fX2-len)
return false;
669 if(fY > fCY-len) State |= 2;
670 else if(fY >= fY2+len)
return false;
685 for(z=pD->
count; z>0; z--) {
688 if(x > xAxis.max) xAxis.max =
x;
689 if(x < xAxis.min) xAxis.min =
x;
694 if(Name ==
"Rect3D") {
698 for(z=pDy->
count; z>0; z--) {
701 if(y > yAxis.max) yAxis.max = y;
702 if(y < yAxis.min) yAxis.min = y;
709 if(pg->
yAxisNo == 0) pa = &yAxis;
719 if(fabs(y) >= 1
e-250) x =
sqrt(x*x+y*y);
722 if(x < pa->min) pa->
min =
x;
727 if(x > xAxis.max) xAxis.max =
x;
728 if(x < xAxis.min) xAxis.min =
x;
731 if(y > pa->
max) pa->
max = y;
732 if(y < pa->min) pa->
min = y;
741 int yNum = yAxis.numGraphs;
742 int zNum = zAxis.numGraphs;
743 yAxis.numGraphs = zAxis.numGraphs = 0;
745 double xmin = xAxis.min, ymin = yAxis.min, zmin = zAxis.min;
746 double xmax = xAxis.max, ymax = yAxis.max, zmax = zAxis.max;
747 yAxis.min = zAxis.min = xAxis.min = DBL_MAX;
748 yAxis.max = zAxis.max = xAxis.max = -DBL_MAX;
751 for(
Graph *pg = Graphs.first(); pg != 0; pg = Graphs.next()) {
752 if(loadVarData(defaultDataSet, pg) != 1)
756 pg->lastLoaded = QDateTime::currentDateTime();
760 yAxis.numGraphs = yNum;
761 zAxis.numGraphs = zNum;
763 xAxis.min = xmin; yAxis.min = ymin; zAxis.min = zmin;
764 xAxis.max = xmax; yAxis.max = ymax; zAxis.max = zmax;
768 if(xAxis.min > xAxis.max)
769 xAxis.min = xAxis.max = 0.0;
770 if(yAxis.min > yAxis.max)
771 yAxis.min = yAxis.max = 0.0;
772 if(zAxis.min > zAxis.max)
773 zAxis.min = zAxis.max = 0.0;
786 yAxis.min = zAxis.min = xAxis.min = DBL_MAX;
787 yAxis.max = zAxis.max = xAxis.max = -DBL_MAX;
788 yAxis.numGraphs = zAxis.numGraphs = 0;
791 for(
Graph *pg = Graphs.first(); pg != 0; pg = Graphs.next())
794 if(xAxis.min > xAxis.max) {
798 if(yAxis.min > yAxis.max) {
802 if(zAxis.min > zAxis.max) {
806 if((Name ==
"Polar") || (Name ==
"Smith")) {
807 if(yAxis.min > zAxis.min) yAxis.min = zAxis.min;
808 if(yAxis.max < zAxis.max) yAxis.max = zAxis.max;
817 int valid = calcDiagram();
820 for(pg = Graphs.first(); pg != 0; pg = Graphs.next()) {
825 if((valid & (pg->
yAxisNo+1)) != 0)
837 for(pg = Graphs.first(); pg != 0; pg = Graphs.next())
847 QFileInfo Info(fileName);
849 int pos = g->
Var.find(
':');
856 setlocale (LC_NUMERIC,
"C");
859 file.setName(fileName);
863 file.setName(Info.dirPath()+QDir::separator() + g->
Var.left(pos)+
".dat");
864 Variable = g->
Var.mid(pos+1);
875 if(Variable.isEmpty())
return 0;
877 if(Variable.right(2) ==
".X")
878 if(Name.at(0) !=
'T')
882 if(!file.open(IO_ReadOnly))
return 0;
887 QByteArray FileContent;
888 FileContent = file.readAll();
890 char *FileString = FileContent.data();
891 if(!FileString)
return 0;
892 char *pPos = FileString+FileContent.size()-1;
893 if(*pPos >
' ')
if(*pPos !=
'>')
return 0;
899 bool isIndep =
false;
900 Variable =
"dep "+Variable+
" ";
903 char *pFile = strstr(FileString, Variable.latin1());
905 if(*(pFile-1) ==
'<')
907 else if(strncmp(pFile-3,
"<in", 3) == 0) {
911 pFile = strstr(pFile+4, Variable.latin1());
917 pFile += Variable.length();
918 pPos =
strchr(pFile,
'>');
921 Line = QString(pFile);
926 tmp = Line.section(
' ', pos, pos);
927 while(!tmp.isEmpty()) {
930 tmp = Line.section(
' ', pos, pos);
941 counting = Line.toInt(&ok);
945 p =
new double[counting];
948 for(
int z=1; z<=counting; z++) *(p++) = double(z);
949 if(xAxis.min > 1.0) xAxis.min = 1.0;
950 if(xAxis.max <
double(counting)) xAxis.max = double(counting);
956 if(Name ==
"Rect3D") bLast = g->
cPointsX.at(1);
958 double min_tmp = xAxis.min, max_tmp = xAxis.max;
965 else if(pD == bLast) pa = &yAxis;
966 counting = loadIndepVarData(pD->Var, FileString, pa, g);
967 if(counting <= 0)
return 0;
978 p =
new double[2*counting];
980 if(g->
yAxisNo == 0) pa = &yAxis;
988 if(Variable.right(3) !=
".X ")
990 for(
int z=counting; z>0; z--) {
992 while((*pPos) && (*pPos <=
' ')) pPos++;
993 x = strtod(pPos, &pEnd);
998 if(((*pEnd !=
'+') && (*pEnd !=
'-')) || (*pPos !=
'j')) {
1004 y = strtod(pPos, &pEnd);
1010 if(Name[0] !=
'C') {
1011 if(fabs(y) >= 1
e-250) x =
sqrt(x*x+y*y);
1014 if(x < pa->min) pa->
min =
x;
1019 if(x > xAxis.max) xAxis.max =
x;
1020 if(x < xAxis.min) xAxis.min =
x;
1023 if(y > pa->
max) pa->
max = y;
1024 if(y < pa->min) pa->
min = y;
1032 char *pc = (
char*)p;
1033 pEnd = pc + 2*(counting-1)*
sizeof(
double);
1035 for(
int z=counting; z>0; z--) {
1037 while((*pPos) && (*pPos <=
' ')) pPos++;
1043 while(*pPos >
' ') {
1044 *(pc++) = *(pPos++);
1046 counting = pc - (
char*)g->
cPointsY;
1047 pc = (
char*)realloc(g->
cPointsY, counting+1024);
1051 pEnd += counting+1020;
1067 bool isIndep =
false;
1072 setlocale (LC_NUMERIC,
"C");
1074 Line =
"dep "+Variable+
" ";
1077 char *pFile = strstr(FileString, Line.latin1());
1079 if(*(pFile-1) ==
'<')
1081 else if(strncmp(pFile-3,
"<in", 3) == 0) {
1085 pFile = strstr(pFile+4, Line.latin1());
1088 if(!pFile)
return -1;
1090 pFile += Line.length();
1091 char *pPos =
strchr(pFile,
'>');
1092 if(!pPos)
return -1;
1094 Line = QString(pFile);
1099 if(Line.find(
' ') >= 0)
return -1;
1100 Line =
"<indep "+Line+
" ";
1101 pPos = strstr(FileString, Line.latin1());
1102 if(!pPos)
return -1;
1103 pPos += Line.length();
1104 pEnd =
strchr(pPos,
'>');
1105 if(!pEnd)
return -1;
1107 Line = QString(pPos);
1113 int n = Line.toInt(&ok);
1116 double *p =
new double[
n];
1125 while((*pPos) && (*pPos <=
' ')) pPos++;
1127 for(
int z=0; z<
n; z++) {
1129 x = strtod(pPos, &pEnd);
1139 if(x < pa->min) pa->
min =
x;
1143 while((*pPos) && (*pPos <=
' ')) pPos++;
1153 if(g1 == g2)
return true;
1157 while(g1Data && g2Data) {
1158 if(g1Data->
Var != g2Data->
Var)
return false;
1163 if(g1Data)
return false;
1164 if(g2Data)
return false;
1170 const QFontMetrics& metrics,
int colWidth,
int x,
int y)
1172 int w = metrics.width(Str);
1175 if((x+colWidth) >= x2) {
1177 Lines.append(
new Line(x2-6, y-4, x2+7, y-4, QPen(QPen::red,2)));
1178 Lines.append(
new Line(x2, y-7, x2+6, y-4, QPen(QPen::red,2)));
1179 Lines.append(
new Line(x2, y-1, x2+6, y-4, QPen(QPen::red,2)));
1213 QString
s =
"<"+Name+
" "+QString::number(
cx)+
" "+QString::number(cy)+
" ";
1214 s += QString::number(x2)+
" "+QString::number(y2)+
" ";
1216 if(xAxis.GridOn) c |= 1;
1217 if(hideLines) c |= 2;
1219 s +=
" " + GridPen.color().name() +
" " + QString::number(GridPen.style());
1221 if(xAxis.log) s+=
" 1";
else s +=
" 0";
1223 if(yAxis.log) c |= 1;
1224 if(zAxis.log) c |= 2;
1227 if(xAxis.autoScale) s+=
" 1 ";
1229 s += QString::number(xAxis.limit_min) +
" ";
1230 s += QString::number(xAxis.step) +
" ";
1231 s += QString::number(xAxis.limit_max);
1232 if(yAxis.autoScale) s+=
" 1 ";
1234 s += QString::number(yAxis.limit_min) +
" ";
1235 s += QString::number(yAxis.step) +
" ";
1236 s += QString::number(yAxis.limit_max);
1237 if(zAxis.autoScale) s+=
" 1 ";
1239 s += QString::number(zAxis.limit_min) +
" ";
1240 s += QString::number(zAxis.step) +
" ";
1241 s += QString::number(zAxis.limit_max) +
" ";
1243 s += QString::number(rotX)+
" "+QString::number(rotY)+
" "+
1244 QString::number(rotZ);
1247 s +=
" \""+xAxis.Label+
"\" \""+yAxis.Label+
"\" \""+zAxis.Label+
"\">\n";
1249 for(
Graph *pg=Graphs.first(); pg != 0; pg=Graphs.next())
1250 s += pg->save()+
"\n";
1252 s +=
" </"+Name+
">";
1262 if(s.at(0) !=
'<')
return false;
1263 if(s.at(s.length()-1) !=
'>')
return false;
1264 s = s.mid(1, s.length()-2);
1267 n = s.section(
' ',1,1);
1269 if(!ok)
return false;
1271 n = s.section(
' ',2,2);
1273 if(!ok)
return false;
1275 n = s.section(
' ',3,3);
1277 if(!ok)
return false;
1279 n = s.section(
' ',4,4);
1281 if(!ok)
return false;
1284 n = s.section(
' ',5,5);
1285 c = n.at(0).latin1() -
'0';
1286 xAxis.GridOn = yAxis.GridOn = (c & 1) != 0;
1287 hideLines = (c & 2) != 0;
1289 n = s.section(
' ',6,6);
1291 co.setNamedColor(n);
1292 GridPen.setColor(co);
1293 if(!GridPen.color().isValid())
return false;
1295 n = s.section(
' ',7,7);
1296 GridPen.setStyle((Qt::PenStyle)n.toInt(&ok));
1297 if(!ok)
return false;
1299 n = s.section(
' ',8,8);
1300 xAxis.log = n.at(0) !=
'0';
1301 c = n.at(1).latin1();
1302 yAxis.log = ((c -
'0') & 1) == 1;
1303 zAxis.log = ((c -
'0') & 2) == 2;
1305 n = s.section(
' ',9,9);
1306 if(n.at(0) !=
'"') {
1307 if(n ==
"1") xAxis.autoScale =
true;
1308 else xAxis.autoScale =
false;
1310 n = s.section(
' ',10,10);
1311 xAxis.limit_min = n.toDouble(&ok);
1312 if(!ok)
return false;
1314 n = s.section(
' ',11,11);
1315 xAxis.step = n.toDouble(&ok);
1316 if(!ok)
return false;
1318 n = s.section(
' ',12,12);
1319 xAxis.limit_max = n.toDouble(&ok);
1320 if(!ok)
return false;
1322 n = s.section(
' ',13,13);
1323 if(n ==
"1") yAxis.autoScale =
true;
1324 else yAxis.autoScale =
false;
1326 n = s.section(
' ',14,14);
1327 yAxis.limit_min = n.toDouble(&ok);
1328 if(!ok)
return false;
1330 n = s.section(
' ',15,15);
1331 yAxis.step = n.toDouble(&ok);
1332 if(!ok)
return false;
1334 n = s.section(
' ',16,16);
1335 yAxis.limit_max = n.toDouble(&ok);
1336 if(!ok)
return false;
1338 n = s.section(
' ',17,17);
1339 if(n ==
"1") zAxis.autoScale =
true;
1340 else zAxis.autoScale =
false;
1342 n = s.section(
' ',18,18);
1343 zAxis.limit_min = n.toDouble(&ok);
1344 if(!ok)
return false;
1346 n = s.section(
' ',19,19);
1347 zAxis.step = n.toDouble(&ok);
1348 if(!ok)
return false;
1350 n = s.section(
' ',20,20);
1351 zAxis.limit_max = n.toDouble(&ok);
1352 if(!ok)
return false;
1354 n = s.section(
' ',21,21);
1355 if(n.at(0) !=
'"') {
1356 rotX = n.toInt(&ok);
1357 if(!ok)
return false;
1359 n = s.section(
' ',22,22);
1360 rotY = n.toInt(&ok);
1361 if(!ok)
return false;
1363 n = s.section(
' ',23,23);
1364 rotZ = n.toInt(&ok);
1365 if(!ok)
return false;
1369 xAxis.Label = s.section(
'"',1,1);
1370 yAxis.Label = s.section(
'"',3,3);
1371 zAxis.Label = s.section(
'"',5,5);
1376 while(!stream->atEnd()) {
1377 s = stream->readLine();
1378 s = s.stripWhiteSpace();
1379 if(s.isEmpty())
continue;
1381 if(s == (
"</"+Name+
">"))
return true;
1382 if(s.section(
' ', 0,0) ==
"<Mkr") {
1386 pg = Graphs.current();
1387 if(!pg)
return false;
1411 xAxis.low = xAxis.min;
1412 xAxis.up = xAxis.max;
1415 if(fabs(Axis->
min) > Axis->
max)
1416 Axis->
max = fabs(Axis->
min);
1418 if(Axis->
max > 1.01) Axis->
up = 1.05*Axis->
max;
1419 else Axis->
up = 1.0;
1424 GridX = GridY = int(Axis->
step);
1433 calcSmithAxisScale(Axis, GridX, GridY);
1436 if(!xAxis.GridOn)
return;
1438 bool Zplane = ((Mode & 1) == 1);
1439 bool Above = ((Mode & 2) == 2);
1440 bool Below = ((Mode & 4) == 4);
1444 double im, n_cos, n_sin,
real, real1, real2, root;
1445 double rMAXq = Axis->
up*Axis->
up;
1446 int theta, beta, phi, len, m,
x, y;
1448 int R1 = int(x2/Axis->
up + 0.5);
1451 for(m=1; m<GridY; m++) {
1452 n_sin =
M_PI*double(m)/double(GridY);
1455 im = (1.0-n_cos)/n_sin *
pow(Axis->
up,0.7);
1456 y = int(im/Axis->
up*x2 + 0.5);
1458 if(Axis->
up <= 1.0) {
1459 beta = int(16.0*180.0*
atan2(n_sin-im,n_cos-1.0)/
M_PI - 0.5);
1460 if(beta<0) beta += 16*360;
1461 theta = 16*270-beta;
1465 real = (rMAXq+1.0)/(rMAXq-1.0);
1466 root = real*real - im*im - 1.0;
1476 root = (real1+1.0)*(real1+1.0) + im*im;
1477 n_cos = (real1*real1 + im*im - 1.0) / root;
1478 n_sin = 2.0*im / root;
1479 beta = int(16.0*180.0*
atan2(n_sin-1.0/im,n_cos-1.0)/
M_PI);
1480 if(beta<0) beta += 16*360;
1482 root = (real2+1.0)*(real2+1.0) + im*im;
1483 n_cos = (real2*real2 + im*im - 1.0) / root;
1484 n_sin = 2.0*im / root;
1485 theta = int(16.0*180.0*
atan2(n_sin-1/im,n_cos-1)/
M_PI);
1486 if(theta<0) theta += 16*360;
1487 theta = theta - beta;
1488 if(theta < 0) theta = 16*360+theta;
1493 x = (x2 + R1 - y) >> 1;
1495 x = (x2 - R1 - y) >> 1;
1496 beta = 16*180 - beta - theta;
1497 if(beta < 0) beta += 16*360;
1501 Arcs.append(
new struct Arc(x, dx2+y, y, y, beta, theta, GridPen));
1503 Arcs.append(
new struct Arc(x, dx2, y, y, 16*360-beta-theta, theta, GridPen));
1510 if(Above) { beta = 0; theta = 16*180; }
1511 if(Below) theta += 16*180;
1513 for(m=1; m<GridX; m++) {
1514 im = m*(Axis->
up+1.0)/GridX - Axis->
up;
1515 y = int((1.0-im)/Axis->
up*
double(dx2) + 0.5);
1518 x = ((x2+R1)>>1) - y;
1521 if(fabs(fabs(im)-1.0) > 0.2)
1522 Arcs.append(
new struct Arc(x, (x2+y)>>1, y, y, beta, theta, GridPen));
1524 if(Axis->
up > 1.0) {
1526 im = (rMAXq-1.0)/(im*(im/2.0+1.0)) - 1.0;
1530 Arcs.append(
new struct Arc(x, (x2+y)>>1, y, y, beta, theta, GridPen));
1532 phi = int(16.0*180.0/
M_PI*
acos(im));
1534 if(Above && Below) len += len;
1535 else if(Below) phi = 16*180;
1536 if(!Zplane) phi += 16*180;
1537 Arcs.append(
new struct Arc(x, (x2+y)>>1, y, y, phi, len, GridPen));
1544 if(Axis->
up > 1.0) {
1547 Arcs.append(
new struct Arc(x, y, R1, R1, beta, theta, QPen(QPen::black,0)));
1551 y = int(
sqrt(rMAXq-1)/Axis->
up*dx2 + 0.5);
1555 Lines.append(
new Line(x, dx2+m, x, dx2-y, GridPen));
1567 double& GridStep,
double& zD)
1571 numGrids =
floor(
double(x2)/80.0);
1573 Base = Axis->
max/numGrids/
pow(10.0,Expo);
1575 if(Base < 1.5) Base = 1.0;
1579 if(Base < 7.5) Base = 5.0;
1580 else { Base = 1.0; Expo++; }
1582 GridStep = Base *
pow(10.0,Expo);
1583 numGrids -=
floor(numGrids - Axis->
max/GridStep);
1584 Axis->
up = GridStep*numGrids;
1586 zD = double(x2) / numGrids;
1590 GridStep = Axis->
step;
1593 if(fabs(zD) < 2.0) {
1595 GridStep = Axis->
step = Axis->
up;
1605 xAxis.low = xAxis.min;
1606 xAxis.up = xAxis.max;
1608 if(fabs(Axis->
min) > Axis->
max)
1609 Axis->
max = fabs(Axis->
min);
1612 bool Above = ((Mode & 1) == 1);
1613 bool Below = ((Mode & 2) == 2);
1616 if(Above) i = y2;
else i = y2>>1;
1617 if(Below) z = 0;
else z = y2>>1;
1619 Lines.append(
new Line(x2>>1, i, x2>>1, z, GridPen));
1623 if(Above) { beta = 0; len = 16*180; }
1624 if(Below) len += 16*180;
1628 if(!Below) tPos = (y2>>1) + 3;
1629 else tPos = (y2>>1) - tHeight + 3;
1631 double Expo,
Base, numGrids, GridStep, zD;
1633 calcPolarAxisScale(Axis, numGrids, GridStep, zD);
1636 double GridNum = 0.0;
1637 for(i=
int(numGrids); i>1; i--) {
1639 GridNum += GridStep;
1642 phi = int(16.0*180.0/
M_PI*
atan(
double(2*tHeight)/zD));
1643 if(!Below) tmp = beta + phi;
1645 Arcs.append(
new struct Arc((x2-z)>>1, (y2+z)>>1, z, z, tmp, len-phi,
1652 Base =
ceil(Axis->
max/
pow(10.0,Expo) - 0.01);
1653 Axis->
up = Base *
pow(10.0,Expo);
1658 phi = int(16.0*180.0/
M_PI*
atan(
double(2*tHeight)/
double(x2)));
1659 if(!Below) tmp = phi;
1661 Arcs.append(
new struct Arc(0, y2, x2, y2, tmp, 16*360-phi, QPen(QPen::black,0)));
1664 QSize r = metrics.size(0, Texts.current()->s);
1665 len = x2+r.width()-4;
1666 if(len > x3) x3 = len;
1680 double& zDstep,
double& GridStep,
double Dist)
1683 double numGrids,
Base, Expo, corr;
1686 if(fabs(Axis->
max-Axis->
min) < 1
e-200) {
1687 if((Axis->
max == 0.0) && (Axis->
min == 0.0)) {
1692 Axis->
up = Axis->
max + fabs(Axis->
max);
1693 Axis->
low = Axis->
min - fabs(Axis->
min);
1696 else if(Axis != &xAxis) {
1702 Axis->
up = Axis->
max;
1707 numGrids =
floor(Dist/60.0);
1708 if(numGrids < 1.0) Base = Axis->
up-Axis->
low;
1709 else Base = (Axis->
up-Axis->
low)/numGrids;
1711 Base = Base/
pow(10.0,Expo);
1713 if(Base < 1.5) Base = 1.0;
1717 if(Base < 7.5) Base = 5.0;
1718 else { Base = 1.0; Expo++; }
1720 GridStep = Base *
pow(10.0,Expo);
1721 corr =
floor((Axis->
up-Axis->
low)/GridStep - numGrids);
1722 if(corr < 0.0) corr++;
1727 zD = fabs(
fmod(Axis->
up, GridStep));
1728 GridNum = zD/GridStep;
1729 if((1.0-GridNum) < 1
e-10) GridNum = 0.0;
1730 if(Axis->
up <= 0.0) {
1731 if(GridNum < 0.3) { Axis->
up += zD; zD = 0.0; }
1733 else if(GridNum > 0.7) Axis->
up += GridStep-zD;
1734 else if(GridNum < 0.1)
1735 if(GridNum*Dist >= 1.0)
1736 Axis->
up += 0.3*GridStep;
1740 zD = fabs(
fmod(Axis->
low, GridStep));
1741 GridNum = zD/GridStep;
1742 if((1.0-GridNum) < 1
e-10) zD = GridNum = 0.0;
1743 if(Axis->
low <= 0.0) {
1744 if(GridNum > 0.7) { Axis->
low -= GridStep-zD; zD = 0.0; }
1745 else if(GridNum < 0.1)
1746 if(GridNum*Dist >= 1.0) {
1747 Axis->
low -= 0.3*GridStep;
1755 if((1.0-GridNum)*Dist >= 1.0) {
1756 Axis->
low -= 0.3*GridStep;
1761 else { Axis->
low -= zD; zD = 0.0; }
1764 GridNum = Axis->
low + zD;
1765 zD /= (Axis->
up-Axis->
low)/Dist;
1773 GridStep = Axis->
step;
1776 zDstep = GridStep/(Axis->
up-Axis->
low)*Dist;
1778 if(fabs(zDstep) < 2.0) {
1780 GridStep = Axis->
step = Axis->
up-Axis->
low;
1798 double& zDstep,
double& corr,
int len)
1800 if(fabs(Axis->
max-Axis->
min) < 1
e-200) {
1812 bool mirror=
false, mirror2=
false;
1814 if(Axis->
up < 0.0) {
1816 Axis->
low = -Axis->
up;
1830 Base = Axis->
max/
pow(10.0,Expo);
1831 if(Base > 3.0001) Axis->
up =
pow(10.0,Expo+1.0);
1832 else if(Base < 1.0001) Axis->
up =
pow(10.0,Expo);
1833 else Axis->
up = 3.0 *
pow(10.0,Expo);
1836 Base = Axis->
min/
pow(10.0,Expo);
1837 if(Base < 2.999) Axis->
low =
pow(10.0,Expo);
1838 else if(Base > 9.999) Axis->
low =
pow(10.0,Expo+1.0);
1839 else Axis->
low = 3.0 *
pow(10.0,Expo);
1841 corr = double(len) /
log10(Axis->
up / Axis->
low);
1845 zDstep =
pow(10.0,Expo);
1854 if(Axis->
up < Axis->
low) {
1856 Axis->
low = Axis->
up;
1863 zD = Base *
pow(10.0, Expo);
1864 zDstep =
pow(10.0,Expo);
1865 if(zD > 9.5*zDstep) zDstep *= 10.0;
1867 corr = double(len) /
log10(Axis->
up / Axis->
low);
1868 z = int(corr*
log10(zD / Axis->
low) + 0.5);
1872 Axis->
low = Axis->
up;
1879 Axis->
low = -Axis->
up;
1883 if(mirror == mirror2)
return false;
1891 double GridStep, corr, zD, zDstep, GridNum;
1900 if(Axis->
max*Axis->
min <= 0.0)
return false;
1904 back = calcAxisLogScale(Axis, z, zD, zDstep, corr, y2);
1907 while((z <= y2) && (z >= 0)) {
1908 if(Axis->
GridOn)
if(z < y2)
if(z > 0)
1909 Lines.prepend(
new Line(0, z, x2, z, GridPen));
1911 if((zD < 1.5*zDstep) || (z == 0)) {
1913 if(Axis->
up < 0.0) tmp =
'-'+tmp;
1915 w = metrics.width(tmp);
1916 if(maxWidth < w) maxWidth = w;
1918 Texts.append(
new Text(x0+7, z-6, tmp));
1920 Texts.append(
new Text(-w-7, z-6, tmp));
1923 Lines.append(
new Line(x0-5, z, x0+5, z, QPen(QPen::black,0)));
1927 if(zD > 9.5*zDstep) zDstep *= 10.0;
1929 z = int(corr*
log10(zD / fabs(Axis->
up)) + 0.5);
1933 z = int(corr*
log10(zD / fabs(Axis->
low)) + 0.5);
1937 back = calcAxisScale(Axis, GridNum, zD, zDstep, GridStep,
double(y2));
1940 if(Axis->
up == 0.0) Expo =
log10(fabs(Axis->
up-Axis->
low));
1941 else Expo =
log10(fabs(Axis->
up));
1945 while((z <= y2) && (z >= 0)) {
1946 if(fabs(GridNum) < 0.01*
pow(10.0, Expo)) GridNum = 0.0;
1949 w = metrics.width(tmp);
1950 if(maxWidth < w) maxWidth = w;
1952 Texts.append(
new Text(x0+8, z-6, tmp));
1954 Texts.append(
new Text(-w-7, z-6, tmp));
1955 GridNum += GridStep;
1957 if(Axis->
GridOn)
if(z < y2)
if(z > 0)
1958 Lines.prepend(
new Line(0, z, x2, z, GridPen));
1959 Lines.append(
new Line(x0-5, z, x0+5, z, QPen(QPen::black,0)));
1964 if(x0 == 0) x1 = maxWidth+14;
1965 else x3 = x2+maxWidth+14;