0023839: Projection algorithm produces wrong results for set of data
[occt.git] / src / ProjLib / ProjLib_Cone.cxx
CommitLineData
b311480e 1// Created on: 1993-08-24
2// Created by: Bruno DUMORTIER
3// Copyright (c) 1993-1999 Matra Datavision
4// Copyright (c) 1999-2012 OPEN CASCADE SAS
5//
6// The content of this file is subject to the Open CASCADE Technology Public
7// License Version 6.5 (the "License"). You may not use the content of this file
8// except in compliance with the License. Please obtain a copy of the License
9// at http://www.opencascade.org and read it completely before using this file.
10//
11// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13//
14// The Original Code and all software distributed under the License is
15// distributed on an "AS IS" basis, without warranty of any kind, and the
16// Initial Developer hereby disclaims all such warranties, including without
17// limitation, any warranties of merchantability, fitness for a particular
18// purpose or non-infringement. Please see the License for the specific terms
19// and conditions governing the rights and limitations under the License.
20
7fd59977 21
22
23
24#include <ProjLib_Cone.ixx>
25
26#include <Precision.hxx>
27#include <gp.hxx>
28#include <gp_Vec.hxx>
29#include <gp_Trsf.hxx>
30#include <gp_Vec2d.hxx>
31#include <ElSLib.hxx>
32
33//=======================================================================
34//function : ProjLib_Cone
35//purpose :
36//=======================================================================
37
38ProjLib_Cone::ProjLib_Cone()
39{
40}
41
42
43//=======================================================================
44//function : ProjLib_Cone
45//purpose :
46//=======================================================================
47
48ProjLib_Cone::ProjLib_Cone(const gp_Cone& Co)
49{
50 Init(Co);
51}
52
53
54//=======================================================================
55//function : ProjLib_Cone
56//purpose :
57//=======================================================================
58
59ProjLib_Cone::ProjLib_Cone(const gp_Cone& Co, const gp_Lin& L)
60{
61 Init(Co);
62 Project(L);
63}
64
65
66//=======================================================================
67//function : ProjLib_Cone
68//purpose :
69//=======================================================================
70
71ProjLib_Cone::ProjLib_Cone(const gp_Cone& Co, const gp_Circ& C)
72{
73 Init(Co);
74 Project(C);
75}
76
77
78//=======================================================================
79//function : Init
80//purpose :
81//=======================================================================
82
83void ProjLib_Cone::Init(const gp_Cone& Co)
84{
85 myType = GeomAbs_OtherCurve;
86 myCone = Co;
87 myIsPeriodic = Standard_False;
88 isDone = Standard_False;
89}
90
91
92//=======================================================================
93//function : EvalPnt2d / EvalDir2d
94//purpose : returns the Projected Pnt / Dir in the parametrization range
95// of myPlane.
96//=======================================================================
97
98#ifdef DEB
99static gp_Pnt2d EvalPnt2d( const gp_Pnt& P, const gp_Cone& C)
100{
101 gp_Vec OP( C.Location(),P);
102 Standard_Real X = OP.Dot(gp_Vec(C.Position().XDirection()));
103 Standard_Real Y = OP.Dot(gp_Vec(C.Position().YDirection()));
104 Standard_Real Z = OP.Dot(gp_Vec(C.Position().Direction()));
105 Standard_Real U,V;
106
107 if ( Abs(X) > Precision::PConfusion() ||
108 Abs(Y) > Precision::PConfusion() ) {
109 U = ATan2(Y,X);
110 }
111 else {
112 U = 0.;
113 }
114
115 V = Z / Cos(C.SemiAngle());
116
117 return gp_Pnt2d( U, Z);
118}
119#endif
120
121//=======================================================================
122//function : Project
123//purpose :
124//=======================================================================
125
126void ProjLib_Cone::Project(const gp_Lin& L)
127{
128
129 Standard_Real U,V;
130
131 // Compute V
132 V = gp_Vec(myCone.Location(),L.Location())
133 .Dot(gp_Vec(myCone.Position().Direction()));
134 V /= Cos( myCone.SemiAngle());
135
136 // Compute U
137 gp_Ax3 CPos = myCone.Position();
138 gp_Dir ZCone = CPos.XDirection() ^ CPos.YDirection();
139
140 gp_Ax3 RightHanded(CPos.Location(), ZCone, CPos.XDirection());
141 gp_Trsf T;
142 T.SetTransformation(RightHanded);
143
144 gp_Dir D = L.Position().Direction();
145 D.Transform(T);
146
147 if ( D.Z() < 0.) D.Reverse();
148 D.SetCoord(3, 0.);
149 U = gp::DX().AngleWithRef( D, gp::DZ());
150
151 Standard_Integer a1 =
152 (ZCone.IsEqual(CPos.Direction(), Precision::Angular())) ? 1 : -1;
153 Standard_Integer a2 =
154 (myCone.SemiAngle() > 0) ? 1 : -1;
c6541a0c 155 if ( ( a1 * a2) == -1) U -= M_PI;
7fd59977 156
c6541a0c 157 if ( U < 0.) U += 2.*M_PI;
7fd59977 158
159 gp_Pnt P;
160 gp_Vec Vu, Vv;
161
162 ElSLib::ConeD1(U, V, CPos, myCone.RefRadius(), myCone.SemiAngle(),
163 P, Vu, Vv);
164
165 if(Vv.IsParallel(gp_Vec(L.Position().Direction()), Precision::Angular())) {
166
167 myType = GeomAbs_Line;
168
169 gp_Pnt2d P2d(U,V);
170
171 Standard_Real Signe = L.Direction().Dot(myCone.Position().Direction());
172 Signe = (Signe > 0.) ? 1. : -1.;
173 gp_Dir2d D2d(0., Signe);
174
175 myLin = gp_Lin2d( P2d, D2d);
176
177 isDone = Standard_True;
178 }
179
180}
181
182
183//=======================================================================
184//function : Project
185//purpose :
186//=======================================================================
187
188void ProjLib_Cone::Project(const gp_Circ& C)
189{
190 myType = GeomAbs_Line;
191
192 gp_Ax3 ConePos = myCone.Position();
193 gp_Ax3 CircPos = C.Position();
194
195 gp_Dir ZCone = ConePos.XDirection().Crossed(ConePos.YDirection());
196 gp_Dir ZCir = CircPos.XDirection().Crossed(CircPos.YDirection());
197
198 Standard_Real U, V;
199 Standard_Real x = ConePos.XDirection().Dot(CircPos.XDirection());
200 Standard_Real y = ConePos.YDirection().Dot(CircPos.XDirection());
201 Standard_Real z
202 = gp_Vec(myCone.Location(),C.Location()).Dot(ConePos.Direction());
203
204 // pour trouver le point U V, on reprend le code de ElSLib
205 // sans appliquer la Trsf au point ( aller retour inutile).
206 if ( x == 0.0 && y == 0.0 ) {
207 U = 0.;
208 }
209 else if ( -myCone.RefRadius() > z * Tan(myCone.SemiAngle())) {
210 U = ATan2(-y, -x);
211 }
212 else {
213 U = ATan2( y, x);
214 }
c6541a0c 215 if ( U < 0.) U += 2*M_PI;
7fd59977 216
217 V = z / Cos(myCone.SemiAngle());
218
219 gp_Pnt2d P2d1 (U, V);
220 gp_Dir2d D2d;
221 if ( ZCone.Dot(ZCir) > 0.)
222 D2d.SetCoord(1., 0.);
223 else
224 D2d.SetCoord(-1., 0.);
225
226 myLin = gp_Lin2d(P2d1, D2d);
227 isDone = Standard_True;
228}
229
230void ProjLib_Cone::Project(const gp_Elips& E)
231{
232 ProjLib_Projector::Project(E);
233}
234
235void ProjLib_Cone::Project(const gp_Parab& P)
236{
237 ProjLib_Projector::Project(P);
238}
239
240void ProjLib_Cone::Project(const gp_Hypr& H)
241{
242 ProjLib_Projector::Project(H);
243}
244