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