Imported Upstream version 4.6.0
[debian/atlc] / src / non_gui / convert_create_bmp_for_rect_in_rect_dimensions_to_integers.c
1 /* atlc - arbitrary transmission line calculator, for the analysis of
2 transmission lines are directional couplers. 
3
4 Copyright (C) 2002. Dr. David Kirkby, PhD (G8WRB).
5
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation; either package_version 2
9 of the License, or (at your option) any later package_version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
19 USA.
20
21 Dr. David Kirkby, e-mail drkirkby at ntlworld.com 
22
23 */
24 #include "config.h"
25
26
27 #ifdef HAVE_STRING_H
28 #include <string.h>
29 #endif
30
31 #ifdef HAVE_STRINGS_H
32 #include <strings.h>
33 #endif
34
35 #ifdef HAVE_STDLIB_H
36 #include <stdlib.h>
37 #endif
38
39 #ifdef HAVE_MATH_H
40 #include <math.h>
41 #endif
42
43 #include "definitions.h"
44 #include "exit_codes.h"
45
46 /* names, colours and Ers are all arrays of 10. It would be better they were 
47 in a structure as they are all linked closely, but they are not and I
48 can't be bothered to change it */
49
50 extern double WW, HH, aa, bb, cc, dd, ww, hh, Er1, Er2;
51 extern int W, H, a, b, c, d, w, h;
52 extern int verbose;
53 extern int lowest;
54 extern int highest;
55
56 void convert_create_bmp_for_rect_in_rect_dimensions_to_integers(int accuracy_level) 
57 {
58    /* A number of paramters are set to -1, as otherwise the compiler   
59    complaings they may be used unitialised. It is wise to check they
60    are not -1 before assining a variable to their contents, 
61    but I can't be bothered. */
62    int best_W=-1, best_H=-1, best_a=-1, best_b=-1, best_c=-1;
63    int best_d=-1, best_w=-1, best_h=-1;
64    int min, max;
65    int i;
66    double max_gridsize, min_gridsize;
67    double error, error_min=VERY_LARGE, gridsize=-1, best_grid_size=-1;
68
69    /* scale grid size,  according to a command line option */
70    /*lowest*=(int) 0.5+pow(2,accuracy_level); */
71    /*highest*=(int) 0.5+pow(2,accuracy_level); */
72    lowest*=1<<accuracy_level;
73    highest*=1<<accuracy_level;
74
75    max_gridsize=sqrt(WW*HH/(double )lowest);  /* minimum dimension in m */
76    min_gridsize=sqrt(WW*HH/(double )highest);
77    if(W>=H)
78    {
79       min=WW/max_gridsize;
80       max=WW/min_gridsize;
81    }
82    else
83    {
84       min=HH/max_gridsize;
85       max=HH/min_gridsize;
86    }
87    for(i=min;i<=max;++i)
88    {
89       /* Try various combinations for  H,a,b,c, etc */
90       if(W>H)
91          gridsize=WW/i;
92       else
93          gridsize=HH/i;
94       W=(int)(WW/gridsize + 0.5);
95       H=(int)(HH/gridsize + 0.5);
96       a=(int)(aa/gridsize + 0.5);
97       b=(int)(bb/gridsize + 0.5);
98       c=(int)(cc/gridsize + 0.5);
99       d=(int)(dd/gridsize + 0.5);
100       w=(int)(ww/gridsize + 0.5);
101       h=(int)(hh/gridsize + 0.5);
102       error=0.0;
103       error+=pow((WW-W*gridsize)/WW,2.0); /* relative error in W */
104       error+=pow((HH-H*gridsize)/HH,2.0);
105       if(a>0)
106          error+=pow((aa-a*gridsize)/aa,2.0);
107       if(b>0)
108           error+=pow((bb-b*gridsize)/bb,2.0);
109       if(c>0)
110           error+=pow((cc-c*gridsize)/cc,2.0);
111       if(d>0)
112           error+=pow((dd-d*gridsize)/dd,2.0);
113       if(w>0)
114           error+=pow((ww-w*gridsize)/ww,2.0);
115       if(h>0)
116           error+=pow((hh-h*gridsize)/hh,2.0);
117       if(error < (error_min-TINY))
118       {
119           error_min=error;
120           best_W=W;
121           best_H=H;
122           best_a=a;
123           best_b=b;
124           best_c=c;
125           best_d=d;
126           best_w=w;
127           best_h=h;
128           best_grid_size=gridsize;
129       }
130    }
131    W=best_W;
132    H=best_H;
133    a=best_a;
134    b=best_b;
135    c=best_c;
136    d=best_d;
137    w=best_w;
138    h=best_h;
139    if(verbose==TRUE)
140    {
141       fprintf(stderr,"error_min=%.16f\n",error_min);
142       fprintf(stderr,"User requested: WW=%f HH=%f a=%f b=%f c=%f\nd=%f w=%f h=%fEr1=%f Er2=%f\n\n",WW,HH,aa,bb,cc,dd,ww,hh,Er1,Er2);
143       fprintf(stderr,"Internally the program is using the following grid:\n");
144       fprintf(stderr,"W=%d H=%d a=%d b=%d c=%d d=%d w=%d h=%d. \nThe  grid size is %f mm, inches or whatever\n\n", W, H, a, b, c, d, w, h,best_grid_size);
145       if(error_min > TINY)
146       {
147          fprintf(stderr,"This means we are simulating a transmission line with these dimensions:\n");
148          fprintf(stderr,"W=%f H=%f a=%f b=%f c=%f d=%f\nw=%f h=%f (mm, inches or whatever)\n",W*best_grid_size,H*best_grid_size,a*best_grid_size,b*best_grid_size,c*best_grid_size,d*best_grid_size,w*best_grid_size,h*best_grid_size);
149          fprintf(stderr,"\nThese are slightly different to what you indicated on the command line,\n");
150          fprintf(stderr,"but they are the best approximation possible, given the grid size\n");
151       }
152    }
153    if(b == 0)
154    {
155       fprintf(stderr,"Error #12. The gap between the two conductors (b) is too small. Either increase the bitmap size (-b option), or make b at least %f\n",gridsize);
156       exit_with_msg_and_exit_code("",GAP_BETWEEN_CONDUCTORS_TOO_SMALL);
157    }
158    if(c == 0)
159    {
160       fprintf(stderr,"Error #13. The thickness of the inner conductor (c) is too small. Either increase the bitmap size (-b option), or make c at least %f\n",gridsize);
161       exit_with_msg_and_exit_code("",GAP_BETWEEN_CONDUCTORS_TOO_SMALL);
162    }
163    if(h == 0)
164    {
165       fprintf(stderr,"Error #14. The thickness of the dielectric of Er2 (h) is too small. Either increase the bitmap size (-b option), or make h at least %f\n",gridsize);
166       exit_with_msg_and_exit_code("",GAP_BETWEEN_CONDUCTORS_TOO_SMALL);
167    }
168    check_error(WW,W,best_grid_size,"W");
169    check_error(HH,H,best_grid_size,"H");
170    check_error(aa,a,best_grid_size,"a");
171    check_error(bb,b,best_grid_size,"b");
172    check_error(cc,c,best_grid_size,"c");
173    check_error(dd,d,best_grid_size,"d");
174    check_error(ww,w,best_grid_size,"w");
175    check_error(hh,h,best_grid_size,"h");
176 }