0024710: Avoid including Handle_Class.hxx headers except where necessary
[occt.git] / src / ProjLib / ProjLib_Torus.cxx
1 // Created on: 1993-08-24
2 // Created by: Bruno DUMORTIER
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <ProjLib_Torus.ixx>
18
19 #include <Precision.hxx>
20 #include <gp.hxx>
21 #include <gp_Vec.hxx>
22 #include <gp_Vec2d.hxx>
23 #include <gp_Dir2d.hxx>
24
25 #include <Precision.hxx>
26
27 //=======================================================================
28 //function : ProjLib_Torus
29 //purpose  : 
30 //=======================================================================
31
32 ProjLib_Torus::ProjLib_Torus()
33 {
34 }
35
36
37 //=======================================================================
38 //function : ProjLib_Torus
39 //purpose  : 
40 //=======================================================================
41
42 ProjLib_Torus::ProjLib_Torus(const gp_Torus& To)
43 {
44   Init(To);
45 }
46
47
48 //=======================================================================
49 //function : ProjLib_Torus
50 //purpose  : 
51 //=======================================================================
52
53 ProjLib_Torus::ProjLib_Torus(const gp_Torus& To, const gp_Circ& C)
54 {
55   Init(To);
56   Project(C);
57 }
58
59
60 //=======================================================================
61 //function : Init
62 //purpose  : 
63 //=======================================================================
64
65 void  ProjLib_Torus::Init(const gp_Torus& To)
66 {
67   myType  = GeomAbs_OtherCurve;
68   myTorus = To;
69   myIsPeriodic = Standard_False;
70   isDone = Standard_False;
71 }
72
73
74 //=======================================================================
75 //function : EvalPnt2d / EvalDir2d
76 //purpose  : returns the Projected Pnt / Dir in the parametrization range
77 //           of myPlane.
78 //           P is a point on a torus with the same Position as To,
79 //           but with a major an minor radius equal to 1. 
80 //           ( in order to avoid to divide by Radius)
81 //                / X = (1+cosV)*cosU        U = Atan(Y/X)
82 //            P = | Y = (1+cosV)*sinU   ==>
83 //                \ Z = sinV                 V = ASin( Z)
84 //=======================================================================
85
86 static gp_Pnt2d EvalPnt2d( const gp_Vec& Ve, const gp_Torus& To)
87 {
88   Standard_Real X = Ve.Dot(gp_Vec(To.Position().XDirection()));
89   Standard_Real Y = Ve.Dot(gp_Vec(To.Position().YDirection()));
90   Standard_Real U,V;
91
92   if ( Abs(X) > Precision::PConfusion() ||
93        Abs(Y) > Precision::PConfusion() ) {
94     U = ATan2(Y,X);
95   }
96   else {
97     U = 0.;
98   }
99
100   V = 0.;
101
102   return gp_Pnt2d( U, V);
103 }
104
105
106 //=======================================================================
107 //function : Project
108 //purpose  : 
109 //=======================================================================
110
111 void  ProjLib_Torus::Project(const gp_Circ& C)
112 {
113   myType = GeomAbs_Line;
114
115   gp_Vec Xc( C.Position().XDirection());
116   gp_Vec Yc( C.Position().YDirection());
117   gp_Vec Xt( myTorus.Position().XDirection());
118   gp_Vec Yt( myTorus.Position().YDirection());
119   gp_Vec Zt( myTorus.Position().Direction());
120   gp_Vec OC( myTorus.Location(), C.Location());
121   
122 //  if (OC.Magnitude() < Precision::Confusion()      ||
123 //      OC.IsParallel(myTorus.Position().Direction(),
124 //                  Precision::Angular())) {
125
126   if (OC.Magnitude() < Precision::Confusion()      ||
127       C.Position().Direction().IsParallel(myTorus.Position().Direction(),
128                                           Precision::Angular())) {
129     // Iso V
130     gp_Pnt2d P1 = EvalPnt2d( Xc, myTorus);  // evaluate U1
131     gp_Pnt2d P2 = EvalPnt2d( Yc, myTorus);  // evaluate U2
132     Standard_Real Z = OC.Dot(myTorus.Position().Direction());
133     Z /= myTorus.MinorRadius();
134     
135     Standard_Real V;
136
137     if ( Z > 1.) {         
138       V = M_PI/2.;          // protection stupide 
139     }                     // contre les erreurs de calcul
140     else if ( Z < -1.) {  // il arrive que Z soit legerement 
141       V = -M_PI/2;          // superieur a 1.
142     }
143     else {
144       V = ASin(Z);
145     }
146
147     if (C.Radius() < myTorus.MajorRadius()) {
148       V = M_PI - V;
149     }
150     else if ( V < 0.) {
151       V += 2*M_PI;
152     }
153     P1.SetY(V);
154     P2.SetY(V);
155     gp_Vec2d V2d ( P1, P2);
156     // Normalement Abs( P1.X() - P2.X()) = PI/2
157     // Si != PI/2, on a traverse la periode => On reverse la Direction
158     if ( Abs( P1.X() - P2.X()) > M_PI) V2d.Reverse();
159     
160     gp_Dir2d D2( V2d);
161     if ( P1.X() < 0) 
162       P1.SetX( 2*M_PI + P1.X());
163     myLin = gp_Lin2d( P1, D2);
164   }
165   else {
166     // Iso U  -> U = angle( Xt, OC)
167     Standard_Real U = Xt.AngleWithRef( OC, Xt^Yt);
168     if ( U < 0.) 
169       U += 2*M_PI;
170     
171     // Origine de la droite
172     Standard_Real V1 = OC.AngleWithRef(Xc, OC^Zt);
173     if ( V1 < 0.)
174       V1 += 2*M_PI;
175
176     gp_Pnt2d P1( U, V1);
177     
178     // Direction de la droite
179     gp_Dir2d D2 = gp::DY2d();
180     if ( ((OC^Zt)*(Xc^Yc)) < 0.) {
181       D2.Reverse();
182     }
183     
184     myLin = gp_Lin2d( P1, D2);
185   }
186   isDone = Standard_True;
187 }
188
189 void  ProjLib_Torus::Project(const gp_Lin& L)
190 {
191  ProjLib_Projector::Project(L);
192 }
193
194 void  ProjLib_Torus::Project(const gp_Elips& E)
195 {
196  ProjLib_Projector::Project(E);
197 }
198
199 void  ProjLib_Torus::Project(const gp_Parab& P)
200 {
201  ProjLib_Projector::Project(P);
202 }
203
204 void  ProjLib_Torus::Project(const gp_Hypr& H)
205 {
206  ProjLib_Projector::Project(H);
207 }
208