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 
18 #include <gp.hxx>
19 #include <gp_Circ.hxx>
20 #include <gp_Dir2d.hxx>
21 #include <gp_Elips.hxx>
22 #include <gp_Hypr.hxx>
23 #include <gp_Lin.hxx>
24 #include <gp_Parab.hxx>
25 #include <gp_Torus.hxx>
26 #include <gp_Vec.hxx>
27 #include <gp_Vec2d.hxx>
28 #include <Precision.hxx>
29 #include <ProjLib_Torus.hxx>
30 #include <Standard_NoSuchObject.hxx>
31 
32 //=======================================================================
33 //function : ProjLib_Torus
34 //purpose  :
35 //=======================================================================
ProjLib_Torus()36 ProjLib_Torus::ProjLib_Torus()
37 {
38 }
39 
40 
41 //=======================================================================
42 //function : ProjLib_Torus
43 //purpose  :
44 //=======================================================================
45 
ProjLib_Torus(const gp_Torus & To)46 ProjLib_Torus::ProjLib_Torus(const gp_Torus& To)
47 {
48   Init(To);
49 }
50 
51 
52 //=======================================================================
53 //function : ProjLib_Torus
54 //purpose  :
55 //=======================================================================
56 
ProjLib_Torus(const gp_Torus & To,const gp_Circ & C)57 ProjLib_Torus::ProjLib_Torus(const gp_Torus& To, const gp_Circ& C)
58 {
59   Init(To);
60   Project(C);
61 }
62 
63 
64 //=======================================================================
65 //function : Init
66 //purpose  :
67 //=======================================================================
68 
Init(const gp_Torus & To)69 void  ProjLib_Torus::Init(const gp_Torus& To)
70 {
71   myType  = GeomAbs_OtherCurve;
72   myTorus = To;
73   myIsPeriodic = Standard_False;
74   isDone = Standard_False;
75 }
76 
77 
78 //=======================================================================
79 //function : EvalPnt2d / EvalDir2d
80 //purpose  : returns the Projected Pnt / Dir in the parametrization range
81 //           of myPlane.
82 //           P is a point on a torus with the same Position as To,
83 //           but with a major an minor radius equal to 1.
84 //           ( in order to avoid to divide by Radius)
85 //                / X = (1+cosV)*cosU        U = Atan(Y/X)
86 //            P = | Y = (1+cosV)*sinU   ==>
87 //                \ Z = sinV                 V = ASin( Z)
88 //=======================================================================
89 
EvalPnt2d(const gp_Vec & Ve,const gp_Torus & To)90 static gp_Pnt2d EvalPnt2d( const gp_Vec& Ve, const gp_Torus& To)
91 {
92   Standard_Real X = Ve.Dot(gp_Vec(To.Position().XDirection()));
93   Standard_Real Y = Ve.Dot(gp_Vec(To.Position().YDirection()));
94   Standard_Real U,V;
95 
96   if ( Abs(X) > Precision::PConfusion() ||
97        Abs(Y) > Precision::PConfusion() ) {
98     U = ATan2(Y,X);
99   }
100   else {
101     U = 0.;
102   }
103 
104   V = 0.;
105 
106   return gp_Pnt2d( U, V);
107 }
108 
109 
110 //=======================================================================
111 //function : Project
112 //purpose  :
113 //=======================================================================
114 
Project(const gp_Circ & C)115 void  ProjLib_Torus::Project(const gp_Circ& C)
116 {
117   myType = GeomAbs_Line;
118 
119   gp_Vec Xc( C.Position().XDirection());
120   gp_Vec Yc( C.Position().YDirection());
121   gp_Vec Xt( myTorus.Position().XDirection());
122   gp_Vec Yt( myTorus.Position().YDirection());
123   gp_Vec Zt( myTorus.Position().Direction());
124   gp_Vec OC( myTorus.Location(), C.Location());
125 
126 //  if (OC.Magnitude() < Precision::Confusion()      ||
127 //      OC.IsParallel(myTorus.Position().Direction(),
128 //		    Precision::Angular())) {
129 
130   if (OC.Magnitude() < Precision::Confusion()      ||
131       C.Position().Direction().IsParallel(myTorus.Position().Direction(),
132 					  Precision::Angular())) {
133     // Iso V
134     gp_Pnt2d P1 = EvalPnt2d( Xc, myTorus);  // evaluate U1
135     gp_Pnt2d P2 = EvalPnt2d( Yc, myTorus);  // evaluate U2
136     Standard_Real Z = OC.Dot(myTorus.Position().Direction());
137     Z /= myTorus.MinorRadius();
138 
139     Standard_Real V;
140 
141     if ( Z > 1.) {
142       V = M_PI/2.;          // protection stupide
143     }                     // contre les erreurs de calcul
144     else if ( Z < -1.) {  // il arrive que Z soit legerement
145       V = -M_PI/2;          // superieur a 1.
146     }
147     else {
148       V = ASin(Z);
149     }
150 
151     if (C.Radius() < myTorus.MajorRadius()) {
152       V = M_PI - V;
153     }
154     else if ( V < 0.) {
155       V += 2*M_PI;
156     }
157     P1.SetY(V);
158     P2.SetY(V);
159     gp_Vec2d V2d ( P1, P2);
160     // Normalement Abs( P1.X() - P2.X()) = PI/2
161     // Si != PI/2, on a traverse la periode => On reverse la Direction
162     if ( Abs( P1.X() - P2.X()) > M_PI) V2d.Reverse();
163 
164     gp_Dir2d D2( V2d);
165     if ( P1.X() < 0)
166       P1.SetX( 2*M_PI + P1.X());
167     myLin = gp_Lin2d( P1, D2);
168   }
169   else {
170     // Iso U  -> U = angle( Xt, OC)
171     Standard_Real U = Xt.AngleWithRef( OC, Xt^Yt);
172     if ( U < 0.)
173       U += 2*M_PI;
174 
175     // Origine de la droite
176     Standard_Real V1 = OC.AngleWithRef(Xc, OC^Zt);
177     if ( V1 < 0.)
178       V1 += 2*M_PI;
179 
180     gp_Pnt2d P1( U, V1);
181 
182     // Direction de la droite
183     gp_Dir2d D2 = gp::DY2d();
184     if ( ((OC^Zt)*(Xc^Yc)) < 0.) {
185       D2.Reverse();
186     }
187 
188     myLin = gp_Lin2d( P1, D2);
189   }
190   isDone = Standard_True;
191 }
192 
Project(const gp_Lin & L)193 void  ProjLib_Torus::Project(const gp_Lin& L)
194 {
195  ProjLib_Projector::Project(L);
196 }
197 
Project(const gp_Elips & E)198 void  ProjLib_Torus::Project(const gp_Elips& E)
199 {
200  ProjLib_Projector::Project(E);
201 }
202 
Project(const gp_Parab & P)203 void  ProjLib_Torus::Project(const gp_Parab& P)
204 {
205  ProjLib_Projector::Project(P);
206 }
207 
Project(const gp_Hypr & H)208 void  ProjLib_Torus::Project(const gp_Hypr& H)
209 {
210  ProjLib_Projector::Project(H);
211 }
212 
213