1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2012 OPEN CASCADE SAS
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.
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.
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.
19 // Modified 23/02/98 : FMN ; Remplacement PI par Standard_PI
21 #define G002 //TCL: Add new DrawElement(), DrawVertex() methods
23 #define VERTEXMARKER 2
24 #define DEFAULTMARKERSIZE 3.0
25 #define MAXPOINTS 1023
28 #include <Graphic2d_EllipsMarker.ixx>
29 #include <TShort_Array1OfShortReal.hxx>
31 #define MAXPOINTS 1023
33 Graphic2d_EllipsMarker::Graphic2d_EllipsMarker (
34 const Handle(Graphic2d_GraphicObject)& aGraphicObject,
35 const Quantity_Length aXPosition,
36 const Quantity_Length aYPosition,
37 const Standard_Real X,
38 const Standard_Real Y,
39 const Standard_Real MajorRadius,
40 const Standard_Real MinorRadius,
41 const Quantity_PlaneAngle anAngle)
43 :Graphic2d_VectorialMarker (aGraphicObject, aXPosition, aYPosition),
44 myX (Standard_ShortReal (X)),
45 myY (Standard_ShortReal (Y)),
46 myMajorRadius (Standard_ShortReal (MajorRadius)),
47 myMinorRadius (Standard_ShortReal (MinorRadius)),
48 myAngle (Standard_ShortReal(anAngle)) {
50 if (myMajorRadius <= RealEpsilon ())
51 Graphic2d_EllipsDefinitionError::Raise ("The major radius = 0.");
53 if (myMinorRadius <= RealEpsilon ())
54 Graphic2d_EllipsDefinitionError::Raise ("The minor radius = 0.");
57 myMinX = myX + Standard_ShortReal (aXPosition) - myMajorRadius;
58 myMinY = myY + Standard_ShortReal (aYPosition) - myMinorRadius;
59 myMaxX = myX + Standard_ShortReal (aXPosition) + myMajorRadius;
60 myMaxY = myY + Standard_ShortReal (aYPosition) + myMinorRadius;
66 #endif /* NOT IMPLEMENTED */
72 void Graphic2d_EllipsMarker::Draw (const Handle(Graphic2d_Drawer)& aDrawer) {
74 DrawLineAttrib(aDrawer);
76 Standard_ShortReal xp,yp;
77 aDrawer->GetMapFromTo(Standard_ShortReal (XPosition ()),
78 Standard_ShortReal (YPosition ()),xp,yp);
82 Standard_ShortReal Def;
83 Standard_ShortReal Coeff;
84 Aspect_TypeOfDeflection Type;
85 aDrawer->DrawPrecision(Def,Coeff,Type);
86 if (Type == Aspect_TOD_RELATIVE) Def = myMajorRadius * Coeff;
89 if(myMajorRadius > Def)
90 val = Max( 0.0044 , Min (0.7854 , 2. * ACos(1.-Def/myMajorRadius)));
92 val = 0.7854; // = PI/4.
93 Standard_Integer nbpoints = Min(MAXPOINTS,Standard_Integer(2 * M_PI / val)+2);
95 // Standard_Integer nbpoints = Max ( 8 ,Standard_Integer ( myMajorRadius / Def));
96 Standard_ShortReal teta = Standard_ShortReal(2 * M_PI / nbpoints);
97 Standard_ShortReal x1 = Standard_ShortReal( myMajorRadius *Cos (myAngle)),
98 y1 = Standard_ShortReal( myMajorRadius *Sin (myAngle));
99 Standard_ShortReal x2,y2;
100 Standard_ShortReal cosin = Standard_ShortReal( Cos(teta) );
102 x2 = Standard_ShortReal( myMajorRadius * Cos(teta) * Cos(myAngle) -
103 myMinorRadius * Sin(teta) * Sin(myAngle));
104 y2 = Standard_ShortReal( myMajorRadius * Cos(teta) * Sin(myAngle) +
105 myMinorRadius * Sin(teta) * Cos(myAngle));
107 TShort_Array1OfShortReal X(1,nbpoints+1);
108 TShort_Array1OfShortReal Y(1,nbpoints+1);
109 X(1) = x1; Y(1) = y1; X(2) = x2; Y(2) = y2;
110 for (Standard_Integer i=3; i<= nbpoints+1; i++) {
111 X(i) = 2*x2*cosin - x1;
112 Y(i) = 2*y2*cosin - y1;
113 x1 = x2; y1 = y2; x2 = X(i); y2 = Y(i);
116 if (myTypeOfPolygonFilling == Graphic2d_TOPF_EMPTY) {
117 aDrawer->DrawPolyline(xp,yp,X,Y);
120 aDrawer->DrawPolygon(xp,yp,X,Y);
127 void Graphic2d_EllipsMarker::DrawElement( const Handle(Graphic2d_Drawer)& aDrawer,
128 const Standard_Integer anIndex) {
130 if ( anIndex > 0 && anIndex < 5) {
131 DrawLineAttrib(aDrawer);
133 Standard_ShortReal xp=0.,yp=0., xpp=0., ypp=0.;
134 aDrawer->GetMapFromTo( Standard_ShortReal(XPosition() ),
135 Standard_ShortReal(YPosition() ), xp, yp );
139 Standard_ShortReal tSin = Standard_ShortReal( Sin(myAngle) ),
140 tCos = Standard_ShortReal( Cos(myAngle) );
141 if ( anIndex == 1 ) {
142 xpp = Standard_ShortReal( xp - myMinorRadius * tSin );
143 ypp = Standard_ShortReal( yp + myMinorRadius * tCos );
144 } else if ( anIndex == 2 ) {
145 xpp = Standard_ShortReal( xp + myMajorRadius * tCos );
146 ypp = Standard_ShortReal( yp + myMajorRadius * tSin );
147 } else if ( anIndex == 3 ) {
148 xpp = Standard_ShortReal( xp - myMajorRadius * tCos );
149 ypp = Standard_ShortReal( yp - myMajorRadius * tSin );
150 } else if ( anIndex == 4 ) {
151 xpp = Standard_ShortReal( xp + myMinorRadius * tSin );
152 ypp = Standard_ShortReal( yp - myMinorRadius * tCos );
155 aDrawer->DrawSegment( xp, yp, xpp, ypp );
160 void Graphic2d_EllipsMarker::DrawVertex( const Handle(Graphic2d_Drawer)& aDrawer,
161 const Standard_Integer anIndex) {
162 if ( anIndex == 1 ) {
163 DrawMarkerAttrib( aDrawer );
164 Standard_ShortReal x = aDrawer->ConvertMapToFrom(myX) + myXPosition;
165 Standard_ShortReal y = aDrawer->ConvertMapToFrom(myY) + myYPosition;
166 aDrawer->MapMarkerFromTo( VERTEXMARKER, x, y, DEFAULTMARKERSIZE,DEFAULTMARKERSIZE, 0.0 );
172 Standard_Boolean Graphic2d_EllipsMarker::Pick (const Standard_ShortReal X,
173 const Standard_ShortReal Y,
174 const Standard_ShortReal aPrecision,
175 const Handle(Graphic2d_Drawer)& aDrawer)
177 Standard_ShortReal xf1,yf1,xf2,yf2; //Les foyers.
178 Standard_ShortReal Xp, Yp;
179 Standard_ShortReal SRX = X, SRY = Y;
181 Standard_ShortReal Majord = aDrawer->ConvertMapToFrom(myMajorRadius);
182 Standard_ShortReal Minord = aDrawer->ConvertMapToFrom(myMinorRadius);
183 Standard_ShortReal x = aDrawer->ConvertMapToFrom(myX) + myXPosition;
184 Standard_ShortReal y = aDrawer->ConvertMapToFrom(myY) + myYPosition;
185 Standard_ShortReal maxord = (Minord < Majord ? Majord : Minord);
186 Standard_Boolean found = Standard_False;
188 Standard_ShortReal q = Standard_ShortReal(
189 Sqrt(Abs (Majord * Majord - Minord * Minord)));
191 Standard_ShortReal cos = Standard_ShortReal( Cos(myAngle) );
192 Standard_ShortReal sin = Standard_ShortReal( Sin(myAngle) );
194 //Focus 1 and 2 calcules pour l' ellipse dont le centre
195 // est ramene a l' origine du repere(0,0)
196 xf1 = Standard_ShortReal( q * cos );
197 yf1 = Standard_ShortReal( q * sin );
198 xf2 = Standard_ShortReal( - q * cos );
199 yf2 = Standard_ShortReal( - q * sin );
201 if (myGOPtr->IsTransformed ()) {
202 gp_GTrsf2d aTrsf = (myGOPtr->Transform ()).Inverted ();
203 Standard_Real RX = Standard_Real (SRX), RY = Standard_Real (SRY);
204 aTrsf.Transforms (RX, RY);
205 SRX = Standard_ShortReal (RX); SRY = Standard_ShortReal (RY);
209 if ( Graphic2d_Primitive::IsOn( SRX, SRY, x, y, aPrecision) ) {
211 return Standard_True;
213 Standard_ShortReal tSin = Standard_ShortReal( Sin(myAngle) ),
214 tCos = Standard_ShortReal( Cos(myAngle) );
215 Standard_ShortReal xpp = Standard_ShortReal( x - Minord * tSin ),
216 ypp = Standard_ShortReal( y + Minord * tCos );
217 if ( IsOn( SRX, SRY, x, y, xpp, ypp, aPrecision) ) {
219 return Standard_True;
221 xpp = x + Majord * tCos;
222 ypp = y + Majord * tSin;
223 if ( IsOn( SRX, SRY, x, y, xpp, ypp, aPrecision) ) {
225 return Standard_True;
227 xpp = x - Majord * tCos;
228 ypp = y - Majord * tSin;
229 if ( IsOn( SRX, SRY, x, y, xpp, ypp, aPrecision) ) {
231 return Standard_True;
233 xpp = x + Minord * tSin,
234 ypp = y - Minord * tCos;
235 if ( IsOn( SRX, SRY, x, y, xpp, ypp, aPrecision) ) {
237 return Standard_True;
245 Xp = SRX - x; Yp = SRY - y;
247 Standard_ShortReal d1,d2;
248 d1 = Standard_ShortReal(
249 Sqrt( (xf1 - Xp) * (xf1 - Xp) + (yf1 - Yp) * (yf1 - Yp)));
250 d2 = Standard_ShortReal(
251 Sqrt( (xf2 - Xp) * (xf2 - Xp) + (yf2 - Yp) * (yf2 - Yp)));
253 if (myTypeOfPolygonFilling != Graphic2d_TOPF_EMPTY)
254 found = Abs (d1 + d2) < 2 * maxord;
256 found = Abs (d1 + d2 - 2 * maxord) < aPrecision;
262 void Graphic2d_EllipsMarker::Center(Quantity_Length& X,Quantity_Length& Y) const {
264 X = Quantity_Length( myX );
265 Y = Quantity_Length( myY );
268 Quantity_Length Graphic2d_EllipsMarker::MajorRadius() const {
270 return Quantity_Length( myMajorRadius );
273 Quantity_Length Graphic2d_EllipsMarker::MinorRadius() const {
275 return Quantity_Length( myMinorRadius );
278 Quantity_PlaneAngle Graphic2d_EllipsMarker::Angle() const {
280 return Quantity_PlaneAngle( myAngle );
283 void Graphic2d_EllipsMarker::Save(Aspect_FStream& aFStream) const
285 *aFStream << "Graphic2d_EllipsMarker" << endl;
286 *aFStream << myXPosition << ' ' << myYPosition << endl;
287 *aFStream << myX << ' ' << myY << endl;
288 *aFStream << myMajorRadius << ' ' << myMinorRadius << endl;
289 *aFStream << myAngle << endl;
290 Graphic2d_Line::Save(aFStream);
293 void Graphic2d_EllipsMarker::Retrieve(Aspect_IFStream& anIFStream,
294 const Handle(Graphic2d_GraphicObject)& aGraphicObject)
296 Standard_ShortReal XPos, YPos, X, Y, radMaj, radMin, Ang;
298 *anIFStream >> XPos >> YPos;
299 *anIFStream >> X >> Y;
300 *anIFStream >> radMaj >> radMin;
302 Handle(Graphic2d_EllipsMarker)
303 theEllM = new Graphic2d_EllipsMarker(aGraphicObject, XPos, YPos, X, Y,
304 radMaj, radMin, Ang);
305 ((Handle (Graphic2d_Line))theEllM)->Retrieve(anIFStream);