Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 1997-05-21 |
2 | // Created by: Prihodyko Michael | |
3 | // Copyright (c) 1997-1999 Matra Datavision | |
4 | // Copyright (c) 1999-2012 OPEN CASCADE SAS | |
5 | // | |
6 | // The content of this file is subject to the Open CASCADE Technology Public | |
7 | // License Version 6.5 (the "License"). You may not use the content of this file | |
8 | // except in compliance with the License. Please obtain a copy of the License | |
9 | // at http://www.opencascade.org and read it completely before using this file. | |
10 | // | |
11 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its | |
12 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. | |
13 | // | |
14 | // The Original Code and all software distributed under the License is | |
15 | // distributed on an "AS IS" basis, without warranty of any kind, and the | |
16 | // Initial Developer hereby disclaims all such warranties, including without | |
17 | // limitation, any warranties of merchantability, fitness for a particular | |
18 | // purpose or non-infringement. Please see the License for the specific terms | |
19 | // and conditions governing the rights and limitations under the License. | |
20 | ||
7fd59977 | 21 | // Modified by mpo, Tue Jul 8 15:31:23 1997 |
22 | // Modified 23/02/98 : FMN ; Remplacement PI par Standard_PI | |
23 | ||
24 | ||
25 | /////////////////////////////////////////////////////////////////////////////////////// | |
26 | ///////////////////////////////// EXAMPLE OF USE ////////////////////////////////////// | |
27 | /////////////////////////////////////////////////////////////////////////////////////// | |
28 | /* | |
29 | mpo_one_line aLine; | |
30 | // Drawing filled arc | |
31 | Standard_Integer n = __InitFillArc (X, Y, anXradius, anYradius, aStartAngle, anOpenAngle, | |
32 | 0.0, 0.0, 0.2*(myHeight/myWidth)); | |
33 | for (Standard_Integer i = 1; i <= n; i++) { | |
34 | __GetLineOfFilledArc (i, aLine); | |
35 | DrawSegment (aLine.X1, aLine.Y1, aLine.X2, aLine.Y2); | |
36 | if (aLine.type == 2) | |
37 | DrawSegment (aLine.X3, aLine.Y3, aLine.X4, aLine.Y4); | |
38 | } | |
39 | __DoneFillArc (); | |
40 | */ | |
41 | ||
42 | //-------------------------------------------------------- | |
43 | #include <math.h> | |
44 | #include <stdlib.h> | |
c6541a0c D |
45 | #ifndef __MATH_WNT_H |
46 | # include <Standard_math.hxx> | |
47 | #endif /* __MATH_WNT_H */ | |
7fd59977 | 48 | #include <Standard_Stream.hxx> |
49 | #include <PlotMgt_fill.hxx> | |
7fd59977 | 50 | #define maxDouble ((double)1.E+30) |
51 | //-------------------------------------------------------- | |
52 | ||
53 | /* | |
54 | // Description: | |
55 | // fill sectorof arc with rotated lines and | |
56 | // arc can be rotated too... | |
57 | ||
58 | // Some about algorithm: | |
59 | // rotate everything so, that lines become horizontal and then | |
60 | // seek points of intersection between each line and sector and | |
61 | // then rotate it in other way | |
62 | ||
63 | // Some about using it: | |
64 | // Call __InitFillArc() to initialize computations | |
65 | // Using __GetLineOfFilledArc() you can get each line of filling | |
66 | // Call of __DoneFillArc() will free all allocated memory and will end your computations | |
67 | ||
68 | // Initialize sector filling | |
69 | // X, Y -- coordinates of ellipse | |
70 | // a, b -- radiuses of ellipse | |
71 | // alpha -- start angle of fill, beta -- add angle of filling | |
72 | // gamma -- rotation angle of filling (non-dependent of delta) | |
73 | // delta -- rotation angle of ellipse | |
74 | // step -- filling step | |
75 | int __InitFillArc(double X, double Y, double a, double b, double alpha, | |
76 | double beta, double gamma, double delta, double step); | |
77 | ||
78 | // Get another line of fill | |
79 | // n -- number of line | |
80 | // data -- structure for retrieving coordinates of points | |
81 | // data->n -- number of lines = {0, 1, 2} | |
82 | // if data->n = 1 line is (data->X1, data->Y1, data->X2, data->Y2) | |
83 | // if data->n = 2 line is (data->X1, data->Y1, data->X2, data->Y2) and | |
84 | // (data->X3, data->Y3, data->X4, data->Y4) | |
85 | int __GetLineOfFilledArc(int n, mpo_one_line &data); | |
86 | ||
87 | // Finish all job | |
88 | void __DoneFillArc(void); | |
89 | */ | |
90 | ||
91 | //----------------------------- Implementation ----------------------- | |
92 | ||
93 | int mpo_count; | |
94 | int mpo_start; | |
95 | mpo_one_line *mpo_lines; | |
96 | ||
97 | //Truncate double number | |
98 | double ftrunc(double a) | |
99 | { | |
100 | a = floor(a); | |
101 | if (a<0) a++; | |
102 | return a; | |
103 | } | |
104 | ||
105 | //trigon functs | |
106 | double fsin(double a) | |
107 | { | |
108 | return sin(a); | |
109 | } | |
110 | double fcos(double a) | |
111 | { | |
112 | return cos(a); | |
113 | } | |
114 | double ftan(double a) | |
115 | { | |
116 | return tan(a); | |
117 | } | |
118 | double fatan2(double a, double b) | |
119 | { | |
120 | return atan2(a, b); | |
121 | } | |
122 | double fsqrt(double a) | |
123 | { | |
124 | return sqrt(a); | |
125 | } | |
126 | ||
127 | // Determine is angle a is between b and b+c (c>0) | |
128 | int mpo_inside(double a, double b, double c) | |
129 | { | |
c6541a0c D |
130 | while (b<0) {b += 2*M_PI;}; b -= 2*M_PI*ftrunc(b/(2*M_PI)); |
131 | c -= 2*M_PI*ftrunc(c/(2*M_PI)); | |
132 | while (a<0) {a+=2*M_PI;}; a -= 2*M_PI*ftrunc(a/(2*M_PI)); | |
133 | // while(c<0) {c+=2*M_PI;}; c-=2*M_PI*ftrunc(c/(2*M_PI)); | |
7fd59977 | 134 | if ((a > b) && (a < b+c)) return 1; |
c6541a0c | 135 | else if ((2*M_PI+a > b) && (2*M_PI+a < b+c)) return 1; |
7fd59977 | 136 | return 0; |
137 | } | |
138 | ||
139 | int __InitFillArc(double X, double Y, double a, double b, double alpha, | |
140 | double beta, double gamma, double delta, double step) | |
141 | { | |
142 | int i ; | |
c6541a0c | 143 | alpha -= 2*M_PI*ftrunc(alpha/(2*M_PI)); beta -= 2*M_PI*ftrunc(beta/(2*M_PI)); |
7fd59977 | 144 | if (beta < 0.0) |
145 | { | |
146 | alpha += beta; beta = -beta; | |
147 | } | |
148 | delta -= gamma; alpha -= gamma; | |
149 | ||
150 | double C1 = b*b*fcos(delta)*fcos(delta) + a*a*fsin(delta)*fsin(delta); | |
151 | double C3 = b*b*fsin(delta)*fsin(delta) + a*a*fcos(delta)*fcos(delta); | |
152 | double C2 = fsin(delta)*fcos(delta)*(b*b - a*a); | |
153 | // cout << "C1 = " << C1 << "; C2 = " << C2 << "; C3 = " << C3 << endl << flush; | |
154 | double Ys = a*b/fsqrt(C3 - C2*C2/C1)-0.5*step; | |
155 | int size = int( ftrunc(2*Ys/step) + 1 ); | |
156 | // cout << "Ysize = " << Ys << endl << flush; | |
157 | // cout << "Size = " << size << endl << flush; | |
c6541a0c D |
158 | // cout << "Alpha = " << alpha*180/M_PI << endl << flush; |
159 | // cout << "Beta = " << beta*180/M_PI << endl << flush; | |
7fd59977 | 160 | mpo_lines = (mpo_one_line*)malloc(sizeof(mpo_one_line)*size); |
161 | for ( i = 0; i < size; i++) | |
162 | { | |
163 | double Yt = Ys - i*step; | |
164 | (mpo_lines+i)->X1 = (-C2*Yt - fsqrt(C2*C2*Yt*Yt - C1*(C3*Yt*Yt - a*a*b*b)))/C1; | |
165 | (mpo_lines+i)->X2 = (-C2*Yt + fsqrt(C2*C2*Yt*Yt - C1*(C3*Yt*Yt - a*a*b*b)))/C1; | |
c6541a0c D |
166 | // cout << "alpha = " << alpha*180/M_PI << " alpha+beta = " << (alpha+beta)*180/M_PI << endl << flush; |
167 | // cout << "" << fatan2(Yt, (mpo_lines+i)->X2)*180/M_PI << " type " << (mpo_lines+i)->type << endl << flush;; | |
7fd59977 | 168 | // cout << "Xleft = " << (mpo_lines+i)->X1 << " Xright = " << (mpo_lines+i)->X2 << endl << flush; |
169 | // cout << "C2*C2 - C1*(C3*Yt*Yt - a*a*b*b) = " << C2*C2 - C1*(C3*Yt*Yt - a*a*b*b) << endl << flush; | |
170 | // cout << "C1*(C3*Yt*Yt - a*a*b*b) = " << C1*(C3*Yt*Yt - a*a*b*b) << endl << flush; | |
171 | // cout << "C2*C2 = " << C2*C2 << endl << flush; | |
172 | if (Yt > 0.0) | |
173 | { | |
174 | if (fsin(alpha) <= 0.0) (mpo_lines+i)->X3 = maxDouble; | |
175 | else (mpo_lines+i)->X3 = Yt/ftan(alpha); | |
176 | if (fsin(alpha+beta) <= 0.0) (mpo_lines+i)->X4 = maxDouble; | |
177 | else (mpo_lines+i)->X4 = Yt/ftan(alpha+beta); | |
178 | if (((mpo_lines+i)->X3 > (mpo_lines+i)->X2) || ((mpo_lines+i)->X3 < (mpo_lines+i)->X1)) | |
179 | (mpo_lines+i)->X3 = maxDouble; | |
180 | if (((mpo_lines+i)->X4 > (mpo_lines+i)->X2) || ((mpo_lines+i)->X4 < (mpo_lines+i)->X1)) | |
181 | (mpo_lines+i)->X4 = maxDouble; | |
182 | if (((mpo_lines+i)->X3 != maxDouble)&&((mpo_lines+i)->X4 != maxDouble)) | |
183 | if ((mpo_lines+i)->X3 <= (mpo_lines+i)->X4) (mpo_lines+i)->type = 0; | |
184 | else | |
185 | { | |
186 | (mpo_lines+i)->type = 1; | |
187 | double tmp = (mpo_lines+i)->X3; (mpo_lines+i)->X3 = (mpo_lines+i)->X4; (mpo_lines+i)->X4 = tmp; | |
188 | } | |
189 | else if ((mpo_lines+i)->X3 != maxDouble) | |
190 | { | |
191 | (mpo_lines+i)->type = 2; (mpo_lines+i)->X4 = (mpo_lines+i)->X3; | |
192 | } | |
193 | else if ((mpo_lines+i)->X4 != maxDouble) | |
194 | { | |
195 | (mpo_lines+i)->type = 3; (mpo_lines+i)->X3 = (mpo_lines+i)->X4; | |
196 | } | |
197 | else if (mpo_inside(fatan2((double)Yt,(double)((mpo_lines+i)->X2)), alpha, beta)) | |
198 | (mpo_lines+i)->type = 5; | |
199 | else (mpo_lines+i)->type = 4; | |
200 | } | |
201 | else if (Yt <= 0.0) //!!!!! | |
202 | { | |
203 | if (fsin(alpha) >= 0.0) (mpo_lines+i)->X3 = maxDouble; | |
204 | else (mpo_lines+i)->X3 = Yt/ftan(alpha); | |
205 | if (fsin(alpha+beta) >= 0.0) (mpo_lines+i)->X4 = maxDouble; | |
206 | else (mpo_lines+i)->X4 = Yt/ftan(alpha+beta); | |
207 | if (((mpo_lines+i)->X3 > (mpo_lines+i)->X2) || ((mpo_lines+i)->X3 < (mpo_lines+i)->X1)) | |
208 | (mpo_lines+i)->X3 = maxDouble; | |
209 | if (((mpo_lines+i)->X4 > (mpo_lines+i)->X2) || ((mpo_lines+i)->X4 < (mpo_lines+i)->X1)) | |
210 | (mpo_lines+i)->X4 = maxDouble; | |
211 | if (((mpo_lines+i)->X3 != maxDouble)&&((mpo_lines+i)->X4 != maxDouble)) | |
212 | if ((mpo_lines+i)->X3 >= (mpo_lines+i)->X4) | |
213 | { | |
214 | (mpo_lines+i)->type = 0; | |
215 | double tmp = (mpo_lines+i)->X3; (mpo_lines+i)->X3 = (mpo_lines+i)->X4; (mpo_lines+i)->X4 = tmp; | |
216 | } | |
217 | else (mpo_lines+i)->type = 1; | |
218 | else if ((mpo_lines+i)->X3 != maxDouble) (mpo_lines+i)->type = 3; | |
219 | else if ((mpo_lines+i)->X4 != maxDouble) (mpo_lines+i)->type = 2; | |
220 | else if (mpo_inside(fatan2((double)Yt, (double)((mpo_lines+i)->X2)), alpha, beta)) | |
221 | (mpo_lines+i)->type = 5; | |
222 | else (mpo_lines+i)->type = 4; | |
223 | } | |
224 | else; | |
225 | // cout << "Xlm = " << (mpo_lines+i)->X3 << " Xrm = " << (mpo_lines+i)->X4 << endl << flush; | |
226 | // cout << "------------ i = " << i << endl << flush; | |
227 | } | |
228 | mpo_start = 0; mpo_count = 0; | |
229 | while (((mpo_lines+mpo_start)->type == 4)&&(mpo_start < size)) mpo_start++; | |
230 | while (((mpo_lines+mpo_start+mpo_count)->type != 4)&&((mpo_start+mpo_count < size))) mpo_count++; | |
231 | // cout << "start = " << mpo_start << " count = " << mpo_count << endl << flush; | |
232 | for (i = mpo_start; i < mpo_count+mpo_start; i++) | |
233 | { | |
234 | double Yt = Ys - i*step; | |
235 | (mpo_lines+i)->Y1 = (mpo_lines+i)->X1*fsin(gamma) + Yt*fcos(gamma) + Y; | |
236 | (mpo_lines+i)->X1 = (mpo_lines+i)->X1*fcos(gamma) - Yt*fsin(gamma) + X; | |
237 | (mpo_lines+i)->Y2 = (mpo_lines+i)->X2*fsin(gamma) + Yt*fcos(gamma) + Y; | |
238 | (mpo_lines+i)->X2 = (mpo_lines+i)->X2*fcos(gamma) - Yt*fsin(gamma) + X; | |
239 | (mpo_lines+i)->Y3 = (mpo_lines+i)->X3*fsin(gamma) + Yt*fcos(gamma) + Y; | |
240 | (mpo_lines+i)->X3 = (mpo_lines+i)->X3*fcos(gamma) - Yt*fsin(gamma) + X; | |
241 | (mpo_lines+i)->Y4 = (mpo_lines+i)->X4*fsin(gamma) + Yt*fcos(gamma) + Y; | |
242 | (mpo_lines+i)->X4 = (mpo_lines+i)->X4*fcos(gamma) - Yt*fsin(gamma) + X; | |
243 | } | |
244 | return mpo_count; | |
245 | } | |
246 | ||
247 | // Get another line of fill | |
248 | // n -- number of line | |
249 | // data -- structure for retrieving coordinates of points | |
250 | // data->n -- number of lines = {0, 1, 2} | |
251 | // data->n = 1 line is (data->X1, data->Y1, data->X2, data->Y2) | |
252 | // data->n = 2 line is (data->X1, data->Y1, data->X2, data->Y2) and (data->X3, data->Y3, data->X4, data->Y4) | |
253 | int __GetLineOfFilledArc(int n, mpo_one_line &data) | |
254 | { | |
255 | if (n > mpo_count) return 0; n--; n += mpo_start; | |
256 | switch((mpo_lines+n)->type) { | |
257 | case 0: | |
258 | data.type = 2; | |
259 | data.X1 = (mpo_lines+n)->X1; | |
260 | data.Y1 = (mpo_lines+n)->Y1; | |
261 | data.X2 = (mpo_lines+n)->X3; | |
262 | data.Y2 = (mpo_lines+n)->Y3; | |
263 | data.X3 = (mpo_lines+n)->X4; | |
264 | data.Y3 = (mpo_lines+n)->Y4; | |
265 | data.X4 = (mpo_lines+n)->X2; | |
266 | data.Y4 = (mpo_lines+n)->Y2; | |
267 | break; | |
268 | case 1: | |
269 | data.type = 1; | |
270 | data.X1 = (mpo_lines+n)->X3; | |
271 | data.Y1 = (mpo_lines+n)->Y3; | |
272 | data.X2 = (mpo_lines+n)->X4; | |
273 | data.Y2 = (mpo_lines+n)->Y4; | |
274 | break; | |
275 | case 2: | |
276 | data.type = 1; | |
277 | data.X1 = (mpo_lines+n)->X1; | |
278 | data.Y1 = (mpo_lines+n)->Y1; | |
279 | data.X2 = (mpo_lines+n)->X4; | |
280 | data.Y2 = (mpo_lines+n)->Y4; | |
281 | break; | |
282 | case 3: | |
283 | data.type = 1; | |
284 | data.X1 = (mpo_lines+n)->X3; | |
285 | data.Y1 = (mpo_lines+n)->Y3; | |
286 | data.X2 = (mpo_lines+n)->X2; | |
287 | data.Y2 = (mpo_lines+n)->Y2; | |
288 | break; | |
289 | case 4: | |
290 | cout << "??????????????????" << endl << flush; // doesn't exist | |
291 | break; | |
292 | case 5: | |
293 | data.type = 1; | |
294 | data.X1 = (mpo_lines+n)->X1; | |
295 | data.Y1 = (mpo_lines+n)->Y1; | |
296 | data.X2 = (mpo_lines+n)->X2; | |
297 | data.Y2 = (mpo_lines+n)->Y2; | |
298 | break; | |
299 | } | |
300 | return 1; | |
301 | } | |
302 | ||
303 | //Ending job with filler | |
304 | void __DoneFillArc(void) | |
305 | { | |
306 | free(mpo_lines); | |
307 | } |