0024750: Replace instantiations of TCollection generic classes by NCollection templat...
[occt.git] / src / Contap / Contap_ContAna.cxx
CommitLineData
b311480e 1// Created on: 1993-03-04
2// Created by: Jacques GOUSSARD
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.
733a0e55 16
7fd59977 17#include <Contap_ContAna.ixx>
18
19#include <gp_XYZ.hxx>
20#include <gp.hxx>
21
7fd59977 22#define Tolpetit 1.e-8
23
7fd59977 24Contap_ContAna::Contap_ContAna (): done(Standard_False) {}
25
26void Contap_ContAna::Perform (const gp_Sphere& S,
733a0e55 27 const gp_Dir& D)
7fd59977 28{
29 done = Standard_False;
30 typL = GeomAbs_Circle;
31 pt1 = S.Location();
32 dir1 = D;
33 if (Abs(D.Dot(S.XAxis().Direction())) < 0.9999999999999) {
34 dir2 = D.Crossed(S.XAxis().Direction());
35 }
36 else {
37 dir2 = D.Crossed(S.YAxis().Direction());
38 }
39 prm = S.Radius();
40 nbSol = 1;
41 done = Standard_True;
42}
43
44void Contap_ContAna::Perform (const gp_Sphere& S,
733a0e55
S
45 const gp_Dir& D,
46 const Standard_Real Angle)
7fd59977 47{
48 done = Standard_False;
49 typL = GeomAbs_Circle;
50
51 dir1 = D;
52 if (Abs(D.Dot(S.XAxis().Direction())) < 0.9999999999999) {
53 dir2 = D.Crossed(S.XAxis().Direction());
54 }
55 else {
56 dir2 = D.Crossed(S.YAxis().Direction());
57 }
58 Standard_Real alpha = (S.Direct() ? Angle : -Angle);
59 pt1.SetXYZ(S.Location().XYZ() - S.Radius()*sin(alpha)*D.XYZ()) ;
60 prm = S.Radius()*cos(alpha);
61 nbSol = 1;
62 done = Standard_True;
63}
64
65void Contap_ContAna::Perform (const gp_Sphere& S,
733a0e55 66 const gp_Pnt& Eye)
7fd59977 67{
68 done = Standard_False;
69
70 Standard_Real radius = S.Radius();
71 Standard_Real dist = Eye.Distance(S.Location());
72 if (dist <= radius) {
73 nbSol = 0;
74 }
75 else {
76 prm = radius*sqrt(1.-radius*radius/(dist*dist));
77 if (prm < Tolpetit) {
78 nbSol = 0;
79 }
80 else {
81 gp_XYZ locxyz(S.Location().XYZ());
82 dir1.SetXYZ(Eye.XYZ()-locxyz);
83 pt1.SetXYZ(locxyz + (radius*radius/dist)*dir1.XYZ());
84 if (Abs(dir1.Dot(S.XAxis().Direction())) < 0.9999999999999) {
85 dir2 = dir1.Crossed(S.XAxis().Direction());
86 }
87 else {
88 dir2 = dir1.Crossed(S.YAxis().Direction());
89 }
90 nbSol = 1;
91 typL = GeomAbs_Circle;
92 }
93 }
94 done = Standard_True;
95}
96
7fd59977 97void Contap_ContAna::Perform (const gp_Cylinder& C,
733a0e55 98 const gp_Dir& D)
7fd59977 99{
100 done = Standard_False;
101
102 gp_XYZ normale(C.Position().Direction().XYZ());
103 normale.Cross(D.XYZ());
104 if (normale.Modulus() <= 1e-15) {
105 nbSol = 0;
106 }
107 else {
108 normale.Normalize();
109 typL = GeomAbs_Line;
110 dir1 = C.Position().Direction();
111 dir2 = dir1;
112 pt1.SetXYZ(C.Location().XYZ() + C.Radius()*normale);
113 pt2.SetXYZ(C.Location().XYZ() - C.Radius()*normale);
114 nbSol = 2;
115 }
116
117 done = Standard_True;
118}
119
120void Contap_ContAna::Perform (const gp_Cylinder& C,
733a0e55
S
121 const gp_Dir& D,
122 const Standard_Real Angle)
7fd59977 123{
124 done = Standard_False;
125
126 Standard_Real Coefcos = D.Dot(C.Position().XDirection());
127 Standard_Real Coefsin = D.Dot(C.Position().YDirection());
c6541a0c 128 Standard_Real Coefcst = cos(M_PI*0.5 + Angle);
7fd59977 129
130 Standard_Real norm1 = Coefcos*Coefcos + Coefsin*Coefsin;
131 Standard_Real norm2 = sqrt(norm1);
132
133 if (Abs(Coefcst) < norm2) {
134 typL = GeomAbs_Line;
135 nbSol = 2;
136 dir1 = dir2 = C.Position().Direction();
137
0d969553 138 if (!C.Direct()) { // The normal is inverted.
7fd59977 139 Coefcos = -Coefcos;
140 Coefsin = -Coefsin;
141 }
142
0d969553
Y
143 // Necessary to solve Coefcos*cos(t) + Coefsin*sin(t) = Coefcst
144 // and the origins of solution are in the reference of the
145 // cylinder in (R*cost0, R*sint0,0) and (R*cost1,R*sint1,0)
146 // By setting cos(phi) = Coefcos/Sqrt(Coefcos**2 + Coefsin**2) and
7fd59977 147 // sin(phi) = Coefsin/Sqrt(Coefcos**2 + Coefsin**2)
0d969553
Y
148 // and by using trigonometric relations the values of cosinus
149 // and sinus to the solutions are obtained.
7fd59977 150
151 prm = Sqrt(norm1 - Coefcst*Coefcst);
152 Standard_Real cost0,sint0,cost1,sint1;
153
154 cost0 = (Coefcos*Coefcst - Coefsin*prm)/norm1;
155 cost1 = (Coefcos*Coefcst + Coefsin*prm)/norm1;
156
157 sint0 = ( Coefcos*prm + Coefsin*Coefcst)/norm1;
158 sint1 = (-Coefcos*prm + Coefsin*Coefcst)/norm1;
159
160 gp_XYZ Xdir(C.Position().XDirection().XYZ());
161 gp_XYZ Ydir(C.Position().YDirection().XYZ());
162 gp_XYZ dirxyz;
163
164 dirxyz.SetLinearForm(cost0,Xdir,sint0,Ydir);
165 dirxyz.Multiply(C.Radius());
166 pt1.SetXYZ(C.Location().XYZ().Added(dirxyz));
167
168 dirxyz.SetLinearForm(cost1,Xdir,sint1,Ydir);
169 dirxyz.Multiply(C.Radius());
170 pt2.SetXYZ(C.Location().XYZ().Added(dirxyz));
171 }
172 else {
173 nbSol = 0;
174 }
175
176 done = Standard_True;
177}
178
179void Contap_ContAna::Perform (const gp_Cylinder& C,
733a0e55 180 const gp_Pnt& Eye)
7fd59977 181{
182 done = Standard_False;
183
184 Standard_Real radius = C.Radius();
185 gp_Lin theaxis(C.Axis());
186 Standard_Real dist = theaxis.Distance(Eye);
187 if (dist <= radius) {
188 nbSol = 0;
189 }
190 else {
191 typL = GeomAbs_Line;
192 prm = radius*sqrt(1.-radius*radius/(dist*dist));
193 dir1 = C.Axis().Direction();
194 dir2 = dir1;
0d969553 195 gp_XYZ axeye(theaxis.Normal(Eye).Direction().XYZ()); // orientate the axis to the outside
7fd59977 196 gp_XYZ normale((theaxis.Direction().Crossed(axeye)).XYZ());
197// normale.Normalize();
198 pt1.SetXYZ(C.Location().XYZ() + (radius*radius/dist)*axeye);
199 pt2.SetXYZ(pt1.XYZ() - prm*normale);
200 pt1.SetXYZ(pt1.XYZ() + prm*normale);
201 nbSol = 2;
202 }
203 done = Standard_True;
204}
205
7fd59977 206void Contap_ContAna::Perform (const gp_Cone& C,
733a0e55 207 const gp_Dir& D)
7fd59977 208{
209 done = Standard_False;
210
211 Standard_Real Tgtalpha = Tan(C.SemiAngle());
212
213 Standard_Real Coefcos = D.Dot(C.Position().XDirection());
214 Standard_Real Coefsin = D.Dot(C.Position().YDirection());
215 Standard_Real Coefcst = D.Dot(C.Axis().Direction())*Tgtalpha;
216
217 Standard_Real norm1 = Coefcos*Coefcos + Coefsin*Coefsin;
218 Standard_Real norm2 = Sqrt(norm1);
219// if (Abs(Abs(Coefcst)-norm2) <= Tolpetit) { // tol angulaire 1.e-8
220// typL = GeomAbs_Line;
221// nbSol = 1;
222// pt1 = C.Apex();
223// dir1 = D;
224// }
225// else if (Abs(Coefcst) < norm2) {
226
227 if (Abs(Coefcst) < norm2) {
228 typL = GeomAbs_Line;
229 nbSol = 2;
230 pt1 = C.Apex();
231 pt2 = pt1;
0d969553
Y
232 // Necessary to solve Coefcos*cos(t) + Coefsin*sin(t) = Coefcst
233 // and director vectors of solutions are
7fd59977 234 // cos(t0) * XDirection + sin(t0) * YDirection + ZDirection/Tgtalpha
0d969553 235 // By setting cos(phi) = Coefcos/Sqrt(Coefcos**2 + Coefsin**2) and
7fd59977 236 // sin(phi) = Coefsin/Sqrt(Coefcos**2 + Coefsin**2)
0d969553
Y
237 // and by using trigonometric relations the values of cosinus
238 // and sinus to the solutions are obtained.
7fd59977 239
240 prm = Sqrt(norm1 - Coefcst*Coefcst);
241 Standard_Real cost0,sint0,cost1,sint1;
242
243 cost0 = (Coefcos*Coefcst - Coefsin*prm)/norm1;
244 cost1 = (Coefcos*Coefcst + Coefsin*prm)/norm1;
245
246 sint0 = ( Coefcos*prm + Coefsin*Coefcst)/norm1;
247 sint1 = (-Coefcos*prm + Coefsin*Coefcst)/norm1;
248
249 gp_XYZ Xdir(C.Position().XDirection().XYZ());
250 gp_XYZ Ydir(C.Position().YDirection().XYZ());
251 gp_XYZ Zdir(C.Axis().Direction().XYZ());
252 gp_XYZ dirxyz;
253 dirxyz.SetLinearForm(cost0,Xdir,sint0,Ydir,1./Tgtalpha,Zdir);
254 dir1.SetXYZ(dirxyz);
255 pt1.SetXYZ(pt1.XYZ()+dirxyz);
256 dirxyz.SetLinearForm(cost1,Xdir,sint1,Ydir,1./Tgtalpha,Zdir);
257 dir2.SetXYZ(dirxyz);
258 pt2.SetXYZ(pt2.XYZ()+dirxyz);
259 }
260 else {
261 nbSol = 0;
262 }
263 done = Standard_True;
264}
265
7fd59977 266void Contap_ContAna::Perform (const gp_Cone& C,
733a0e55
S
267 const gp_Dir& D,
268 const Standard_Real Angle)
7fd59977 269{
270 done = Standard_False;
271 nbSol = 0;
272
273 Standard_Real Ang = C.SemiAngle();
274 Standard_Real Cosa = cos(Ang);
275 Standard_Real Sina = sin(Ang);
276
277 Standard_Real Coefcos = D.Dot(C.Position().XDirection());
278 Standard_Real Coefsin = D.Dot(C.Position().YDirection());
279
c6541a0c 280 Standard_Real Coefcst1 = cos(M_PI*0.5 + Angle);
7fd59977 281
282 Standard_Real norm1 = Coefcos*Coefcos + Coefsin*Coefsin;
283 Standard_Real norm2 = Sqrt(norm1);
284
285 Standard_Real Coefnz = D.Dot(C.Axis().Direction())*Sina;
286 Standard_Real Coefcst = (Coefcst1 + Coefnz)/Cosa;
287
288 if (Abs(Coefcst) < norm2) {
289 typL = GeomAbs_Line;
290 nbSol+= 2;
291 pt1 = C.Apex();
292 pt2 = pt1;
293
0d969553
Y
294 // It is requiredto solve Coefcos*cos(t) + Coefsin*sin(t) = Coefcst
295 // and the director vectors of solutions are
7fd59977 296 // cos(t0) * XDirection + sin(t0) * YDirection + ZDirection/Tgtalpha
0d969553 297 // By setting cos(phi) = Coefcos/Sqrt(Coefcos**2 + Coefsin**2) and
7fd59977 298 // sin(phi) = Coefsin/Sqrt(Coefcos**2 + Coefsin**2)
0d969553
Y
299 // and by using trigonometric relations the values of cosinus
300 // and sinus to the solutions are obtained.
7fd59977 301
302 prm = Sqrt(norm1 - Coefcst*Coefcst);
303 Standard_Real cost0,sint0,cost1,sint1;
304
305 cost0 = (Coefcos*Coefcst - Coefsin*prm)/norm1;
306 cost1 = (Coefcos*Coefcst + Coefsin*prm)/norm1;
307
308 sint0 = ( Coefcos*prm + Coefsin*Coefcst)/norm1;
309 sint1 = (-Coefcos*prm + Coefsin*Coefcst)/norm1;
310
311 gp_XYZ Xdir(C.Position().XDirection().XYZ());
312 gp_XYZ Ydir(C.Position().YDirection().XYZ());
313 gp_XYZ Zdir(C.Axis().Direction().XYZ());
314 if (!C.Direct()) {
315 Zdir.Reverse();
316 }
317 gp_XYZ dirxyz;
318 dirxyz.SetLinearForm(cost0,Xdir,sint0,Ydir,Cosa/Sina,Zdir);
319 dir1.SetXYZ(dirxyz);
320 pt1.SetXYZ(pt1.XYZ()+dirxyz);
321 dirxyz.SetLinearForm(cost1,Xdir,sint1,Ydir,Cosa/Sina,Zdir);
322 dir2.SetXYZ(dirxyz);
323 pt2.SetXYZ(pt2.XYZ()+dirxyz);
324 }
325
326 Coefcst = (Coefcst1 - Coefnz)/Cosa;
327
328 if (Abs(Coefcst) < norm2) {
329 typL = GeomAbs_Line;
330 nbSol+= 2;
331 pt3 = C.Apex();
332 pt4 = pt3;
333
334 prm = Sqrt(norm1 - Coefcst*Coefcst);
335 Standard_Real cost0,sint0,cost1,sint1;
336
337 cost0 = (Coefcos*Coefcst - Coefsin*prm)/norm1;
338 cost1 = (Coefcos*Coefcst + Coefsin*prm)/norm1;
339
340 sint0 = ( Coefcos*prm + Coefsin*Coefcst)/norm1;
341 sint1 = (-Coefcos*prm + Coefsin*Coefcst)/norm1;
342
343 gp_XYZ Xdir(C.Position().XDirection().XYZ());
344 gp_XYZ Ydir(C.Position().YDirection().XYZ());
345 gp_XYZ Zdir(C.Axis().Direction().XYZ());
346 if (!C.Direct()) {
347 Zdir.Reverse();
348 }
349 gp_XYZ dirxyz;
350 dirxyz.SetLinearForm(cost0,Xdir,sint0,Ydir,-Cosa/Sina,Zdir);
351 dir3.SetXYZ(dirxyz);
352 pt3.SetXYZ(pt3.XYZ()+dirxyz);
353 dirxyz.SetLinearForm(cost1,Xdir,sint1,Ydir,-Cosa/Sina,Zdir);
354 dir4.SetXYZ(dirxyz);
355 pt4.SetXYZ(pt4.XYZ()+dirxyz);
356 if (nbSol == 2) {
357 pt1 = pt3;
358 pt2 = pt4;
359 dir1 = dir3;
360 dir2 = dir4;
361 }
362 }
363
364 done = Standard_True;
7fd59977 365}
366
367void Contap_ContAna::Perform (const gp_Cone& C,
733a0e55 368 const gp_Pnt& Eye)
7fd59977 369{
370 done = Standard_False;
371
372 Standard_Real Tgtalpha = Tan(C.SemiAngle());
373
374 gp_XYZ apexeye(Eye.XYZ());
375 apexeye.Subtract(C.Apex().XYZ());
376
377 Standard_Real Coefcos = apexeye.Dot(C.Position().XDirection().XYZ());
378 Standard_Real Coefsin = apexeye.Dot(C.Position().YDirection().XYZ());
379 Standard_Real Coefcst = apexeye.Dot(C.Axis().Direction().XYZ())*Tgtalpha;
380
381 Standard_Real norm1 = Coefcos*Coefcos + Coefsin*Coefsin;
382 Standard_Real norm2 = Sqrt(Coefcos*Coefcos + Coefsin*Coefsin);
383// if (Abs(Abs(Coefcst)-norm2) <= Tolpetit) { // tol angulaire 1.e-8
384// typL = GeomAbs_Line;
385// nbSol = 1;
386// pt1 = C.Apex();
387// dir1.SetXYZ(apexeye);
388// }
389// else if (Abs(Coefcst) < norm2) {
390
391 if (Abs(Coefcst) < norm2) {
392 typL = GeomAbs_Line;
393 nbSol = 2;
394 pt1 = C.Apex();
395 pt2 = pt1;
0d969553
Y
396 // It is required to solve Coefcos*cos(t) + Coefsin*sin(t) = Coefcst
397 // and the director vectors of solutions are
7fd59977 398 // cos(t0) * XDirection + sin(t0) * YDirection + ZDirection/Tgtalpha
0d969553 399 // By setting cos(phi) = Coefcos/Sqrt(Coefcos**2 + Coefsin**2) and
7fd59977 400 // sin(phi) = Coefsin/Sqrt(Coefcos**2 + Coefsin**2)
0d969553
Y
401 // and by using trigonometric relations the values of cosinus
402 // and sinus to the solutions are obtained.
7fd59977 403
404 prm = Sqrt(norm1 - Coefcst*Coefcst);
405 Standard_Real cost0,sint0,cost1,sint1;
406
407 cost0 = (Coefcos*Coefcst - Coefsin*prm)/norm1;
408 cost1 = (Coefcos*Coefcst + Coefsin*prm)/norm1;
409
410 sint0 = ( Coefcos*prm + Coefsin*Coefcst)/norm1;
411 sint1 = (-Coefcos*prm + Coefsin*Coefcst)/norm1;
412
413 gp_XYZ Xdir(C.Position().XDirection().XYZ());
414 gp_XYZ Ydir(C.Position().YDirection().XYZ());
415 gp_XYZ Zdir(C.Axis().Direction().XYZ());
416 gp_XYZ dirxyz;
417 dirxyz.SetLinearForm(cost0,Xdir,sint0,Ydir,1./Tgtalpha,Zdir);
418 dir1.SetXYZ(dirxyz);
419 pt1.SetXYZ(pt1.XYZ()+dirxyz);
420 dirxyz.SetLinearForm(cost1,Xdir,sint1,Ydir,1./Tgtalpha,Zdir);
421 dir2.SetXYZ(dirxyz);
422 pt2.SetXYZ(pt2.XYZ()+dirxyz);
423 }
424 else {
425 nbSol = 0;
426 }
427 done = Standard_True;
7fd59977 428}
429
7fd59977 430gp_Lin Contap_ContAna::Line (const Standard_Integer Index) const
431{
432 if (!done) {StdFail_NotDone::Raise();}
433 if (typL != GeomAbs_Line || nbSol == 0) {Standard_DomainError::Raise();}
434 if (Index <=0 || Index > nbSol) {Standard_OutOfRange::Raise();}
435 switch (Index) {
436 case 1:
437 return gp_Lin(pt1,dir1);
438 case 2:
439 return gp_Lin(pt2,dir2);
440 case 3:
441 return gp_Lin(pt3,dir3);
442 case 4:
443 return gp_Lin(pt4,dir4);
444 }
733a0e55 445 Standard_OutOfRange::Raise("Program error in Contap_ContAna");
7fd59977 446 return gp_Lin();
447}