7fd59977 |
1 | /*===================================================================== |
2 | |
81bba717 |
3 | FUNCTION : |
7fd59977 |
4 | ---------- |
81bba717 |
5 | Class Graphic2d_Ellips |
7fd59977 |
6 | |
7 | TEST : |
8 | ------ |
9 | |
10 | Voir TestG2D/TestG21 |
11 | |
81bba717 |
12 | NOTES: |
7fd59977 |
13 | ---------- |
14 | |
81bba717 |
15 | HISTORY OF MODIFICATIONS : |
7fd59977 |
16 | -------------------------------- |
17 | |
18 | 27-01-98 : GG ; OPTIMISATION LOADER |
81bba717 |
19 | Transform global static variables into static locals. |
7fd59977 |
20 | |
21 | =====================================================================*/ |
22 | #define G002 //Add new DrawElement(), DrawVertex() methods |
23 | |
24 | #define VERTEXMARKER 2 |
25 | #define DEFAULTMARKERSIZE 3.0 |
26 | |
27 | #include <Graphic2d_Ellips.ixx> |
28 | #include <TShort_Array1OfShortReal.hxx> |
29 | |
30 | #define MAXPOINTS 1023 |
31 | |
32 | Graphic2d_Ellips::Graphic2d_Ellips |
33 | (const Handle(Graphic2d_GraphicObject)& aGraphicObject, |
34 | const Quantity_Length X, |
35 | const Quantity_Length Y, |
36 | const Quantity_Length MajorRadius, |
37 | const Quantity_Length MinorRadius, |
38 | const Quantity_PlaneAngle anAngle) |
39 | : Graphic2d_Line(aGraphicObject) { |
40 | |
41 | myX = Standard_ShortReal(X); |
42 | myY = Standard_ShortReal(Y); |
43 | myMajorRadius = Standard_ShortReal(MajorRadius); |
44 | myMinorRadius = Standard_ShortReal(MinorRadius); |
45 | |
46 | if (myMajorRadius <= RealEpsilon ()) |
47 | Graphic2d_EllipsDefinitionError::Raise ("The major radius = 0."); |
48 | |
49 | if (myMinorRadius <= RealEpsilon ()) |
50 | Graphic2d_EllipsDefinitionError::Raise ("The minor radius = 0."); |
51 | |
52 | myAngle =Standard_ShortReal(anAngle); |
53 | |
81bba717 |
54 | // Case of horizontal ellipse |
7fd59977 |
55 | if (Abs (anAngle) <= RealEpsilon ()) { |
56 | myMinX = myX - myMajorRadius; |
57 | myMaxX = myX + myMajorRadius; |
58 | myMinY = myY - myMinorRadius; |
59 | myMaxY = myY + myMinorRadius; |
60 | } |
61 | else { |
62 | Standard_ShortReal X1, Y1, X2, Y2; |
63 | Standard_Integer nbpoints = 360; // fobenselitmiter |
64 | Standard_ShortReal teta = Standard_ShortReal(2 * Standard_PI / nbpoints); |
65 | Standard_ShortReal x1 = Standard_ShortReal(myMajorRadius * Cos (myAngle)); |
66 | Standard_ShortReal y1 = Standard_ShortReal(myMajorRadius * Sin (myAngle)); |
67 | Standard_ShortReal x2, y2; |
68 | Standard_ShortReal costeta = Standard_ShortReal(Cos(teta)); |
69 | Standard_ShortReal sinteta = Standard_ShortReal(Sin(teta)); |
70 | |
71 | x2 = Standard_ShortReal(myMajorRadius * costeta * Cos (myAngle) - |
72 | myMinorRadius * sinteta * Sin (myAngle)); |
73 | y2 = Standard_ShortReal(myMajorRadius * costeta * Sin (myAngle) + |
74 | myMinorRadius * sinteta * Cos (myAngle)); |
75 | |
76 | X1 = myX + x1; Y1 = myY + y1; |
77 | X2 = myX + x2; Y2 = myY + y2; |
78 | |
79 | myMinX = ( X1 < X2 ? X1 : X2 ); |
80 | myMaxX = ( X1 < X2 ? X2 : X1 ); |
81 | myMinY = ( Y1 < Y2 ? Y1 : Y2 ); |
82 | myMaxY = ( Y1 < Y2 ? Y2 : Y1 ); |
83 | |
84 | nbpoints++; |
85 | for (Standard_Integer i=3; i<= nbpoints; i++) { |
86 | X2 = 2*x2*costeta - x1; |
87 | Y2 = 2*y2*costeta - y1; |
88 | x1 = x2; y1 = y2; x2 = X2; y2 = Y2; |
89 | X2 += myX; Y2 += myY; |
90 | myMinX = ( myMinX < X2 ? myMinX : X2 ); |
91 | myMaxX = ( myMaxX < X2 ? X2 : myMaxX ); |
92 | myMinY = ( myMinY < Y2 ? myMinY : Y2 ); |
93 | myMaxY = ( myMaxY < Y2 ? Y2 : myMaxY ); |
94 | } |
95 | } |
96 | myNumOfElem = 4; |
97 | myNumOfVert = 1; |
98 | } |
99 | |
100 | void Graphic2d_Ellips::Draw (const Handle(Graphic2d_Drawer)& aDrawer) { |
101 | |
102 | Standard_Boolean IsIn = Standard_False; |
103 | |
104 | if (! myGOPtr->IsTransformed ()) |
105 | IsIn = aDrawer->IsIn (myMinX,myMaxX,myMinY,myMaxY); |
106 | else { |
107 | Standard_ShortReal minx, miny, maxx, maxy; |
108 | MinMax(minx,maxx,miny,maxy); |
109 | IsIn = aDrawer->IsIn (minx,maxx,miny,maxy); |
110 | } |
111 | |
112 | if (IsIn) { |
113 | static TShort_Array1OfShortReal Xpoint(1,MAXPOINTS+1); |
114 | static TShort_Array1OfShortReal Ypoint(1,MAXPOINTS+1); |
115 | |
116 | DrawLineAttrib(aDrawer); |
117 | Standard_ShortReal Def; |
118 | Standard_ShortReal Coeff; |
119 | Aspect_TypeOfDeflection Type; |
120 | aDrawer->DrawPrecision(Def,Coeff,Type); |
121 | |
122 | if (Type == Aspect_TOD_RELATIVE) Def = myMajorRadius * Coeff; |
123 | |
124 | Standard_Real val; |
125 | if(myMajorRadius > Def) |
126 | val = Max( 0.0044 , Min (0.7854 , 2. * ACos(1.-Def/myMajorRadius))); |
127 | else |
128 | val = 0.7854; // = PI/4. |
129 | Standard_Integer nbpoints = Min(MAXPOINTS,Standard_Integer(2*Standard_PI/val)+2); |
130 | |
131 | // Standard_Integer nbpoints = Max ( 8 ,Standard_Integer ( myMajorRadius / Def)); |
132 | Standard_ShortReal teta = Standard_ShortReal(2*Standard_PI /nbpoints); |
133 | Standard_ShortReal x1 = Standard_ShortReal(myMajorRadius *Cos (myAngle)), |
134 | y1 = Standard_ShortReal(myMajorRadius *Sin (myAngle)); |
135 | Standard_ShortReal x2,y2; |
136 | Standard_ShortReal cosin = Standard_ShortReal(Cos(teta)); |
137 | |
138 | x2 = Standard_ShortReal(myMajorRadius * Cos(teta) * Cos(myAngle) - |
139 | myMinorRadius * Sin(teta) * Sin(myAngle)); |
140 | y2 = Standard_ShortReal(myMajorRadius * Cos(teta) * Sin(myAngle) + |
141 | myMinorRadius * Sin(teta) * Cos(myAngle)); |
142 | |
143 | Xpoint(1) = myX + x1; Ypoint(1) = myY + y1; |
144 | Xpoint(2) = myX + x2; Ypoint(2) = myY + y2; |
145 | |
146 | nbpoints++; |
147 | for (Standard_Integer i=3; i<= nbpoints; i++) { |
148 | Xpoint(i) = 2*x2*cosin - x1; |
149 | Ypoint(i) = 2*y2*cosin - y1; |
150 | x1 = x2; y1 = y2; x2 = Xpoint(i); y2 = Ypoint(i); |
151 | Xpoint(i) += myX; Ypoint(i) += myY; |
152 | } |
153 | |
154 | if ( myGOPtr->IsTransformed() ) { |
155 | gp_GTrsf2d aTrsf = myGOPtr->Transform (); |
156 | Standard_Real A, B; |
157 | for (Standard_Integer j=1; j<= nbpoints; j++) { |
158 | A = Standard_Real (Xpoint(j)); |
159 | B = Standard_Real (Ypoint(j)); |
160 | aTrsf.Transforms (A, B); |
161 | Xpoint(j) = Standard_ShortReal (A); |
162 | Ypoint(j) = Standard_ShortReal (B); |
163 | } |
164 | } |
165 | |
166 | if (myTypeOfPolygonFilling == Graphic2d_TOPF_EMPTY) { |
167 | aDrawer->MapPolylineFromTo(Xpoint,Ypoint,nbpoints); |
168 | } else { |
169 | aDrawer->MapPolygonFromTo(Xpoint,Ypoint,nbpoints); |
170 | } |
171 | } |
172 | |
173 | } |
174 | |
175 | #ifdef G002 |
176 | |
177 | void Graphic2d_Ellips::DrawElement( const Handle(Graphic2d_Drawer)& aDrawer, |
178 | const Standard_Integer anIndex) { |
179 | |
180 | Standard_Boolean IsIn = Standard_False; |
181 | |
182 | if (! myGOPtr->IsTransformed ()) |
183 | IsIn = aDrawer->IsIn (myMinX,myMaxX,myMinY,myMaxY); |
184 | else { |
185 | Standard_ShortReal minx, miny, maxx, maxy; |
186 | MinMax(minx,maxx,miny,maxy); |
187 | IsIn = aDrawer->IsIn (minx,maxx,miny,maxy); |
188 | } |
189 | |
190 | if (IsIn) { |
191 | if ( anIndex > 0 && anIndex < 5 ) { |
192 | DrawLineAttrib(aDrawer); |
193 | Standard_ShortReal Xp=0., Yp=0.; |
194 | Standard_ShortReal tSin = Standard_ShortReal(Sin(myAngle)), |
195 | tCos = Standard_ShortReal(Cos(myAngle)); |
196 | if ( anIndex == 1 ) { |
197 | Xp = myX - myMinorRadius * tSin; |
198 | Yp = myY + myMinorRadius * tCos; |
199 | } else if ( anIndex == 2 ) { |
200 | Xp = myX + myMajorRadius * tCos; |
201 | Yp = myY + myMajorRadius * tSin; |
202 | } else if ( anIndex == 3 ) { |
203 | Xp = myX - myMajorRadius * tCos; |
204 | Yp = myY - myMajorRadius * tSin; |
205 | } else if ( anIndex == 4 ) { |
206 | Xp = myX + myMinorRadius * tSin; |
207 | Yp = myY - myMinorRadius * tCos; |
208 | } |
209 | |
210 | Standard_Real A, B, C, D; |
211 | Standard_ShortReal a = myX, b = myY, c = Xp, d = Yp; |
212 | if ( myGOPtr->IsTransformed() ) { |
213 | gp_GTrsf2d aTrsf = myGOPtr->Transform (); |
214 | A = Standard_Real(a); |
215 | B = Standard_Real(b); |
216 | C = Standard_Real(c); |
217 | D = Standard_Real(d); |
218 | aTrsf.Transforms (A, B); |
219 | aTrsf.Transforms (C, D); |
220 | a = Standard_ShortReal(A); |
221 | b = Standard_ShortReal(B); |
222 | c = Standard_ShortReal(C); |
223 | d = Standard_ShortReal(D); |
224 | } |
225 | |
226 | aDrawer->MapSegmentFromTo( a, b, c, d ); |
227 | } |
228 | } // end if IsIn |
229 | |
230 | } |
231 | |
232 | void Graphic2d_Ellips::DrawVertex( const Handle(Graphic2d_Drawer)& aDrawer, |
233 | const Standard_Integer anIndex) { |
234 | |
235 | Standard_Boolean IsIn = Standard_False; |
236 | |
237 | if ( ! myGOPtr->IsTransformed() ) |
238 | IsIn = aDrawer->IsIn( myMinX, myMaxX, myMinY, myMaxY ); |
239 | else { |
240 | Standard_ShortReal minx, miny, maxx, maxy; |
241 | MinMax( minx, maxx, miny, maxy ); |
242 | IsIn = aDrawer->IsIn( minx, maxx, miny, maxy ); |
243 | } |
244 | if ( IsIn ) { |
245 | if ( anIndex == 1 ) { |
246 | Standard_ShortReal X,Y; |
247 | DrawMarkerAttrib( aDrawer ); |
248 | if ( myGOPtr->IsTransformed() ) { |
249 | gp_GTrsf2d aTrsf = myGOPtr->Transform (); |
250 | Standard_Real A, B; |
251 | A = Standard_Real( myX ); |
252 | B = Standard_Real( myY ); |
253 | aTrsf.Transforms (A, B); |
254 | X = Standard_ShortReal( A ); |
255 | Y = Standard_ShortReal( B ); |
256 | } else { |
257 | X = Standard_ShortReal( myX ); |
258 | Y = Standard_ShortReal( myY ); |
259 | } |
260 | aDrawer->MapMarkerFromTo( VERTEXMARKER, X, Y, |
261 | DEFAULTMARKERSIZE,DEFAULTMARKERSIZE, 0.0 ); |
262 | } |
263 | } // end if IsIn is true |
264 | } |
265 | |
266 | #endif |
267 | |
268 | Standard_Boolean Graphic2d_Ellips::Pick (const Standard_ShortReal X, |
269 | const Standard_ShortReal Y, |
270 | const Standard_ShortReal aPrecision, |
271 | const Handle(Graphic2d_Drawer)& /*aDrawer*/) { |
272 | |
273 | Standard_ShortReal SRX = X, SRY = Y; |
274 | Standard_ShortReal maxRadius = |
275 | (myMinorRadius < myMajorRadius ? myMajorRadius : myMinorRadius); |
276 | |
277 | Standard_Boolean found = Standard_False; |
278 | if ( IsInMinMax (X, Y, aPrecision) ) { |
279 | if ( myGOPtr->IsTransformed() ) { |
280 | gp_GTrsf2d aTrsf = (myGOPtr->Transform ()).Inverted (); |
281 | Standard_Real RX = Standard_Real (SRX), RY = Standard_Real (SRY); |
282 | aTrsf.Transforms (RX, RY); |
283 | SRX = Standard_ShortReal (RX); SRY = Standard_ShortReal (RY); |
284 | } |
285 | #ifdef G002 |
286 | if ( Graphic2d_Primitive::IsOn( SRX, SRY, myX, myY, aPrecision) ) { |
287 | SetPickedIndex(-1); |
288 | found = Standard_True; |
289 | } else { |
290 | Standard_ShortReal tSin = Standard_ShortReal(Sin(myAngle)), |
291 | tCos = Standard_ShortReal(Cos(myAngle)); |
292 | Standard_ShortReal Xp = myX - myMinorRadius * tSin, |
293 | Yp = myY + myMinorRadius * tCos; |
294 | if ( IsOn( SRX, SRY, myX, myY, Xp, Yp, aPrecision) ) { |
295 | SetPickedIndex(1); |
296 | return Standard_True; |
297 | } else { |
298 | Xp = myX + myMajorRadius * tCos; |
299 | Yp = myY + myMajorRadius * tSin; |
300 | if ( IsOn( SRX, SRY, myX, myY, Xp, Yp, aPrecision) ) { |
301 | SetPickedIndex(2); |
302 | return Standard_True; |
303 | } else { |
304 | Xp = myX - myMajorRadius * tCos; |
305 | Yp = myY - myMajorRadius * tSin; |
306 | if ( IsOn( SRX, SRY, myX, myY, Xp, Yp, aPrecision) ) { |
307 | SetPickedIndex(3); |
308 | return Standard_True; |
309 | } else { |
310 | Xp = myX + myMinorRadius * tSin, |
311 | Yp = myY - myMinorRadius * tCos; |
312 | if ( IsOn( SRX, SRY, myX, myY, Xp, Yp, aPrecision) ) { |
313 | SetPickedIndex(4); |
314 | return Standard_True; |
315 | } |
316 | } |
317 | } |
318 | } |
81bba717 |
319 | Standard_ShortReal xf1,yf1,xf2,yf2; //Sources. |
7fd59977 |
320 | Standard_ShortReal q = |
321 | Standard_ShortReal(Sqrt( Abs( myMajorRadius*myMajorRadius - myMinorRadius*myMinorRadius) )); |
322 | |
323 | Standard_ShortReal cos = Standard_ShortReal(Cos(myAngle)); |
324 | Standard_ShortReal sin = Standard_ShortReal(Sin(myAngle)); |
325 | |
81bba717 |
326 | // Focus 1 and 2 calculated for the ellipse with centre |
327 | // at the origin of mark(0,0) |
7fd59977 |
328 | xf1 = q*cos; |
329 | yf1 = q*sin; |
330 | xf2 = -q*cos; |
331 | yf2 = -q*sin; |
332 | |
333 | Xp = SRX - myX; Yp = SRY - myY; |
334 | |
335 | Standard_ShortReal d1,d2; |
336 | d1 = Standard_ShortReal(Sqrt( (xf1 - Xp) * (xf1 - Xp) + (yf1 - Yp) * (yf1 - Yp))); |
337 | d2 = Standard_ShortReal(Sqrt( (xf2 - Xp) * (xf2 - Xp) + (yf2 - Yp) * (yf2 - Yp))); |
338 | if ( myTypeOfPolygonFilling != Graphic2d_TOPF_EMPTY ) |
339 | found = Abs (d1 + d2) < 2 * maxRadius; |
340 | if ( !found ) |
341 | found = Abs(d1 + d2 - 2 * maxRadius) < aPrecision; |
342 | if ( found ) |
343 | SetPickedIndex( 0 ); |
344 | } |
345 | #else |
81bba717 |
346 | Standard_ShortReal xf1,yf1,xf2,yf2; //Sourses. |
7fd59977 |
347 | Standard_ShortReal Xp, Yp; |
348 | Standard_ShortReal q = |
349 | Sqrt( Abs( myMajorRadius*myMajorRadius - myMinorRadius*myMinorRadius) ); |
350 | |
351 | Standard_ShortReal cos = Cos (myAngle); |
352 | Standard_ShortReal sin = Sin (myAngle); |
353 | |
81bba717 |
354 | // Focus 1 and 2 calculated for the ellipse with centre |
355 | // at the origin of mark(0,0) |
7fd59977 |
356 | xf1 = q*cos; |
357 | yf1 = q*sin; |
358 | xf2 = -q*cos; |
359 | yf2 = -q*sin; |
360 | |
361 | Xp = SRX - myX; Yp = SRY - myY; |
362 | |
363 | Standard_ShortReal d1,d2; |
364 | d1 = Sqrt ( (xf1 - Xp) * (xf1 - Xp) + (yf1 - Yp) * (yf1 - Yp)); |
365 | d2 = Sqrt ( (xf2 - Xp) * (xf2 - Xp) + (yf2 - Yp) * (yf2 - Yp)); |
366 | if ( myTypeOfPolygonFilling != Graphic2d_TOPF_EMPTY ) |
367 | found = Abs (d1 + d2) < 2 * maxRadius; |
368 | if ( !found ) |
369 | found = Abs(d1 + d2 - 2 * maxRadius) < aPrecision; |
370 | |
371 | #endif |
372 | |
373 | } // end if it's in MinMax |
374 | |
375 | return found; |
376 | } |
377 | |
378 | void Graphic2d_Ellips::Center(Quantity_Length& X,Quantity_Length& Y) const { |
379 | X = Quantity_Length( myX ); |
380 | Y = Quantity_Length( myY ); |
381 | } |
382 | |
383 | Quantity_Length Graphic2d_Ellips::MajorRadius() const { |
384 | return Quantity_Length( myMajorRadius ); |
385 | } |
386 | |
387 | Quantity_Length Graphic2d_Ellips::MinorRadius() const { |
388 | return Quantity_Length( myMinorRadius ); |
389 | } |
390 | |
391 | Quantity_PlaneAngle Graphic2d_Ellips::Angle() const { |
392 | return Quantity_PlaneAngle( myAngle ); |
393 | } |
394 | |
395 | void Graphic2d_Ellips::Save(Aspect_FStream& aFStream) const |
396 | { |
397 | *aFStream << "Graphic2d_Ellips" << endl; |
398 | *aFStream << myX << ' ' << myY << endl; |
399 | *aFStream << myMajorRadius << ' ' << myMinorRadius << endl; |
400 | *aFStream << myAngle << endl; |
401 | Graphic2d_Line::Save(aFStream); |
402 | } |
403 | |
404 | void Graphic2d_Ellips::Retrieve(Aspect_IFStream& anIFStream, |
405 | const Handle(Graphic2d_GraphicObject)& aGraphicObject) |
406 | { |
407 | Standard_ShortReal X, Y, radMaj, radMin, Ang; |
408 | |
409 | *anIFStream >> X >> Y; |
410 | *anIFStream >> radMaj >> radMin; |
411 | *anIFStream >> Ang; |
412 | Handle(Graphic2d_Ellips) |
413 | theEll = new Graphic2d_Ellips(aGraphicObject, X, Y, radMaj, radMin, Ang); |
414 | ((Handle (Graphic2d_Line))theEll)->Retrieve(anIFStream); |
415 | } |
416 | |