0023510: Integration of test grid "vis" into the new testing system
[occt.git] / src / Graphic2d / Graphic2d_Circle.cxx
CommitLineData
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
46Graphic2d_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
66Graphic2d_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
126void Graphic2d_Circle :: Center ( Quantity_Length& X,Quantity_Length& Y ) const {
127
128 X = Quantity_Length(myX);
129 Y = Quantity_Length(myY);
130}
131
132Quantity_Length Graphic2d_Circle :: Radius ( ) const {
133
134 return Quantity_Length(myRadius);
135}
136
137Quantity_PlaneAngle Graphic2d_Circle :: FirstAngle ( ) const {
138
139 return Quantity_PlaneAngle(myFirstAngle);
140
141}
142
143Quantity_PlaneAngle Graphic2d_Circle :: SecondAngle ( ) const {
144
145 return Quantity_PlaneAngle(mySecondAngle);
146
147}
148
149void 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
157void Graphic2d_Circle::SetRadius( const Quantity_Length theR ) {
158 myRadius = Standard_ShortReal( theR );
159 DoMinMax();
160}
161
162void 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
170void 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
240void 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
284void 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
327Standard_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
400void Graphic2d_Circle::DoMinMax() {
401
402 myMinX = myX - myRadius; myMinY = myY - myRadius;
403 myMaxX = myX + myRadius; myMaxY = myY + myRadius;
404
405}
406
407void 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
418void 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