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