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