b311480e |
1 | // Created on: 1993-08-24 |
2 | // Created by: Bruno DUMORTIER |
3 | // Copyright (c) 1993-1999 Matra Datavision |
973c2be1 |
4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
5 | // |
973c2be1 |
6 | // This file is part of Open CASCADE Technology software library. |
b311480e |
7 | // |
d5f74e42 |
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 |
973c2be1 |
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. |
b311480e |
13 | // |
973c2be1 |
14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. |
7fd59977 |
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.) { |
c6541a0c |
138 | V = M_PI/2.; // protection stupide |
7fd59977 |
139 | } // contre les erreurs de calcul |
140 | else if ( Z < -1.) { // il arrive que Z soit legerement |
c6541a0c |
141 | V = -M_PI/2; // superieur a 1. |
7fd59977 |
142 | } |
143 | else { |
144 | V = ASin(Z); |
145 | } |
146 | |
147 | if (C.Radius() < myTorus.MajorRadius()) { |
c6541a0c |
148 | V = M_PI - V; |
7fd59977 |
149 | } |
150 | else if ( V < 0.) { |
c6541a0c |
151 | V += 2*M_PI; |
7fd59977 |
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 |
c6541a0c |
158 | if ( Abs( P1.X() - P2.X()) > M_PI) V2d.Reverse(); |
7fd59977 |
159 | |
160 | gp_Dir2d D2( V2d); |
161 | if ( P1.X() < 0) |
c6541a0c |
162 | P1.SetX( 2*M_PI + P1.X()); |
7fd59977 |
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.) |
c6541a0c |
169 | U += 2*M_PI; |
7fd59977 |
170 | |
171 | // Origine de la droite |
172 | Standard_Real V1 = OC.AngleWithRef(Xc, OC^Zt); |
173 | if ( V1 < 0.) |
c6541a0c |
174 | V1 += 2*M_PI; |
7fd59977 |
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 | |