0024428: Implementation of LGPL license
[occt.git] / src / Aspect / Aspect_CircularGrid.cxx
1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and / or modify it
6 // under the terms of the GNU Lesser General Public version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14 // Modified     23/02/98 : FMN ; Remplacement PI par Standard_PI
15
16 #define CSR577  //GG 25/09/00 Avoid to have unaccuracy coordinates computation
17 //              when the grid is activated.
18
19 #define OCC192_193 // jfa 27/02/2002
20 // for big rotation angles - error of negative values expression in round numbers
21
22 #define xTRACE
23
24 #include <Aspect_CircularGrid.ixx>
25 #include <Aspect_Grid.hxx>
26 #include <Standard_NumericError.hxx>
27 Aspect_CircularGrid::Aspect_CircularGrid
28      (const Quantity_Length aRadiusStep,
29       const Standard_Integer aDivisionNumber,
30       const Quantity_Length anXOrigin,
31       const Quantity_Length anYOrigin,
32       const Quantity_PlaneAngle aRotationAngle)
33 :Aspect_Grid(anXOrigin,anYOrigin,aRotationAngle),myRadiusStep(aRadiusStep),
34 myDivisionNumber(aDivisionNumber) {
35    }
36
37 void Aspect_CircularGrid::SetRadiusStep(const Standard_Real aRadiusStep) {
38   Standard_NegativeValue_Raise_if(aRadiusStep < 0., "invalid radius step");
39   Standard_NullValue_Raise_if(aRadiusStep == 0. , "invalid radius step");
40   myRadiusStep= aRadiusStep;
41   Init();
42   UpdateDisplay();
43 }
44 void Aspect_CircularGrid::SetDivisionNumber(const Standard_Integer aNumber) {
45   Standard_NegativeValue_Raise_if(aNumber < 0., "invalid division number");
46   Standard_NullValue_Raise_if(aNumber == 0. , "invalid division number");
47   myDivisionNumber = aNumber;
48   Init();
49   UpdateDisplay();
50 }
51 void Aspect_CircularGrid::SetGridValues
52      (const Quantity_Length theXOrigin,
53       const Quantity_Length theYOrigin,
54       const Quantity_Length theRadiusStep,
55       const Standard_Integer theDivisionNumber,
56       const Quantity_PlaneAngle theRotationAngle) {
57   myXOrigin = theXOrigin;
58   myYOrigin = theYOrigin;
59   Standard_NegativeValue_Raise_if(theRadiusStep < 0., "invalid radius step");
60   Standard_NullValue_Raise_if(theRadiusStep == 0. , "invalid radius step");
61   myRadiusStep= theRadiusStep;
62   Standard_NegativeValue_Raise_if(theDivisionNumber < 0., "invalid division number");
63   Standard_NullValue_Raise_if(theDivisionNumber == 0. , "invalid division number");
64   myDivisionNumber = theDivisionNumber;
65   myRotationAngle = theRotationAngle;
66   Init();
67   UpdateDisplay();
68 }
69 void Aspect_CircularGrid::Compute(const Quantity_Length X,
70                          const Quantity_Length Y,
71                          Quantity_Length& gridX,
72                          Quantity_Length& gridY) const {
73
74 #ifdef TRACE 
75   if( X == 0. || Y == 0. ) {
76       cout << " Aspect_CircularGrid" << endl;
77   }
78 #endif
79   Standard_Real xo = XOrigin();
80   Standard_Real yo = YOrigin();
81   Standard_Real d = Sqrt( (xo-X)*(xo-X) + (yo-Y)*(yo-Y) );
82   Standard_Integer n = (Standard_Integer ) ( d/myRadiusStep + 0.5 ) ;
83   Standard_Real radius = Standard_Real(n) * myRadiusStep;
84   Standard_Real cosinus = (X-xo)/d;
85   Standard_Real a = ACos(cosinus);
86   Standard_Real ra = RotationAngle();
87   if ( Y < yo ) a = 2 * M_PI - a;
88 #ifdef OCC192_193
89   n = (Standard_Integer ) ((a-ra)/myAlpha + Sign(0.5, a-ra)) ;
90 #else
91   n = (Standard_Integer ) ((a-ra)/myAlpha +0.5 ) ;
92 #endif
93
94 #ifdef CSR577
95   Standard_Real cs=0,sn=0;
96   Standard_Boolean done = Standard_False;
97   Standard_Integer nmax = 2*myDivisionNumber;
98   Standard_Integer nquad,qmax;
99
100   if( ra == 0. ) {
101     nquad = 4; qmax = nmax/nquad;
102     if( (n == 0) || (!(nmax % nquad) && !(n % qmax)) ) {
103       Standard_Integer q = n/qmax;
104       switch (q) {
105         default:
106         case 0:
107           cs = 1.; sn = 0.;
108           break;
109         case 1:
110           cs = 0.; sn = 1.;
111           break;
112         case 2:
113           cs = -1.; sn = 0.;
114           break;
115         case 3:
116           cs = 0.; sn = -1.;
117           break;
118       }
119       done = Standard_True;
120     } else {
121       nquad = 2; qmax = nmax/nquad;
122       if( !(nmax % nquad) && !(n % qmax) ) {
123         Standard_Integer q = n/qmax;
124         switch (q) {
125           default:
126           case 0:
127             cs = 1.; sn = 0.;
128             break;
129           case 1:
130             cs = -1.; sn = 0.;
131             break;
132         }
133         done = Standard_True;
134       }
135     }
136   } 
137
138   if( !done ) {
139     Standard_Real ang = ra + Standard_Real(n)*myAlpha;
140     cs = Cos(ang); sn = Sin(ang);
141   }
142 #else
143   Standard_Real ang = RotationAngle()+ Standard_Real(n)*myAlpha;
144   Standard_Real cs = Cos(ang);
145   Standard_Real sn = Sin(ang);  
146 #endif
147   gridX = xo + cs * radius;
148   gridY = yo + sn * radius;
149 #ifdef TRACE
150     cout << "Aspect_CircularGrid::Compute (" << Quantity_Length (X) << ", "
151          << Quantity_Length (Y) << ", " << Quantity_Length (gridX) << ", "
152          << Quantity_Length (gridY) << ")" << endl;
153 #endif
154 }
155
156 Quantity_Length Aspect_CircularGrid::RadiusStep() const {
157   return myRadiusStep;
158 }
159
160 Standard_Integer Aspect_CircularGrid::DivisionNumber () const {
161 return myDivisionNumber;
162 }
163
164 void Aspect_CircularGrid::Init () {
165   myAlpha = M_PI / Standard_Real(myDivisionNumber);
166   myA1 = Cos(myAlpha); myB1=Sin(myAlpha);
167 }