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