2 // Created: Wed May 21 10:48:27 1997
3 // Author: Prihodyko Michael
5 // Modified by mpo, Tue Jul 8 15:31:23 1997
6 // Modified 23/02/98 : FMN ; Remplacement PI par Standard_PI
9 ///////////////////////////////////////////////////////////////////////////////////////
10 ///////////////////////////////// EXAMPLE OF USE //////////////////////////////////////
11 ///////////////////////////////////////////////////////////////////////////////////////
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);
21 DrawSegment (aLine.X3, aLine.Y3, aLine.X4, aLine.Y4);
26 //--------------------------------------------------------
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 //--------------------------------------------------------
39 // fill sectorof arc with rotated lines and
40 // arc can be rotated too...
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
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
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);
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);
72 void __DoneFillArc(void);
75 //----------------------------- Implementation -----------------------
79 mpo_one_line *mpo_lines;
81 //Truncate double number
82 double ftrunc(double a)
102 double fatan2(double a, double b)
106 double fsqrt(double a)
111 // Determine is angle a is between b and b+c (c>0)
112 int mpo_inside(double a, double b, double c)
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;
123 int __InitFillArc(double X, double Y, double a, double b, double alpha,
124 double beta, double gamma, double delta, double step)
127 alpha -= 2*M_PI*ftrunc(alpha/(2*M_PI)); beta -= 2*M_PI*ftrunc(beta/(2*M_PI));
130 alpha += beta; beta = -beta;
132 delta -= gamma; alpha -= gamma;
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++)
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;
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;
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;
173 else if ((mpo_lines+i)->X3 != maxDouble)
175 (mpo_lines+i)->type = 2; (mpo_lines+i)->X4 = (mpo_lines+i)->X3;
177 else if ((mpo_lines+i)->X4 != maxDouble)
179 (mpo_lines+i)->type = 3; (mpo_lines+i)->X3 = (mpo_lines+i)->X4;
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;
185 else if (Yt <= 0.0) //!!!!!
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)
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;
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;
209 // cout << "Xlm = " << (mpo_lines+i)->X3 << " Xrm = " << (mpo_lines+i)->X4 << endl << flush;
210 // cout << "------------ i = " << i << endl << flush;
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++)
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;
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)
239 if (n > mpo_count) return 0; n--; n += mpo_start;
240 switch((mpo_lines+n)->type) {
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;
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;
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;
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;
274 cout << "??????????????????" << endl << flush; // doesn't exist
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;
287 //Ending job with filler
288 void __DoneFillArc(void)