8bddca6fb9736098018fcb4a223e2f1ebfa4aa86
[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 under
6 // the terms of the GNU Lesser General Public License 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 #include <Aspect_CircularGrid.hxx>
17 #include <Aspect_Grid.hxx>
18 #include <Standard_NegativeValue.hxx>
19 #include <Standard_NullValue.hxx>
20 #include <Standard_NumericError.hxx>
21 #include <Standard_Type.hxx>
22
23 IMPLEMENT_STANDARD_RTTIEXT(Aspect_CircularGrid,Aspect_Grid)
24
25 Aspect_CircularGrid::Aspect_CircularGrid
26      (const Standard_Real aRadiusStep,
27       const Standard_Integer aDivisionNumber,
28       const Standard_Real anXOrigin,
29       const Standard_Real anYOrigin,
30       const Standard_Real aRotationAngle)
31 :Aspect_Grid(anXOrigin,anYOrigin,aRotationAngle),myRadiusStep(aRadiusStep),
32 myDivisionNumber(aDivisionNumber) {
33    }
34
35 void Aspect_CircularGrid::SetRadiusStep(const Standard_Real aRadiusStep) {
36   Standard_NegativeValue_Raise_if(aRadiusStep < 0., "invalid radius step");
37   Standard_NullValue_Raise_if(aRadiusStep == 0. , "invalid radius step");
38   myRadiusStep= aRadiusStep;
39   Init();
40   UpdateDisplay();
41 }
42 void Aspect_CircularGrid::SetDivisionNumber(const Standard_Integer aNumber) {
43   Standard_NegativeValue_Raise_if(aNumber < 0., "invalid division number");
44   Standard_NullValue_Raise_if(aNumber == 0. , "invalid division number");
45   myDivisionNumber = aNumber;
46   Init();
47   UpdateDisplay();
48 }
49 void Aspect_CircularGrid::SetGridValues
50      (const Standard_Real theXOrigin,
51       const Standard_Real theYOrigin,
52       const Standard_Real theRadiusStep,
53       const Standard_Integer theDivisionNumber,
54       const Standard_Real theRotationAngle) {
55   myXOrigin = theXOrigin;
56   myYOrigin = theYOrigin;
57   Standard_NegativeValue_Raise_if(theRadiusStep < 0., "invalid radius step");
58   Standard_NullValue_Raise_if(theRadiusStep == 0. , "invalid radius step");
59   myRadiusStep= theRadiusStep;
60   Standard_NegativeValue_Raise_if(theDivisionNumber < 0., "invalid division number");
61   Standard_NullValue_Raise_if(theDivisionNumber == 0. , "invalid division number");
62   myDivisionNumber = theDivisionNumber;
63   myRotationAngle = theRotationAngle;
64   Init();
65   UpdateDisplay();
66 }
67 void Aspect_CircularGrid::Compute(const Standard_Real X,
68                                   const Standard_Real Y,
69                                   Standard_Real& gridX,
70                                   Standard_Real& gridY) const {
71
72   Standard_Real xo = XOrigin();
73   Standard_Real yo = YOrigin();
74   Standard_Real d = Sqrt( (xo-X)*(xo-X) + (yo-Y)*(yo-Y) );
75   Standard_Integer n = (Standard_Integer ) ( d/myRadiusStep + 0.5 ) ;
76   Standard_Real radius = Standard_Real(n) * myRadiusStep;
77   Standard_Real cosinus = (X-xo)/d;
78   Standard_Real a = ACos(cosinus);
79   Standard_Real ra = RotationAngle();
80   if ( Y < yo ) a = 2 * M_PI - a;
81   n = (Standard_Integer ) ((a-ra)/myAlpha + Sign(0.5, a-ra)) ;
82
83   Standard_Real cs=0,sn=0;
84   Standard_Boolean done = Standard_False;
85   Standard_Integer nmax = 2*myDivisionNumber;
86   Standard_Integer nquad,qmax;
87
88   if( ra == 0. ) {
89     nquad = 4; qmax = nmax/nquad;
90     if( (n == 0) || (!(nmax % nquad) && !(n % qmax)) ) {
91       Standard_Integer q = n/qmax;
92       switch (q) {
93         default:
94         case 0:
95           cs = 1.; sn = 0.;
96           break;
97         case 1:
98           cs = 0.; sn = 1.;
99           break;
100         case 2:
101           cs = -1.; sn = 0.;
102           break;
103         case 3:
104           cs = 0.; sn = -1.;
105           break;
106       }
107       done = Standard_True;
108     } else {
109       nquad = 2; qmax = nmax/nquad;
110       if( !(nmax % nquad) && !(n % qmax) ) {
111         Standard_Integer q = n/qmax;
112         switch (q) {
113           default:
114           case 0:
115             cs = 1.; sn = 0.;
116             break;
117           case 1:
118             cs = -1.; sn = 0.;
119             break;
120         }
121         done = Standard_True;
122       }
123     }
124   } 
125
126   if( !done ) {
127     Standard_Real ang = ra + Standard_Real(n)*myAlpha;
128     cs = Cos(ang); sn = Sin(ang);
129   }
130   gridX = xo + cs * radius;
131   gridY = yo + sn * radius;
132 }
133
134 Standard_Real Aspect_CircularGrid::RadiusStep() const {
135   return myRadiusStep;
136 }
137
138 Standard_Integer Aspect_CircularGrid::DivisionNumber () const {
139 return myDivisionNumber;
140 }
141
142 void Aspect_CircularGrid::Init () {
143   myAlpha = M_PI / Standard_Real(myDivisionNumber);
144   myA1 = Cos(myAlpha); myB1=Sin(myAlpha);
145 }