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