b311480e |
1 | // Copyright (c) 1995-1999 Matra Datavision |
2 | // Copyright (c) 1999-2012 OPEN CASCADE SAS |
3 | // |
4 | // The content of this file is subject to the Open CASCADE Technology Public |
5 | // License Version 6.5 (the "License"). You may not use the content of this file |
6 | // except in compliance with the License. Please obtain a copy of the License |
7 | // at http://www.opencascade.org and read it completely before using this file. |
8 | // |
9 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its |
10 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. |
11 | // |
12 | // The Original Code and all software distributed under the License is |
13 | // distributed on an "AS IS" basis, without warranty of any kind, and the |
14 | // Initial Developer hereby disclaims all such warranties, including without |
15 | // limitation, any warranties of merchantability, fitness for a particular |
16 | // purpose or non-infringement. Please see the License for the specific terms |
17 | // and conditions governing the rights and limitations under the License. |
18 | |
7fd59977 |
19 | |
20 | #define PRO3730 |
21 | |
22 | #define WTO0006 //GG_221196 |
23 | // Ne pas transformer les cercles pleins en arc de cercles |
24 | // presque pleins a EPSILON pres car dans ce cas les |
25 | // JAP ne peuvent plus tracer leur drapeaux !!! |
26 | |
27 | #define BUC50076//GG_231097/090298 |
28 | // Attention aux transformations de type MIRROR |
29 | // car dans ce cas il faut inverser le parcours de l'arc et |
30 | // surtout ne pas annuler la translation dans la matrice! |
31 | |
32 | |
33 | #define G002 //Add new DrawElement(), DrawVertex() methods |
34 | |
35 | #define VERTEXMARKER 2 |
36 | #define DEFAULTMARKERSIZE 3.0 |
37 | #define MAXPOINTS 1023 |
38 | |
39 | #include <Graphic2d_Circle.ixx> |
40 | #include <Quantity_PlaneAngle.hxx> |
41 | #include <TShort_Array1OfShortReal.hxx> |
42 | #include <gp_Trsf2d.hxx> |
43 | |
44 | #include <Graphic2d_Primitive.pxx> |
45 | |
46 | Graphic2d_Circle::Graphic2d_Circle |
47 | (const Handle(Graphic2d_GraphicObject)& aGraphicObject, |
48 | const Quantity_Length X, const Quantity_Length Y, const Quantity_Length Radius) |
49 | : Graphic2d_Line(aGraphicObject) { |
50 | |
51 | myX = Standard_ShortReal(X); |
52 | myY = Standard_ShortReal(Y); |
53 | myRadius = Standard_ShortReal(Radius); |
54 | |
55 | if ( myRadius <= ShortRealEpsilon ()) |
56 | Graphic2d_CircleDefinitionError::Raise ("The radius = 0."); |
57 | |
58 | DoMinMax(); |
59 | myFirstAngle = 0.; |
c6541a0c |
60 | mySecondAngle = Standard_ShortReal(2. * M_PI); |
7fd59977 |
61 | myisArc = Standard_False; |
62 | myNumOfElem = MAXPOINTS + 1; |
63 | myNumOfVert = 3; |
64 | } |
65 | |
66 | Graphic2d_Circle::Graphic2d_Circle |
67 | (const Handle(Graphic2d_GraphicObject)& aGraphicObject, |
68 | const Quantity_Length X, const Quantity_Length Y, |
69 | const Quantity_Length Radius, const Quantity_PlaneAngle Alpha, |
70 | const Quantity_PlaneAngle Beta) |
71 | : Graphic2d_Line(aGraphicObject) { |
72 | |
73 | myX = Standard_ShortReal(X); |
74 | myY = Standard_ShortReal(Y); |
75 | myRadius = Standard_ShortReal(Radius); |
76 | myisArc = Standard_True; |
77 | if (myRadius <= ShortRealEpsilon ()) |
78 | Graphic2d_CircleDefinitionError::Raise ("The radius = 0."); |
79 | myNumOfElem = MAXPOINTS + 1; |
80 | myNumOfVert = 3; |
81 | #ifdef PRO3730 |
c6541a0c |
82 | Standard_ShortReal TwoPI = Standard_ShortReal(2. * M_PI); |
7fd59977 |
83 | myFirstAngle = Standard_ShortReal (Alpha); |
84 | mySecondAngle = Standard_ShortReal (Beta); |
85 | while( myFirstAngle < 0. ) myFirstAngle += TwoPI; |
c6541a0c |
86 | while( myFirstAngle > 2. * M_PI ) myFirstAngle -= TwoPI; |
7fd59977 |
87 | while( mySecondAngle < 0. ) mySecondAngle += TwoPI; |
c6541a0c |
88 | while( mySecondAngle > 2. * M_PI ) mySecondAngle -= TwoPI; |
7fd59977 |
89 | if( mySecondAngle < myFirstAngle ) mySecondAngle += TwoPI; |
90 | if ( (mySecondAngle - myFirstAngle < ShortRealEpsilon()) || |
91 | (mySecondAngle - myFirstAngle >= TwoPI) ) { |
92 | myFirstAngle = 0.; |
93 | mySecondAngle = TwoPI; |
94 | DoMinMax(); |
95 | } else { |
96 | Standard_ShortReal Acur,Xcur,Ycur,Xsav; |
97 | myMinX = myMaxX = Standard_ShortReal(Cos(myFirstAngle)); |
98 | myMinY = myMaxY = Standard_ShortReal(Sin(myFirstAngle)); |
99 | Xcur = Standard_ShortReal(Cos(mySecondAngle)); |
100 | Ycur = Standard_ShortReal(Sin(mySecondAngle)); |
101 | myMinX = myMinX < Xcur ? myMinX : Xcur; |
102 | myMaxX = myMaxX < Xcur ? Xcur : myMaxX; |
103 | myMinY = myMinY < Ycur ? myMinY : Ycur; |
104 | myMaxY = myMaxY < Ycur ? Ycur : myMaxY; |
105 | |
106 | for( Acur = 0.,Xcur = 1.,Ycur = 0.; |
c6541a0c |
107 | Acur < mySecondAngle; Acur += Standard_ShortReal(M_PI / 2.) ) { |
7fd59977 |
108 | if( Acur > myFirstAngle ) { |
109 | myMinX = ( myMinX < Xcur ? myMinX : Xcur ); |
110 | myMaxX = ( myMaxX < Xcur ? Xcur : myMaxX ); |
111 | myMinY = ( myMinY < Ycur ? myMinY : Ycur ); |
112 | myMaxY = ( myMaxY < Ycur ? Ycur : myMaxY ); |
113 | } |
114 | Xsav = Xcur ;Xcur = -Ycur; Ycur = Xsav; |
115 | } |
116 | myMinX = myX + myRadius * myMinX; |
117 | myMaxX = myX + myRadius * myMaxX; |
118 | myMinY = myY + myRadius * myMinY; |
119 | myMaxY = myY + myRadius * myMaxY; |
120 | } |
121 | #else |
122 | DoMinMax(); |
123 | #endif |
124 | } |
125 | |
126 | void Graphic2d_Circle :: Center ( Quantity_Length& X,Quantity_Length& Y ) const { |
127 | |
128 | X = Quantity_Length(myX); |
129 | Y = Quantity_Length(myY); |
130 | } |
131 | |
132 | Quantity_Length Graphic2d_Circle :: Radius ( ) const { |
133 | |
134 | return Quantity_Length(myRadius); |
135 | } |
136 | |
137 | Quantity_PlaneAngle Graphic2d_Circle :: FirstAngle ( ) const { |
138 | |
139 | return Quantity_PlaneAngle(myFirstAngle); |
140 | |
141 | } |
142 | |
143 | Quantity_PlaneAngle Graphic2d_Circle :: SecondAngle ( ) const { |
144 | |
145 | return Quantity_PlaneAngle(mySecondAngle); |
146 | |
147 | } |
148 | |
149 | void Graphic2d_Circle::SetCenter( const Quantity_Length X, |
150 | const Quantity_Length Y ) { |
151 | myX = Standard_ShortReal( X ); |
152 | myY = Standard_ShortReal( Y ); |
153 | DoMinMax(); |
154 | |
155 | } |
156 | |
157 | void Graphic2d_Circle::SetRadius( const Quantity_Length theR ) { |
158 | myRadius = Standard_ShortReal( theR ); |
159 | DoMinMax(); |
160 | } |
161 | |
162 | void Graphic2d_Circle::SetAngles( const Quantity_PlaneAngle Alpha, |
163 | const Quantity_PlaneAngle Beta ) { |
164 | |
165 | myFirstAngle = Standard_ShortReal( Alpha ); |
166 | mySecondAngle = Standard_ShortReal( Beta ); |
167 | } |
168 | |
169 | |
170 | void Graphic2d_Circle::Draw (const Handle(Graphic2d_Drawer)& aDrawer) { |
171 | |
172 | Standard_Boolean IsIn = Standard_False; |
173 | |
174 | if (! myGOPtr->IsTransformed ()) |
175 | IsIn = aDrawer->IsIn (myMinX,myMaxX,myMinY,myMaxY); |
176 | else { |
177 | Standard_ShortReal minx, miny, maxx, maxy; |
178 | MinMax(minx,maxx,miny,maxy); |
179 | IsIn = aDrawer->IsIn (minx,maxx,miny,maxy); |
180 | } |
181 | |
182 | if (IsIn) { |
183 | |
184 | DrawLineAttrib(aDrawer); |
185 | |
186 | Standard_ShortReal a, b, c, e, f; |
187 | |
188 | a = myX; b = myY; c = myRadius; |
189 | e = myFirstAngle; f = mySecondAngle; |
190 | if (myGOPtr->IsTransformed ()) { |
191 | gp_GTrsf2d aTrsf = myGOPtr->Transform (); |
192 | Standard_Real A, B; |
193 | Standard_Real X0, Y0, X1, Y1, X2, Y2, E, F; |
194 | A = Standard_Real (a); B = Standard_Real (b); |
195 | E = Standard_Real (e); F = Standard_Real (f); |
196 | aTrsf.Transforms (A, B); |
197 | a = Standard_ShortReal (A); b = Standard_ShortReal (B); |
c6541a0c |
198 | if( Abs(f-e) < Standard_ShortReal(2. * M_PI) ) { |
81bba717 |
199 | // To calculate new aperture angles |
200 | // the calculation is done on the trigonometric circle |
201 | // and in this case the translation is not taken into account |
202 | // except for transformations of type Mirror |
203 | // with negative determinant. |
7fd59977 |
204 | #ifndef BUC50076 |
205 | aTrsf.SetValue (1, 3, 0.0); |
206 | aTrsf.SetValue (2, 3, 0.0); |
207 | #endif |
208 | X1 = Cos (E); Y1 = Sin (E); |
209 | X2 = Cos (F); Y2 = Sin (F); |
210 | aTrsf.Transforms (X1, Y1); |
211 | aTrsf.Transforms (X2, Y2); |
212 | #ifdef BUC50076 |
213 | X0 = Y0 = 0.; |
214 | aTrsf.Transforms (X0, Y0); |
215 | X1 -= X0; Y1 -= Y0; |
216 | X2 -= X0; Y2 -= Y0; |
217 | #endif |
218 | c = myRadius * Standard_ShortReal(Sqrt(X1*X1 + Y1*Y1)); |
219 | e = Standard_ShortReal(atan2(Y1,X1)); |
220 | f = Standard_ShortReal(atan2(Y2,X2)); |
221 | #ifdef BUC50076 |
222 | if( aTrsf.IsNegative() ) { |
223 | Standard_ShortReal t = e; e = f; f = t; |
224 | } |
225 | #endif |
226 | } |
227 | } |
228 | |
229 | if (myTypeOfPolygonFilling == Graphic2d_TOPF_EMPTY) { |
230 | aDrawer->MapArcFromTo(a, b, c, e, f); |
231 | } else { |
232 | aDrawer->MapPolyArcFromTo(a, b, c, e, f); |
233 | } |
234 | |
235 | } |
236 | } |
237 | |
238 | #ifdef G002 |
239 | |
240 | void Graphic2d_Circle::DrawElement( const Handle(Graphic2d_Drawer)& aDrawer, |
241 | const Standard_Integer anIndex) { |
242 | |
243 | Standard_Boolean IsIn = Standard_False; |
244 | |
245 | if (! myGOPtr->IsTransformed ()) |
246 | IsIn = aDrawer->IsIn (myMinX,myMaxX,myMinY,myMaxY); |
247 | else { |
248 | Standard_ShortReal minx, miny, maxx, maxy; |
249 | MinMax(minx,maxx,miny,maxy); |
250 | IsIn = aDrawer->IsIn (minx,maxx,miny,maxy); |
251 | } |
252 | |
253 | if ( IsIn ) { |
254 | |
255 | DrawLineAttrib(aDrawer); |
256 | |
257 | if ( anIndex > 0 && anIndex <= MAXPOINTS + 1 ) { |
258 | |
259 | Standard_ShortReal teta = Abs( mySecondAngle - myFirstAngle ) / MAXPOINTS; |
260 | Standard_ShortReal Xp = Standard_ShortReal(myX + myRadius * Cos(myFirstAngle + teta*(anIndex-1))), |
261 | Yp = Standard_ShortReal(myY + myRadius * Sin(myFirstAngle + teta*(anIndex-1))); |
262 | Standard_Real A, B, C, D; |
263 | Standard_ShortReal a = myX, b = myY, c = Xp, d = Yp; |
264 | if ( myGOPtr->IsTransformed() ) { |
265 | gp_GTrsf2d aTrsf = myGOPtr->Transform (); |
266 | A = Standard_Real(a); |
267 | B = Standard_Real(b); |
268 | C = Standard_Real(c); |
269 | D = Standard_Real(d); |
270 | aTrsf.Transforms (A, B); |
271 | aTrsf.Transforms (C, D); |
272 | a = Standard_ShortReal(A); |
273 | b = Standard_ShortReal(B); |
274 | c = Standard_ShortReal(C); |
275 | d = Standard_ShortReal(D); |
276 | } |
277 | |
278 | aDrawer->MapSegmentFromTo( a, b, c, d ); |
279 | } |
280 | } |
281 | |
282 | } |
283 | |
284 | void Graphic2d_Circle::DrawVertex( const Handle(Graphic2d_Drawer)& aDrawer, |
285 | const Standard_Integer anIndex) { |
286 | |
287 | Standard_Boolean IsIn = Standard_False; |
288 | |
289 | if ( ! myGOPtr->IsTransformed() ) |
290 | IsIn = aDrawer->IsIn( myMinX, myMaxX, myMinY, myMaxY ); |
291 | else { |
292 | Standard_ShortReal minx, miny, maxx, maxy; |
293 | MinMax( minx, maxx, miny, maxy ); |
294 | IsIn = aDrawer->IsIn( minx, maxx, miny, maxy ); |
295 | } |
296 | |
297 | if ( IsIn ) { |
298 | if ( anIndex > 0 && anIndex < 4) { |
299 | DrawMarkerAttrib( aDrawer ); |
300 | Standard_ShortReal X=0.,Y=0.; |
301 | if ( anIndex == 1 ) { |
302 | X = myX; Y = myY; |
303 | } else if ( anIndex == 2 ) { |
304 | X = Standard_ShortReal( myX + myRadius *Cos( myFirstAngle ) ); |
305 | Y = Standard_ShortReal( myY + myRadius *Sin( myFirstAngle ) ); |
306 | } else if ( anIndex == 3 ) { |
307 | X = Standard_ShortReal( myX + myRadius *Cos( mySecondAngle ) ); |
308 | Y = Standard_ShortReal( myY + myRadius *Sin( mySecondAngle ) ); |
309 | } |
310 | if ( myGOPtr->IsTransformed() ) { |
311 | gp_GTrsf2d aTrsf = myGOPtr->Transform (); |
312 | Standard_Real A, B; |
313 | A = Standard_Real( X ); |
314 | B = Standard_Real( Y ); |
315 | aTrsf.Transforms (A, B); |
316 | X = Standard_ShortReal( A ); |
317 | Y = Standard_ShortReal( B ); |
318 | } |
319 | aDrawer->MapMarkerFromTo( VERTEXMARKER, X, Y, |
320 | DEFAULTMARKERSIZE,DEFAULTMARKERSIZE, 0.0 ); |
321 | } |
322 | } // end if IsIn is true |
323 | } |
324 | |
325 | #endif |
326 | |
327 | Standard_Boolean Graphic2d_Circle::Pick (const Standard_ShortReal X, |
328 | const Standard_ShortReal Y, |
329 | const Standard_ShortReal aPrecision, |
330 | const Handle(Graphic2d_Drawer)& /*aDrawer*/) { |
331 | |
332 | Standard_Boolean found = Standard_False; |
333 | Standard_ShortReal SRX = X, SRY = Y; |
334 | |
335 | if ( IsInMinMax( X, Y, aPrecision) ) { |
336 | if ( myGOPtr->IsTransformed() ) { |
337 | gp_GTrsf2d aTrsf = ( myGOPtr->Transform () ).Inverted (); |
338 | Standard_Real RX = Standard_Real (SRX), RY = Standard_Real (SRY); |
339 | aTrsf.Transforms( RX, RY ); |
340 | SRX = Standard_ShortReal( RX ); |
341 | SRY = Standard_ShortReal( RY ); |
342 | } |
343 | #ifdef G002 |
344 | if ( Graphic2d_Primitive::IsOn( SRX, SRY, myX, myY, aPrecision) ) { |
345 | SetPickedIndex(-1); |
346 | return Standard_True; |
347 | } else { |
348 | if ( myisArc ) { |
349 | Standard_ShortReal x1 = Standard_ShortReal(myRadius *Cos( myFirstAngle ) + myX), |
350 | y1 = Standard_ShortReal(myRadius *Sin( myFirstAngle ) + myY), |
351 | x2 = Standard_ShortReal(myRadius *Cos( mySecondAngle ) + myX), |
352 | y2 = Standard_ShortReal(myRadius *Sin( mySecondAngle ) + myY); |
353 | |
354 | if ( Graphic2d_Primitive::IsOn( SRX, SRY, x1, y1, aPrecision) ) { |
355 | SetPickedIndex(-2); |
356 | return Standard_True; |
357 | } else if ( Graphic2d_Primitive::IsOn( SRX, SRY, x2, y2, aPrecision) ) { |
358 | SetPickedIndex(-3); |
359 | return Standard_True; |
360 | } |
361 | } |
362 | |
363 | Standard_ShortReal alpha = Abs( mySecondAngle - myFirstAngle ); |
364 | TShort_Array1OfShortReal Xpoint(1,MAXPOINTS+1); |
365 | TShort_Array1OfShortReal Ypoint(1,MAXPOINTS+1); |
366 | |
367 | Standard_ShortReal teta = alpha / MAXPOINTS; |
368 | |
369 | for ( Standard_Integer i = 1; i<= MAXPOINTS+1; i++) { |
370 | Xpoint(i) = Standard_ShortReal(myX + myRadius * Cos(myFirstAngle + teta*(i-1))); |
371 | Ypoint(i) = Standard_ShortReal(myY + myRadius * Sin(myFirstAngle + teta*(i-1))); |
372 | if ( Graphic2d_Primitive::IsOn( SRX, SRY, Xpoint(i), Ypoint(i), aPrecision) ) { |
373 | SetPickedIndex(i); |
374 | return Standard_True; |
375 | } |
376 | } |
377 | if ( myTypeOfPolygonFilling != Graphic2d_TOPF_EMPTY ) |
378 | found = Abs( Sqrt((myX - SRX)*(myX - SRX) + (myY - SRY)*(myY - SRY))) |
379 | < myRadius; |
380 | if ( !found ) |
381 | found = Abs( Sqrt( (myX - SRX)*(myX - SRX) + (myY - SRY)*(myY - SRY)) |
382 | - myRadius ) < aPrecision; |
383 | if ( found ) |
384 | SetPickedIndex( 0 ); |
385 | } |
386 | #else |
387 | if ( myTypeOfPolygonFilling != Graphic2d_TOPF_EMPTY ) |
388 | found = Abs( Sqrt((myX - SRX)*(myX - SRX) + (myY - SRY)*(myY - SRY))) |
389 | < myRadius; |
390 | |
391 | if ( !found ) |
392 | found = Abs( Sqrt( (myX - SRX)*(myX - SRX) + (myY - SRY)*(myY - SRY)) |
393 | - myRadius ) < aPrecision; |
394 | #endif |
395 | } |
396 | |
397 | return found; |
398 | } |
399 | |
400 | void Graphic2d_Circle::DoMinMax() { |
401 | |
402 | myMinX = myX - myRadius; myMinY = myY - myRadius; |
403 | myMaxX = myX + myRadius; myMaxY = myY + myRadius; |
404 | |
405 | } |
406 | |
407 | void Graphic2d_Circle::Save(Aspect_FStream& aFStream) const |
408 | { |
409 | *aFStream << "Graphic2d_Circle" << endl; |
410 | *aFStream << myX << ' ' << myY << endl; |
411 | *aFStream << myRadius << endl; |
412 | *aFStream << myisArc << endl; |
413 | if (myisArc) |
414 | *aFStream << myFirstAngle << ' ' << mySecondAngle << endl; |
415 | Graphic2d_Line::Save(aFStream); |
416 | } |
417 | |
418 | void Graphic2d_Circle::Retrieve(Aspect_IFStream& anIFStream, |
419 | const Handle(Graphic2d_GraphicObject)& aGraphicObject) |
420 | { |
421 | Quantity_Length X, Y, Rad; |
422 | Quantity_PlaneAngle Ang1, Ang2; |
423 | int isArc; |
424 | Handle(Graphic2d_Circle) theCir; |
425 | |
426 | *anIFStream >> X >> Y; |
427 | *anIFStream >> Rad; |
428 | *anIFStream >> isArc; |
429 | if (isArc) |
430 | { |
431 | *anIFStream >> Ang1 >> Ang2; |
432 | theCir = new Graphic2d_Circle(aGraphicObject, X, Y, Rad, Ang1, Ang2); |
433 | } |
434 | else |
435 | theCir = new Graphic2d_Circle(aGraphicObject, X, Y, Rad); |
436 | ((Handle (Graphic2d_Line))theCir)->Retrieve(anIFStream); |
437 | } |
438 | |