My Project  0.0.16
QUCS Mapping
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
curvediagram.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  curvediagram.cpp
3  ------------------
4  begin : Sat Apr 9 2005
5  copyright : (C) 2005 by Michael Margraf
6  email : michael.margraf@alumni.tu-berlin.de
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
18 #if HAVE_CONFIG_H
19 # include <config.h>
20 #endif
21 
22 #include <math.h>
23 #include <float.h>
24 #ifdef __MINGW32__
25 # define finite(x) _finite(x)
26 #endif
27 #if HAVE_IEEEFP_H
28 # include <ieeefp.h>
29 #endif
30 
31 #include <qmessagebox.h>
32 
33 #include "curvediagram.h"
34 #include "main.h"
35 
36 CurveDiagram::CurveDiagram(int _cx, int _cy) : Diagram(_cx, _cy)
37 {
38  x1 = 10; // position of label text
39  y1 = y3 = 33;
40  x2 = y2 = 200; // initial size of diagram
41  x3 = 207; // with some distance for right axes text
42 
43  Name = "Curve";
44  calcDiagram();
45 }
46 
48 {
49 }
50 
51 // ------------------------------------------------------------
52 void CurveDiagram::calcCoordinate(double* &, double* &yD, double* &,
53  float *px, float *py, Axis *pa)
54 {
55  double yr = *(yD++);
56  double yi = *(yD++);
57  if(xAxis.log)
58  *px = float(log10(yr / xAxis.low)/log10(xAxis.up / xAxis.low)
59  *double(x2));
60  else *px = float((yr-xAxis.low)/(xAxis.up-xAxis.low)*double(x2));
61 
62  if(pa->log)
63  *py = float(log10(yi / pa->low)/log10(pa->up / pa->low)
64  *double(y2));
65  else *py = float((yi-pa->low)/(pa->up-pa->low)*double(y2));
66 
67  if(finite(*px))
68  if(finite(*py))
69  return;
70 
71  *px = *py = 0.0;
72 }
73 
74 // --------------------------------------------------------------
76 {
77  int i;
78  double a, b, c;
79 
80  if(xAxis.autoScale) {// check before, to preserve limit exchange (max < min)
81  if(xAxis.log) {
82  calcAxisLogScale(&xAxis, i, a, b, c, x2);
83  xAxis.step = 1.0;
84  }
85  else calcAxisScale(&xAxis, a, b, c, xAxis.step, double(x2));
88  }
89 
90  if(yAxis.autoScale) {// check before, to preserve limit exchange (max < min)
91  if(yAxis.log) {
92  calcAxisLogScale(&yAxis, i, a, b, c, y2);
93  yAxis.step = 1.0;
94  }
95  else calcAxisScale(&yAxis, a, b, c, yAxis.step, double(y2));
98  }
99 
100  if(zAxis.autoScale) {// check before, to preserve limit exchange (max < min)
101  if(zAxis.log) {
102  calcAxisLogScale(&zAxis, i, a, b, c, y2);
103  zAxis.step = 1.0;
104  }
105  else calcAxisScale(&zAxis, a, b, c, zAxis.step, double(y2));
108  }
109 }
110 
111 // --------------------------------------------------------------
113 {
114  Lines.clear();
115  Texts.clear();
116  Arcs.clear();
117 
118  double GridStep, corr, zD, zDstep, GridNum;
119  QFontMetrics metrics(QucsSettings.font);
120  y1 = QucsSettings.font.pointSize() + 6;
121 
122  x1 = 10; // position of label text
123  x3 = x2 + 7;
124  QString tmp;
125  bool back = false;
126  int z, w, valid = 0;
127 
128  // ===== give "step" the right sign (if user made it wrong) ==============
129  xAxis.step = fabs(xAxis.step);
131  xAxis.step *= -1.0;
132 
133  yAxis.step = fabs(yAxis.step);
135  yAxis.step *= -1.0;
136 
137  zAxis.step = fabs(zAxis.step);
139  zAxis.step *= -1.0;
140 
141 
142  // ==== x grid =======================================================
143 if(xAxis.log) {
144  if(xAxis.autoScale) {
145  if(xAxis.max*xAxis.min <= 0.0) goto Frame; // invalid
146  }
147  else if(xAxis.limit_min*xAxis.limit_max <= 0.0) goto Frame; // invalid
148 
149  back = calcAxisLogScale(&xAxis, z, zD, zDstep, corr, x2);
150 
151  if(back) z = x2;
152  while((z <= x2) && (z >= 0)) { // create all grid lines
153  if(xAxis.GridOn) if(z < x2) if(z > 0)
154  Lines.prepend(new Line(z, y2, z, 0, GridPen)); // x grid
155 
156  if((zD < 1.5*zDstep) || (z == 0) || (z == x2)) {
157  tmp = StringNiceNum(zD);
158  if(xAxis.up < 0.0) tmp = '-'+tmp;
159  w = metrics.width(tmp); // width of text
160 
161  Texts.append(new Text(z-(w>>1), -y1, tmp));
162  Lines.append(new Line(z, 5, z, -5, QPen(QPen::black,0))); // x marks
163  }
164 
165  zD += zDstep;
166  if(zD > 9.5*zDstep) zDstep *= 10.0;
167  if(back) {
168  z = int(corr*log10(zD / fabs(xAxis.up)) + 0.5); // int() implies floor()
169  z = x2 - z;
170  }
171  else
172  z = int(corr*log10(zD / fabs(xAxis.low)) + 0.5);// int() implies floor()
173  }
174 }
175 else { // not logarithmical
176  calcAxisScale(&xAxis, GridNum, zD, zDstep, GridStep, double(x2));
177 
178  double Expo;
179  if(xAxis.up == 0.0) Expo = log10(fabs(xAxis.up-xAxis.low));
180  else Expo = log10(fabs(xAxis.up));
181 
182  zD += 0.5; // perform rounding
183  z = int(zD); // "int(...)" implies "floor(...)"
184  while((z <= x2) && (z >= 0)) { // create all grid lines
185  if(fabs(GridNum) < 0.01*pow(10.0, Expo)) GridNum = 0.0;// make 0 really 0
186  tmp = StringNiceNum(GridNum);
187  w = metrics.width(tmp); // width of text
188  Texts.append(new Text(z-(w>>1), -y1, tmp));
189  GridNum += GridStep;
190 
191  if(xAxis.GridOn) if(z < x2) if(z > 0)
192  Lines.prepend(new Line(z, y2, z, 0, GridPen)); // x grid
193  Lines.append(new Line(z, 5, z, -5, QPen(QPen::black,0))); // x marks
194  zD += zDstep;
195  z = int(zD);
196  }
197 
198  if(xAxis.up >= 0.0) if(xAxis.low <= 0.0) { // paint origin cross ?
199  z = int(double(x2) * fabs(xAxis.low / (xAxis.up-xAxis.low)) + 0.5);
200  Lines.append(new Line(z, 0, z, y2, QPen(QPen::black,0)));
201  }
202 } // of "if(xlog) ... else ..."
203 
204 
205  // ==== y grid =======================================================
206  if(zAxis.numGraphs > 0) if(calcYAxis(&zAxis, x2)) valid |= 2;
207  if(yAxis.numGraphs > 0) if(calcYAxis(&yAxis, 0)) {
208  valid |= 1;
209  if(yAxis.up >= 0.0) if(yAxis.low <= 0.0) { // paint origin cross ?
210  z = int(double(y2) * fabs(yAxis.low / (yAxis.up-yAxis.low)) + 0.5);
211  Lines.append(new Line(0, z, x2, z, QPen(QPen::black,0)));
212  }
213  }
214 
215 
216 Frame:
217  // outer frame
218  Lines.append(new Line(0, y2, x2, y2, QPen(QPen::black,0)));
219  Lines.append(new Line(x2, y2, x2, 0, QPen(QPen::black,0)));
220  Lines.append(new Line(0, 0, x2, 0, QPen(QPen::black,0)));
221  Lines.append(new Line(0, y2, 0, 0, QPen(QPen::black,0)));
222  return valid;
223 }
224 
225 // ------------------------------------------------------------
226 bool CurveDiagram::insideDiagram(float x, float y)
227 {
228  return (regionCode(x, y) == 0);
229 }
230 
231 // ------------------------------------------------------------
232 void CurveDiagram::clip(float* &p)
233 {
234  rectClip(p);
235 }
236 
237 // ------------------------------------------------------------
239 {
240  return new CurveDiagram();
241 }
242 
243 // ------------------------------------------------------------
244 Element* CurveDiagram::info(QString& Name, char* &BitmapFile, bool getNewOne)
245 {
246  Name = QObject::tr("Locus Curve");
247  BitmapFile = (char *) "curve";
248 
249  if(getNewOne) return new CurveDiagram();
250  return 0;
251 }