5ca0fee0e0d898b28de77a243a4857c2158aaef2
[occt.git] / src / ProjLib / ProjLib_Cone.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
18 #include <ElSLib.hxx>
19 #include <gp.hxx>
20 #include <gp_Circ.hxx>
21 #include <gp_Cone.hxx>
22 #include <gp_Elips.hxx>
23 #include <gp_Hypr.hxx>
24 #include <gp_Lin.hxx>
25 #include <gp_Parab.hxx>
26 #include <gp_Trsf.hxx>
27 #include <gp_Vec.hxx>
28 #include <gp_Vec2d.hxx>
29 #include <Precision.hxx>
30 #include <ProjLib_Cone.hxx>
31 #include <Standard_NoSuchObject.hxx>
32
33 //=======================================================================
34 //function : ProjLib_Cone
35 //purpose  : 
36 //=======================================================================
37 ProjLib_Cone::ProjLib_Cone()
38 {
39 }
40
41
42 //=======================================================================
43 //function : ProjLib_Cone
44 //purpose  : 
45 //=======================================================================
46
47 ProjLib_Cone::ProjLib_Cone(const gp_Cone& Co)
48 {
49   Init(Co);
50 }
51
52
53 //=======================================================================
54 //function : ProjLib_Cone
55 //purpose  : 
56 //=======================================================================
57
58 ProjLib_Cone::ProjLib_Cone(const gp_Cone& Co, const gp_Lin& L)
59 {
60   Init(Co);
61   Project(L);
62 }
63
64
65 //=======================================================================
66 //function : ProjLib_Cone
67 //purpose  : 
68 //=======================================================================
69
70 ProjLib_Cone::ProjLib_Cone(const gp_Cone& Co, const gp_Circ& C)
71 {
72   Init(Co);
73   Project(C);
74 }
75
76
77 //=======================================================================
78 //function : Init
79 //purpose  : 
80 //=======================================================================
81
82 void  ProjLib_Cone::Init(const gp_Cone& Co)
83 {
84   myType = GeomAbs_OtherCurve;
85   myCone = Co;
86   myIsPeriodic = Standard_False;
87   isDone = Standard_False;
88 }
89
90 //=======================================================================
91 //function : Project
92 //purpose  : 
93 //=======================================================================
94
95 void  ProjLib_Cone::Project(const gp_Lin& L)
96 {
97
98   Standard_Real U,V;
99   
100   // Compute V
101   V = gp_Vec(myCone.Location(),L.Location())
102     .Dot(gp_Vec(myCone.Position().Direction()));
103   V /= Cos( myCone.SemiAngle());
104
105   // Compute U
106   gp_Ax3 CPos  = myCone.Position();
107   gp_Dir ZCone = CPos.XDirection() ^ CPos.YDirection();
108   
109   gp_Ax3 RightHanded(CPos.Location(), ZCone, CPos.XDirection());
110   gp_Trsf T;
111   T.SetTransformation(RightHanded);
112
113   gp_Dir D = L.Position().Direction();
114   D.Transform(T);
115
116   if ( D.Z() < 0.) D.Reverse();
117   D.SetCoord(3, 0.);
118   U = gp::DX().AngleWithRef( D, gp::DZ());
119
120   Standard_Integer a1 = 
121     (ZCone.IsEqual(CPos.Direction(), Precision::Angular())) ? 1 : -1;
122   Standard_Integer a2 = 
123     (myCone.SemiAngle() > 0) ? 1 : -1;
124   if ( ( a1 * a2) == -1) U -= M_PI;
125
126   if ( U < 0.) U += 2.*M_PI;
127
128   gp_Pnt P;
129   gp_Vec Vu, Vv;
130
131   ElSLib::ConeD1(U, V, CPos, myCone.RefRadius(), myCone.SemiAngle(),
132                  P, Vu, Vv);
133
134   if(Vv.IsParallel(gp_Vec(L.Position().Direction()), Precision::Angular())) {
135
136     myType = GeomAbs_Line;
137
138     gp_Pnt2d P2d(U,V);
139   
140     Standard_Real Signe = L.Direction().Dot(myCone.Position().Direction());
141     Signe = (Signe > 0.) ? 1. : -1.;
142     gp_Dir2d D2d(0., Signe);
143   
144     myLin = gp_Lin2d( P2d, D2d);
145
146     isDone = Standard_True;
147   }
148     
149 }
150
151
152 //=======================================================================
153 //function : Project
154 //purpose  : 
155 //=======================================================================
156
157 void  ProjLib_Cone::Project(const gp_Circ& C)
158 {
159   myType = GeomAbs_Line;
160
161   gp_Ax3 ConePos = myCone.Position();
162   gp_Ax3 CircPos = C.Position();
163
164   gp_Dir ZCone = ConePos.XDirection().Crossed(ConePos.YDirection());
165   gp_Dir ZCir =  CircPos.XDirection().Crossed(CircPos.YDirection());
166
167   Standard_Real U, V;
168   Standard_Real x = ConePos.XDirection().Dot(CircPos.XDirection());
169   Standard_Real y = ConePos.YDirection().Dot(CircPos.XDirection());
170   Standard_Real z 
171     = gp_Vec(myCone.Location(),C.Location()).Dot(ConePos.Direction());
172   
173   // pour trouver le point U V, on reprend le code de ElSLib
174   // sans appliquer la Trsf au point ( aller retour inutile).
175   if ( x == 0.0 && y == 0.0 ) {
176     U = 0.;
177   }
178   else if ( -myCone.RefRadius() > z * Tan(myCone.SemiAngle())) {
179     U = ATan2(-y, -x);
180   }
181   else {
182     U = ATan2( y, x);
183   }
184   if ( U < 0.) U += 2*M_PI;
185
186   V = z / Cos(myCone.SemiAngle());
187
188   gp_Pnt2d P2d1 (U, V);
189   gp_Dir2d D2d;
190   if ( ZCone.Dot(ZCir) > 0.) 
191     D2d.SetCoord(1., 0.);
192   else
193     D2d.SetCoord(-1., 0.);
194
195   myLin = gp_Lin2d(P2d1, D2d);
196   isDone = Standard_True;
197 }
198
199 void  ProjLib_Cone::Project(const gp_Elips& E)
200 {
201   ProjLib_Projector::Project(E);
202 }
203
204 void  ProjLib_Cone::Project(const gp_Parab& P)
205 {
206  ProjLib_Projector::Project(P);
207 }
208
209 void  ProjLib_Cone::Project(const gp_Hypr& H)
210 {
211  ProjLib_Projector::Project(H);
212 }
213