Integration of OCCT 6.5.0 from SVN
[occt.git] / src / Aspect / Aspect_CircularGrid.cxx
1 // Modified     23/02/98 : FMN ; Remplacement PI par Standard_PI
2
3 #define CSR577  //GG 25/09/00 Avoid to have unaccuracy coordinates computation
4 //              when the grid is activated.
5
6 #define OCC192_193 // jfa 27/02/2002
7 // for big rotation angles - error of negative values expression in round numbers
8
9 #define xTRACE
10
11 #include <Aspect_CircularGrid.ixx>
12 #include <Aspect_Grid.hxx>
13 #include <Standard_NumericError.hxx>
14 Aspect_CircularGrid::Aspect_CircularGrid
15      (const Quantity_Length aRadiusStep,
16       const Standard_Integer aDivisionNumber,
17       const Quantity_Length anXOrigin,
18       const Quantity_Length anYOrigin,
19       const Quantity_PlaneAngle aRotationAngle)
20 :Aspect_Grid(anXOrigin,anYOrigin,aRotationAngle),myRadiusStep(aRadiusStep),
21 myDivisionNumber(aDivisionNumber) {
22    }
23
24 void Aspect_CircularGrid::SetRadiusStep(const Standard_Real aRadiusStep) {
25   Standard_NegativeValue_Raise_if(aRadiusStep < 0., "invalid radius step");
26   Standard_NullValue_Raise_if(aRadiusStep == 0. , "invalid radius step");
27   myRadiusStep= aRadiusStep;
28   Init();
29   UpdateDisplay();
30 }
31 void Aspect_CircularGrid::SetDivisionNumber(const Standard_Integer aNumber) {
32   Standard_NegativeValue_Raise_if(aNumber < 0., "invalid division number");
33   Standard_NullValue_Raise_if(aNumber == 0. , "invalid division number");
34   myDivisionNumber = aNumber;
35   Init();
36   UpdateDisplay();
37 }
38 void Aspect_CircularGrid::SetGridValues
39      (const Quantity_Length theXOrigin,
40       const Quantity_Length theYOrigin,
41       const Quantity_Length theRadiusStep,
42       const Standard_Integer theDivisionNumber,
43       const Quantity_PlaneAngle theRotationAngle) {
44   myXOrigin = theXOrigin;
45   myYOrigin = theYOrigin;
46   Standard_NegativeValue_Raise_if(theRadiusStep < 0., "invalid radius step");
47   Standard_NullValue_Raise_if(theRadiusStep == 0. , "invalid radius step");
48   myRadiusStep= theRadiusStep;
49   Standard_NegativeValue_Raise_if(theDivisionNumber < 0., "invalid division number");
50   Standard_NullValue_Raise_if(theDivisionNumber == 0. , "invalid division number");
51   myDivisionNumber = theDivisionNumber;
52   myRotationAngle = theRotationAngle;
53   Init();
54   UpdateDisplay();
55 }
56 void Aspect_CircularGrid::Compute(const Quantity_Length X,
57                          const Quantity_Length Y,
58                          Quantity_Length& gridX,
59                          Quantity_Length& gridY) const {
60
61 #ifdef TRACE 
62   if( X == 0. || Y == 0. ) {
63       cout << " Aspect_CircularGrid" << endl;
64   }
65 #endif
66   Standard_Real xo = XOrigin();
67   Standard_Real yo = YOrigin();
68   Standard_Real d = Sqrt( (xo-X)*(xo-X) + (yo-Y)*(yo-Y) );
69   Standard_Integer n = (Standard_Integer ) ( d/myRadiusStep + 0.5 ) ;
70   Standard_Real radius = Standard_Real(n) * myRadiusStep;
71   Standard_Real cosinus = (X-xo)/d;
72   Standard_Real a = ACos(cosinus);
73   Standard_Real ra = RotationAngle();
74   if ( Y < yo ) a = 2*Standard_PI - a;
75 #ifdef OCC192_193
76   n = (Standard_Integer ) ((a-ra)/myAlpha + Sign(0.5, a-ra)) ;
77 #else
78   n = (Standard_Integer ) ((a-ra)/myAlpha +0.5 ) ;
79 #endif
80
81 #ifdef CSR577
82   Standard_Real cs=0,sn=0;
83   Standard_Boolean done = Standard_False;
84   Standard_Integer nmax = 2*myDivisionNumber;
85   Standard_Integer nquad,qmax;
86
87   if( ra == 0. ) {
88     nquad = 4; qmax = nmax/nquad;
89     if( (n == 0) || (!(nmax % nquad) && !(n % qmax)) ) {
90       Standard_Integer q = n/qmax;
91       switch (q) {
92         default:
93         case 0:
94           cs = 1.; sn = 0.;
95           break;
96         case 1:
97           cs = 0.; sn = 1.;
98           break;
99         case 2:
100           cs = -1.; sn = 0.;
101           break;
102         case 3:
103           cs = 0.; sn = -1.;
104           break;
105       }
106       done = Standard_True;
107     } else {
108       nquad = 2; qmax = nmax/nquad;
109       if( !(nmax % nquad) && !(n % qmax) ) {
110         Standard_Integer q = n/qmax;
111         switch (q) {
112           default:
113           case 0:
114             cs = 1.; sn = 0.;
115             break;
116           case 1:
117             cs = -1.; sn = 0.;
118             break;
119         }
120         done = Standard_True;
121       }
122     }
123   } 
124
125   if( !done ) {
126     Standard_Real ang = ra + Standard_Real(n)*myAlpha;
127     cs = Cos(ang); sn = Sin(ang);
128   }
129 #else
130   Standard_Real ang = RotationAngle()+ Standard_Real(n)*myAlpha;
131   Standard_Real cs = Cos(ang);
132   Standard_Real sn = Sin(ang);  
133 #endif
134   gridX = xo + cs * radius;
135   gridY = yo + sn * radius;
136 #ifdef TRACE
137     cout << "Aspect_CircularGrid::Compute (" << Quantity_Length (X) << ", "
138          << Quantity_Length (Y) << ", " << Quantity_Length (gridX) << ", "
139          << Quantity_Length (gridY) << ")" << endl;
140 #endif
141 }
142
143 Quantity_Length Aspect_CircularGrid::RadiusStep() const {
144   return myRadiusStep;
145 }
146
147 Standard_Integer Aspect_CircularGrid::DivisionNumber () const {
148 return myDivisionNumber;
149 }
150
151 void Aspect_CircularGrid::Init () {
152   myAlpha = Standard_PI /Standard_Real(myDivisionNumber);
153   myA1 = Cos(myAlpha); myB1=Sin(myAlpha);
154 }