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