Qucs-GUI  0.0.18
 All Data Structures 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 #include <QtGui>
22 #include <math.h>
23 #include <float.h>
24 #if HAVE_IEEEFP_H
25 # include <ieeefp.h>
26 #endif
27 
28 #include <QMessageBox>
29 
30 #include "curvediagram.h"
31 #include "main.h"
32 #include "qucs.h"
33 #include "schematic.h"
34 
35 CurveDiagram::CurveDiagram(int _cx, int _cy) : Diagram(_cx, _cy)
36 {
37  x1 = 10; // position of label text
38  y1 = y3 = 33;
39  x2 = y2 = 200; // initial size of diagram
40  x3 = 207; // with some distance for right axes text
41 
42  Name = "Curve";
43  calcDiagram();
44 }
45 
47 {
48 }
49 
50 // ------------------------------------------------------------
51 void CurveDiagram::calcCoordinate(double* &, double* &yD, double* &,
52  float *px, float *py, Axis *pa)
53 {
54  double yr = *(yD++);
55  double yi = *(yD++);
56  if(xAxis.log)
57  *px = float(log10(yr / xAxis.low)/log10(xAxis.up / xAxis.low)
58  *double(x2));
59  else *px = float((yr-xAxis.low)/(xAxis.up-xAxis.low)*double(x2));
60 
61  if(pa->log)
62  *py = float(log10(yi / pa->low)/log10(pa->up / pa->low)
63  *double(y2));
64  else *py = float((yi-pa->low)/(pa->up-pa->low)*double(y2));
65 
66  if(isfinite(*px))
67  if(isfinite(*py))
68  return;
69 
70  *px = *py = 0.0;
71 }
72 
73 // --------------------------------------------------------------
75 {
76  int i;
77  double a, b, c;
78 
79  if(xAxis.autoScale) {// check before, to preserve limit exchange (max < min)
80  if(xAxis.log) {
81  calcAxisLogScale(&xAxis, i, a, b, c, x2);
82  xAxis.step = 1.0;
83  }
84  else calcAxisScale(&xAxis, a, b, c, xAxis.step, double(x2));
87  }
88 
89  if(yAxis.autoScale) {// check before, to preserve limit exchange (max < min)
90  if(yAxis.log) {
91  calcAxisLogScale(&yAxis, i, a, b, c, y2);
92  yAxis.step = 1.0;
93  }
94  else calcAxisScale(&yAxis, a, b, c, yAxis.step, double(y2));
97  }
98 
99  if(zAxis.autoScale) {// check before, to preserve limit exchange (max < min)
100  if(zAxis.log) {
101  calcAxisLogScale(&zAxis, i, a, b, c, y2);
102  zAxis.step = 1.0;
103  }
104  else calcAxisScale(&zAxis, a, b, c, zAxis.step, double(y2));
107  }
108 }
109 
110 // --------------------------------------------------------------
112 {
113  Lines.clear();
114  Texts.clear();
115  Arcs.clear();
116 
117  double GridStep, corr, zD, zDstep, GridNum;
118  QFontMetrics metrics(((Schematic*)QucsMain->DocumentTab->currentPage())->font()); // get size of text
119  y1 = QucsSettings.font.pointSize() + 6;
120 
121  x1 = 10; // position of label text
122  x3 = x2 + 7;
123  QString tmp;
124  bool back = false;
125  int z, w, valid = 0;
126 
127  // ===== give "step" the right sign (if user made it wrong) ==============
128  xAxis.step = fabs(xAxis.step);
130  xAxis.step *= -1.0;
131 
132  yAxis.step = fabs(yAxis.step);
134  yAxis.step *= -1.0;
135 
136  zAxis.step = fabs(zAxis.step);
138  zAxis.step *= -1.0;
139 
140 
141  // ==== x grid =======================================================
142 if(xAxis.log) {
143  if(xAxis.autoScale) {
144  if(xAxis.max*xAxis.min <= 0.0) goto Frame; // invalid
145  }
146  else if(xAxis.limit_min*xAxis.limit_max <= 0.0) goto Frame; // invalid
147 
148  back = calcAxisLogScale(&xAxis, z, zD, zDstep, corr, x2);
149 
150  if(back) z = x2;
151  while((z <= x2) && (z >= 0)) { // create all grid lines
152  if(xAxis.GridOn) if(z < x2) if(z > 0)
153  Lines.prepend(new Line(z, y2, z, 0, GridPen)); // x grid
154 
155  if((zD < 1.5*zDstep) || (z == 0) || (z == x2)) {
156  tmp = StringNiceNum(zD);
157  if(xAxis.up < 0.0) tmp = '-'+tmp;
158  w = metrics.width(tmp); // width of text
159 
160  Texts.append(new Text(z-(w>>1), -y1, tmp));
161  Lines.append(new Line(z, 5, z, -5, QPen(Qt::black,0))); // x marks
162  }
163 
164  zD += zDstep;
165  if(zD > 9.5*zDstep) zDstep *= 10.0;
166  if(back) {
167  z = int(corr*log10(zD / fabs(xAxis.up)) + 0.5); // int() implies floor()
168  z = x2 - z;
169  }
170  else
171  z = int(corr*log10(zD / fabs(xAxis.low)) + 0.5);// int() implies floor()
172  }
173 }
174 else { // not logarithmical
175  calcAxisScale(&xAxis, GridNum, zD, zDstep, GridStep, double(x2));
176 
177  double Expo;
178  if(xAxis.up == 0.0) Expo = log10(fabs(xAxis.up-xAxis.low));
179  else Expo = log10(fabs(xAxis.up));
180 
181  zD += 0.5; // perform rounding
182  z = int(zD); // "int(...)" implies "floor(...)"
183  while((z <= x2) && (z >= 0)) { // create all grid lines
184  if(fabs(GridNum) < 0.01*pow(10.0, Expo)) GridNum = 0.0;// make 0 really 0
185  tmp = StringNiceNum(GridNum);
186  w = metrics.width(tmp); // width of text
187  Texts.append(new Text(z-(w>>1), -y1, tmp));
188  GridNum += GridStep;
189 
190  if(xAxis.GridOn) if(z < x2) if(z > 0)
191  Lines.prepend(new Line(z, y2, z, 0, GridPen)); // x grid
192  Lines.append(new Line(z, 5, z, -5, QPen(Qt::black,0))); // x marks
193  zD += zDstep;
194  z = int(zD);
195  }
196 
197  if(xAxis.up >= 0.0) if(xAxis.low <= 0.0) { // paint origin cross ?
198  z = int(double(x2) * fabs(xAxis.low / (xAxis.up-xAxis.low)) + 0.5);
199  Lines.append(new Line(z, 0, z, y2, QPen(Qt::black,0)));
200  }
201 } // of "if(xlog) ... else ..."
202 
203 
204  // ==== y grid =======================================================
205  if(zAxis.numGraphs > 0) if(calcYAxis(&zAxis, x2)) valid |= 2;
206  if(yAxis.numGraphs > 0) if(calcYAxis(&yAxis, 0)) {
207  valid |= 1;
208  if(yAxis.up >= 0.0) if(yAxis.low <= 0.0) { // paint origin cross ?
209  z = int(double(y2) * fabs(yAxis.low / (yAxis.up-yAxis.low)) + 0.5);
210  Lines.append(new Line(0, z, x2, z, QPen(Qt::black,0)));
211  }
212  }
213 
214 
215 Frame:
216  // outer frame
217  Lines.append(new Line(0, y2, x2, y2, QPen(Qt::black,0)));
218  Lines.append(new Line(x2, y2, x2, 0, QPen(Qt::black,0)));
219  Lines.append(new Line(0, 0, x2, 0, QPen(Qt::black,0)));
220  Lines.append(new Line(0, y2, 0, 0, QPen(Qt::black,0)));
221  return valid;
222 }
223 
224 // ------------------------------------------------------------
225 bool CurveDiagram::insideDiagram(float x, float y)
226 {
227  return (regionCode(x, y) == 0);
228 }
229 
230 // ------------------------------------------------------------
231 void CurveDiagram::clip(float* &p)
232 {
233  rectClip(p);
234 }
235 
236 // ------------------------------------------------------------
238 {
239  return new CurveDiagram();
240 }
241 
242 // ------------------------------------------------------------
243 Element* CurveDiagram::info(QString& Name, char* &BitmapFile, bool getNewOne)
244 {
245  Name = QObject::tr("Locus Curve");
246  BitmapFile = (char *) "curve";
247 
248  if(getNewOne) return new CurveDiagram();
249  return 0;
250 }
static Element * info(QString &, char *&, bool getNewOne=false)
Axis xAxis
Definition: diagram.h:101
int regionCode(float, float)
Definition: diagram.cpp:287
int y1
Definition: element.h:153
QFont font
Definition: main.h:46
QString Name
Definition: diagram.h:92
tQucsSettings QucsSettings
Definition: main.cpp:52
int y2
Definition: element.h:153
void calcCoordinate(double *&, double *&, double *&, float *, float *, Axis *)
int x1
Definition: element.h:153
double limit_min
Definition: diagram.h:56
void clip(float *&)
CurveDiagram(int _cx=0, int _cy=0)
bool GridOn
Definition: diagram.h:53
Definitions and declarations for the main application.
QucsApp * QucsMain
Definition: main.cpp:54
QString StringNiceNum(double num)
Definition: main.cpp:293
QPen GridPen
Definition: diagram.h:93
void rectClip(float *&)
Definition: diagram.cpp:315
int numGraphs
Definition: diagram.h:52
Axis zAxis
Definition: diagram.h:101
Q3PtrList< struct Arc > Arcs
Definition: diagram.h:96
Definition: diagram.h:47
bool log
Definition: diagram.h:50
Definition: element.h:82
int x3
Definition: diagram.h:100
Definition: element.h:48
bool calcAxisLogScale(Axis *, int &, double &, double &, double &, int)
Definition: diagram.cpp:1783
Superclass of all schematic drawing elements.
Definition: element.h:142
double max
Definition: diagram.h:48
double limit_max
Definition: diagram.h:56
int y3
Definition: diagram.h:100
QTabWidget * DocumentTab
Definition: qucs.h:164
Q3PtrList< Text > Texts
Definition: diagram.h:98
bool calcAxisScale(Axis *, double &, double &, double &, double &, double)
Definition: diagram.cpp:1665
bool insideDiagram(float, float)
Axis yAxis
Definition: diagram.h:101
Diagram * newOne()
double step
Definition: diagram.h:56
double up
Definition: diagram.h:49
void calcLimits()
int x2
Definition: element.h:153
bool autoScale
Definition: diagram.h:55
bool calcYAxis(Axis *, int)
Definition: diagram.cpp:1874
Q3PtrList< Line > Lines
Definition: diagram.h:97
double low
Definition: diagram.h:49
double min
Definition: diagram.h:48