0022792: Globally defined symbol PI conflicts with VTK definition (Intel compiler)
[occt.git] / src / PlotMgt / PlotMgt_fillpolyarc.cxx
1 // File:        fill.cxx
2 // Created:     Wed May 21 10:48:27 1997
3 // Author:      Prihodyko Michael
4 //              <kim@maniax>
5 // Modified by mpo, Tue Jul  8 15:31:23 1997
6 // Modified     23/02/98 : FMN ; Remplacement PI par Standard_PI
7
8
9 ///////////////////////////////////////////////////////////////////////////////////////
10 ///////////////////////////////// EXAMPLE OF USE //////////////////////////////////////
11 ///////////////////////////////////////////////////////////////////////////////////////
12 /*
13   mpo_one_line aLine;
14   // Drawing filled arc
15   Standard_Integer n = __InitFillArc (X, Y, anXradius, anYradius, aStartAngle, anOpenAngle,
16                                       0.0, 0.0, 0.2*(myHeight/myWidth));
17   for (Standard_Integer i = 1; i <= n; i++) {
18     __GetLineOfFilledArc (i, aLine);
19     DrawSegment (aLine.X1, aLine.Y1, aLine.X2, aLine.Y2);
20     if (aLine.type == 2)
21       DrawSegment (aLine.X3, aLine.Y3, aLine.X4, aLine.Y4);
22   }
23   __DoneFillArc ();
24 */
25
26 //--------------------------------------------------------
27 #include <math.h>
28 #include <stdlib.h>
29 #ifndef __MATH_WNT_H
30 # include <Standard_math.hxx>
31 #endif  /* __MATH_WNT_H */
32 #include <Standard_Stream.hxx>
33 #include <PlotMgt_fill.hxx>
34 #define maxDouble ((double)1.E+30)
35 //--------------------------------------------------------
36
37 /*
38 // Description:
39 //   fill sectorof arc with rotated lines and
40 //   arc can be rotated too...
41
42 // Some about algorithm:
43 //   rotate everything so, that lines become horizontal and then
44 //   seek points of intersection between each line and sector and
45 //   then rotate it in other way
46
47 // Some about using it:
48 //   Call __InitFillArc() to initialize computations
49 //   Using __GetLineOfFilledArc() you can get each line of filling
50 //   Call of __DoneFillArc() will free all allocated memory and will end your computations
51
52 // Initialize sector filling
53 // X, Y -- coordinates of ellipse
54 // a, b -- radiuses of ellipse
55 // alpha -- start angle of fill, beta -- add angle of filling
56 // gamma -- rotation angle of filling (non-dependent of delta)
57 // delta -- rotation angle of ellipse
58 // step -- filling step
59 int __InitFillArc(double X,  double Y, double a, double b, double alpha, 
60                   double beta, double gamma, double delta, double step);
61
62 // Get another line of fill
63 // n -- number of line
64 // data -- structure for retrieving coordinates of points
65 // data->n -- number of lines = {0, 1, 2}
66 //   if data->n = 1 line is (data->X1, data->Y1, data->X2, data->Y2)
67 //   if data->n = 2 line is (data->X1, data->Y1, data->X2, data->Y2) and 
68 //                          (data->X3, data->Y3, data->X4, data->Y4)
69 int __GetLineOfFilledArc(int n, mpo_one_line &data);
70
71 // Finish all job
72 void __DoneFillArc(void);
73 */
74
75 //----------------------------- Implementation -----------------------
76
77 int mpo_count;
78 int mpo_start;
79 mpo_one_line *mpo_lines;
80
81 //Truncate double number
82 double ftrunc(double a)
83 {
84   a = floor(a);
85   if (a<0) a++;
86   return a;
87 }
88
89 //trigon functs
90 double fsin(double a)
91 {
92   return sin(a);
93 }
94 double fcos(double a)
95 {
96   return cos(a);
97 }
98 double ftan(double a)
99 {
100   return tan(a);
101 }
102 double fatan2(double a, double b)
103 {
104   return atan2(a, b);
105 }
106 double fsqrt(double a)
107 {
108   return sqrt(a);
109 }
110
111 // Determine is angle a is between b and b+c (c>0)
112 int mpo_inside(double a, double b, double c)
113 {
114   while (b<0) {b += 2*M_PI;}; b -= 2*M_PI*ftrunc(b/(2*M_PI));
115   c -= 2*M_PI*ftrunc(c/(2*M_PI));
116   while (a<0) {a+=2*M_PI;}; a -= 2*M_PI*ftrunc(a/(2*M_PI));
117 //  while(c<0) {c+=2*M_PI;}; c-=2*M_PI*ftrunc(c/(2*M_PI));
118   if ((a > b) && (a < b+c)) return 1;
119   else if ((2*M_PI+a > b) && (2*M_PI+a < b+c)) return 1;
120   return 0;
121 }
122
123 int __InitFillArc(double X,  double Y, double a, double b, double alpha, 
124                   double beta, double gamma, double delta, double step)
125 {
126   int i ;
127   alpha -= 2*M_PI*ftrunc(alpha/(2*M_PI)); beta -= 2*M_PI*ftrunc(beta/(2*M_PI));
128   if (beta < 0.0) 
129     {
130       alpha += beta; beta = -beta;
131     }
132   delta -= gamma; alpha -= gamma;
133
134   double C1 = b*b*fcos(delta)*fcos(delta) + a*a*fsin(delta)*fsin(delta);
135   double C3 = b*b*fsin(delta)*fsin(delta) + a*a*fcos(delta)*fcos(delta);
136   double C2 = fsin(delta)*fcos(delta)*(b*b - a*a);
137 //  cout << "C1 = " << C1 << ";    C2 = " << C2 << ";   C3 = " << C3 << endl << flush;
138   double Ys = a*b/fsqrt(C3 - C2*C2/C1)-0.5*step;
139   int size = int( ftrunc(2*Ys/step) + 1 );
140 //  cout << "Ysize = " << Ys << endl << flush;
141 //  cout << "Size  = " << size << endl << flush;
142 //  cout << "Alpha = " << alpha*180/M_PI << endl << flush;
143 //  cout << "Beta  = " << beta*180/M_PI << endl << flush;
144   mpo_lines = (mpo_one_line*)malloc(sizeof(mpo_one_line)*size);
145   for ( i = 0; i < size; i++)
146     {
147       double Yt = Ys - i*step;
148       (mpo_lines+i)->X1 = (-C2*Yt - fsqrt(C2*C2*Yt*Yt - C1*(C3*Yt*Yt - a*a*b*b)))/C1;
149       (mpo_lines+i)->X2 = (-C2*Yt + fsqrt(C2*C2*Yt*Yt - C1*(C3*Yt*Yt - a*a*b*b)))/C1;
150 //    cout << "alpha = " << alpha*180/M_PI << "    alpha+beta = " << (alpha+beta)*180/M_PI << endl << flush;
151 //    cout << "" << fatan2(Yt, (mpo_lines+i)->X2)*180/M_PI << "     type " << (mpo_lines+i)->type << endl << flush;;
152 //    cout << "Xleft = " << (mpo_lines+i)->X1 << "     Xright = " << (mpo_lines+i)->X2 << endl << flush;
153 //    cout << "C2*C2 - C1*(C3*Yt*Yt - a*a*b*b) = " << C2*C2 - C1*(C3*Yt*Yt - a*a*b*b) << endl << flush;
154 //    cout << "C1*(C3*Yt*Yt - a*a*b*b) = " << C1*(C3*Yt*Yt - a*a*b*b) << endl << flush;
155 //    cout << "C2*C2 = " << C2*C2 << endl << flush;
156       if (Yt > 0.0)
157         {
158           if (fsin(alpha) <= 0.0) (mpo_lines+i)->X3 = maxDouble;
159           else (mpo_lines+i)->X3 = Yt/ftan(alpha);
160           if (fsin(alpha+beta) <= 0.0) (mpo_lines+i)->X4 = maxDouble;
161           else (mpo_lines+i)->X4 = Yt/ftan(alpha+beta);
162           if (((mpo_lines+i)->X3 > (mpo_lines+i)->X2) || ((mpo_lines+i)->X3 < (mpo_lines+i)->X1))
163             (mpo_lines+i)->X3 = maxDouble; 
164           if (((mpo_lines+i)->X4 > (mpo_lines+i)->X2) || ((mpo_lines+i)->X4 < (mpo_lines+i)->X1))
165             (mpo_lines+i)->X4 = maxDouble; 
166           if (((mpo_lines+i)->X3 != maxDouble)&&((mpo_lines+i)->X4 != maxDouble))
167             if ((mpo_lines+i)->X3 <= (mpo_lines+i)->X4) (mpo_lines+i)->type = 0;
168             else 
169               {
170                 (mpo_lines+i)->type = 1;
171                 double tmp = (mpo_lines+i)->X3; (mpo_lines+i)->X3 = (mpo_lines+i)->X4; (mpo_lines+i)->X4 = tmp; 
172               }
173           else if ((mpo_lines+i)->X3 != maxDouble) 
174             {
175               (mpo_lines+i)->type = 2; (mpo_lines+i)->X4 = (mpo_lines+i)->X3;
176             }
177           else if ((mpo_lines+i)->X4 != maxDouble) 
178             {
179               (mpo_lines+i)->type = 3; (mpo_lines+i)->X3 = (mpo_lines+i)->X4;
180             }
181           else if (mpo_inside(fatan2((double)Yt,(double)((mpo_lines+i)->X2)), alpha, beta))
182             (mpo_lines+i)->type = 5;
183           else (mpo_lines+i)->type = 4;
184         }
185       else if (Yt <= 0.0)   //!!!!!
186         {
187           if (fsin(alpha) >= 0.0) (mpo_lines+i)->X3 = maxDouble;
188           else (mpo_lines+i)->X3 = Yt/ftan(alpha);
189           if (fsin(alpha+beta) >= 0.0) (mpo_lines+i)->X4 = maxDouble;
190           else (mpo_lines+i)->X4 = Yt/ftan(alpha+beta);
191           if (((mpo_lines+i)->X3 > (mpo_lines+i)->X2) || ((mpo_lines+i)->X3 < (mpo_lines+i)->X1))
192             (mpo_lines+i)->X3 = maxDouble; 
193           if (((mpo_lines+i)->X4 > (mpo_lines+i)->X2) || ((mpo_lines+i)->X4 < (mpo_lines+i)->X1))
194             (mpo_lines+i)->X4 = maxDouble; 
195           if (((mpo_lines+i)->X3 != maxDouble)&&((mpo_lines+i)->X4 != maxDouble))
196             if ((mpo_lines+i)->X3 >= (mpo_lines+i)->X4) 
197               {
198                 (mpo_lines+i)->type = 0; 
199                 double tmp = (mpo_lines+i)->X3; (mpo_lines+i)->X3 = (mpo_lines+i)->X4; (mpo_lines+i)->X4 = tmp; 
200               }
201             else (mpo_lines+i)->type = 1;
202           else if ((mpo_lines+i)->X3 != maxDouble) (mpo_lines+i)->type = 3;
203           else if ((mpo_lines+i)->X4 != maxDouble) (mpo_lines+i)->type = 2;
204           else if (mpo_inside(fatan2((double)Yt, (double)((mpo_lines+i)->X2)), alpha, beta))
205             (mpo_lines+i)->type = 5;
206           else (mpo_lines+i)->type = 4;
207         }
208       else;
209 //      cout << "Xlm  = " << (mpo_lines+i)->X3 << "      Xrm  = " << (mpo_lines+i)->X4 << endl << flush;
210 //      cout << "------------ i = " << i << endl << flush;
211     }
212   mpo_start = 0; mpo_count = 0;
213   while (((mpo_lines+mpo_start)->type == 4)&&(mpo_start < size)) mpo_start++;
214   while (((mpo_lines+mpo_start+mpo_count)->type != 4)&&((mpo_start+mpo_count < size))) mpo_count++;  
215 //  cout << "start = " << mpo_start << "   count = " << mpo_count << endl << flush;
216   for (i = mpo_start; i < mpo_count+mpo_start; i++) 
217     {
218       double Yt = Ys - i*step;
219       (mpo_lines+i)->Y1 =  (mpo_lines+i)->X1*fsin(gamma) + Yt*fcos(gamma) + Y;
220       (mpo_lines+i)->X1 =  (mpo_lines+i)->X1*fcos(gamma) - Yt*fsin(gamma) + X;
221       (mpo_lines+i)->Y2 =  (mpo_lines+i)->X2*fsin(gamma) + Yt*fcos(gamma) + Y;
222       (mpo_lines+i)->X2 =  (mpo_lines+i)->X2*fcos(gamma) - Yt*fsin(gamma) + X;
223       (mpo_lines+i)->Y3 =  (mpo_lines+i)->X3*fsin(gamma) + Yt*fcos(gamma) + Y;
224       (mpo_lines+i)->X3 =  (mpo_lines+i)->X3*fcos(gamma) - Yt*fsin(gamma) + X;
225       (mpo_lines+i)->Y4 =  (mpo_lines+i)->X4*fsin(gamma) + Yt*fcos(gamma) + Y;
226       (mpo_lines+i)->X4 =  (mpo_lines+i)->X4*fcos(gamma) - Yt*fsin(gamma) + X;
227     }
228   return mpo_count;
229 }
230
231 // Get another line of fill
232 // n -- number of line
233 // data -- structure for retrieving coordinates of points
234 // data->n -- number of lines = {0, 1, 2}
235 //   data->n = 1 line is (data->X1, data->Y1, data->X2, data->Y2)
236 //   data->n = 2 line is (data->X1, data->Y1, data->X2, data->Y2) and (data->X3, data->Y3, data->X4, data->Y4)
237 int __GetLineOfFilledArc(int n, mpo_one_line &data)
238 {
239   if (n > mpo_count) return 0; n--; n += mpo_start;
240   switch((mpo_lines+n)->type) {
241     case 0:
242       data.type = 2;
243       data.X1 = (mpo_lines+n)->X1;
244       data.Y1 = (mpo_lines+n)->Y1;
245       data.X2 = (mpo_lines+n)->X3;
246       data.Y2 = (mpo_lines+n)->Y3;
247       data.X3 = (mpo_lines+n)->X4;
248       data.Y3 = (mpo_lines+n)->Y4;
249       data.X4 = (mpo_lines+n)->X2;
250       data.Y4 = (mpo_lines+n)->Y2;
251       break;
252     case 1:
253       data.type = 1;
254       data.X1 = (mpo_lines+n)->X3;
255       data.Y1 = (mpo_lines+n)->Y3;
256       data.X2 = (mpo_lines+n)->X4;
257       data.Y2 = (mpo_lines+n)->Y4;
258       break;
259     case 2:
260       data.type = 1;
261       data.X1 = (mpo_lines+n)->X1;
262       data.Y1 = (mpo_lines+n)->Y1;
263       data.X2 = (mpo_lines+n)->X4;
264       data.Y2 = (mpo_lines+n)->Y4;
265       break;
266     case 3:
267       data.type = 1;
268       data.X1 = (mpo_lines+n)->X3;
269       data.Y1 = (mpo_lines+n)->Y3;
270       data.X2 = (mpo_lines+n)->X2;
271       data.Y2 = (mpo_lines+n)->Y2;
272       break;
273     case 4:
274       cout << "??????????????????" << endl << flush;  // doesn't exist
275       break;
276     case 5:
277       data.type = 1;
278       data.X1 = (mpo_lines+n)->X1;
279       data.Y1 = (mpo_lines+n)->Y1;
280       data.X2 = (mpo_lines+n)->X2;
281       data.Y2 = (mpo_lines+n)->Y2;
282       break;
283   }
284   return 1;
285 }
286
287 //Ending job with filler
288 void __DoneFillArc(void)
289 {
290   free(mpo_lines);
291 }