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
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.
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.
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.
22 #include <Contap_ContAna.ixx>
27 #define Tolpetit 1.e-8
29 Contap_ContAna::Contap_ContAna (): done(Standard_False) {}
31 void Contap_ContAna::Perform (const gp_Sphere& S,
34 done = Standard_False;
35 typL = GeomAbs_Circle;
38 if (Abs(D.Dot(S.XAxis().Direction())) < 0.9999999999999) {
39 dir2 = D.Crossed(S.XAxis().Direction());
42 dir2 = D.Crossed(S.YAxis().Direction());
49 void Contap_ContAna::Perform (const gp_Sphere& S,
51 const Standard_Real Angle)
53 done = Standard_False;
54 typL = GeomAbs_Circle;
57 if (Abs(D.Dot(S.XAxis().Direction())) < 0.9999999999999) {
58 dir2 = D.Crossed(S.XAxis().Direction());
61 dir2 = D.Crossed(S.YAxis().Direction());
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);
70 void Contap_ContAna::Perform (const gp_Sphere& S,
73 done = Standard_False;
75 Standard_Real radius = S.Radius();
76 Standard_Real dist = Eye.Distance(S.Location());
81 prm = radius*sqrt(1.-radius*radius/(dist*dist));
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());
93 dir2 = dir1.Crossed(S.YAxis().Direction());
96 typL = GeomAbs_Circle;
102 void Contap_ContAna::Perform (const gp_Cylinder& C,
105 done = Standard_False;
107 gp_XYZ normale(C.Position().Direction().XYZ());
108 normale.Cross(D.XYZ());
109 if (normale.Modulus() <= 1e-15) {
115 dir1 = C.Position().Direction();
117 pt1.SetXYZ(C.Location().XYZ() + C.Radius()*normale);
118 pt2.SetXYZ(C.Location().XYZ() - C.Radius()*normale);
122 done = Standard_True;
125 void Contap_ContAna::Perform (const gp_Cylinder& C,
127 const Standard_Real Angle)
129 done = Standard_False;
131 Standard_Real Coefcos = D.Dot(C.Position().XDirection());
132 Standard_Real Coefsin = D.Dot(C.Position().YDirection());
133 Standard_Real Coefcst = cos(M_PI*0.5 + Angle);
135 Standard_Real norm1 = Coefcos*Coefcos + Coefsin*Coefsin;
136 Standard_Real norm2 = sqrt(norm1);
138 if (Abs(Coefcst) < norm2) {
141 dir1 = dir2 = C.Position().Direction();
143 if (!C.Direct()) { // The normal is inverted.
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
152 // sin(phi) = Coefsin/Sqrt(Coefcos**2 + Coefsin**2)
153 // and by using trigonometric relations the values of cosinus
154 // and sinus to the solutions are obtained.
156 prm = Sqrt(norm1 - Coefcst*Coefcst);
157 Standard_Real cost0,sint0,cost1,sint1;
159 cost0 = (Coefcos*Coefcst - Coefsin*prm)/norm1;
160 cost1 = (Coefcos*Coefcst + Coefsin*prm)/norm1;
162 sint0 = ( Coefcos*prm + Coefsin*Coefcst)/norm1;
163 sint1 = (-Coefcos*prm + Coefsin*Coefcst)/norm1;
165 gp_XYZ Xdir(C.Position().XDirection().XYZ());
166 gp_XYZ Ydir(C.Position().YDirection().XYZ());
169 dirxyz.SetLinearForm(cost0,Xdir,sint0,Ydir);
170 dirxyz.Multiply(C.Radius());
171 pt1.SetXYZ(C.Location().XYZ().Added(dirxyz));
173 dirxyz.SetLinearForm(cost1,Xdir,sint1,Ydir);
174 dirxyz.Multiply(C.Radius());
175 pt2.SetXYZ(C.Location().XYZ().Added(dirxyz));
181 done = Standard_True;
184 void Contap_ContAna::Perform (const gp_Cylinder& C,
187 done = Standard_False;
189 Standard_Real radius = C.Radius();
190 gp_Lin theaxis(C.Axis());
191 Standard_Real dist = theaxis.Distance(Eye);
192 if (dist <= radius) {
197 prm = radius*sqrt(1.-radius*radius/(dist*dist));
198 dir1 = C.Axis().Direction();
200 gp_XYZ axeye(theaxis.Normal(Eye).Direction().XYZ()); // orientate the axis to the outside
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);
208 done = Standard_True;
211 void Contap_ContAna::Perform (const gp_Cone& C,
214 done = Standard_False;
216 Standard_Real Tgtalpha = Tan(C.SemiAngle());
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;
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;
230 // else if (Abs(Coefcst) < norm2) {
232 if (Abs(Coefcst) < norm2) {
237 // Necessary to solve Coefcos*cos(t) + Coefsin*sin(t) = Coefcst
238 // and director vectors of solutions are
239 // cos(t0) * XDirection + sin(t0) * YDirection + ZDirection/Tgtalpha
240 // By setting cos(phi) = Coefcos/Sqrt(Coefcos**2 + Coefsin**2) and
241 // sin(phi) = Coefsin/Sqrt(Coefcos**2 + Coefsin**2)
242 // and by using trigonometric relations the values of cosinus
243 // and sinus to the solutions are obtained.
245 prm = Sqrt(norm1 - Coefcst*Coefcst);
246 Standard_Real cost0,sint0,cost1,sint1;
248 cost0 = (Coefcos*Coefcst - Coefsin*prm)/norm1;
249 cost1 = (Coefcos*Coefcst + Coefsin*prm)/norm1;
251 sint0 = ( Coefcos*prm + Coefsin*Coefcst)/norm1;
252 sint1 = (-Coefcos*prm + Coefsin*Coefcst)/norm1;
254 gp_XYZ Xdir(C.Position().XDirection().XYZ());
255 gp_XYZ Ydir(C.Position().YDirection().XYZ());
256 gp_XYZ Zdir(C.Axis().Direction().XYZ());
258 dirxyz.SetLinearForm(cost0,Xdir,sint0,Ydir,1./Tgtalpha,Zdir);
260 pt1.SetXYZ(pt1.XYZ()+dirxyz);
261 dirxyz.SetLinearForm(cost1,Xdir,sint1,Ydir,1./Tgtalpha,Zdir);
263 pt2.SetXYZ(pt2.XYZ()+dirxyz);
268 done = Standard_True;
271 void Contap_ContAna::Perform (const gp_Cone& C,
273 const Standard_Real Angle)
275 done = Standard_False;
278 Standard_Real Ang = C.SemiAngle();
279 Standard_Real Cosa = cos(Ang);
280 Standard_Real Sina = sin(Ang);
282 Standard_Real Coefcos = D.Dot(C.Position().XDirection());
283 Standard_Real Coefsin = D.Dot(C.Position().YDirection());
285 Standard_Real Coefcst1 = cos(M_PI*0.5 + Angle);
287 Standard_Real norm1 = Coefcos*Coefcos + Coefsin*Coefsin;
288 Standard_Real norm2 = Sqrt(norm1);
290 Standard_Real Coefnz = D.Dot(C.Axis().Direction())*Sina;
291 Standard_Real Coefcst = (Coefcst1 + Coefnz)/Cosa;
293 if (Abs(Coefcst) < norm2) {
299 // It is requiredto solve Coefcos*cos(t) + Coefsin*sin(t) = Coefcst
300 // and the director vectors of solutions are
301 // cos(t0) * XDirection + sin(t0) * YDirection + ZDirection/Tgtalpha
302 // By setting cos(phi) = Coefcos/Sqrt(Coefcos**2 + Coefsin**2) and
303 // sin(phi) = Coefsin/Sqrt(Coefcos**2 + Coefsin**2)
304 // and by using trigonometric relations the values of cosinus
305 // and sinus to the solutions are obtained.
307 prm = Sqrt(norm1 - Coefcst*Coefcst);
308 Standard_Real cost0,sint0,cost1,sint1;
310 cost0 = (Coefcos*Coefcst - Coefsin*prm)/norm1;
311 cost1 = (Coefcos*Coefcst + Coefsin*prm)/norm1;
313 sint0 = ( Coefcos*prm + Coefsin*Coefcst)/norm1;
314 sint1 = (-Coefcos*prm + Coefsin*Coefcst)/norm1;
316 gp_XYZ Xdir(C.Position().XDirection().XYZ());
317 gp_XYZ Ydir(C.Position().YDirection().XYZ());
318 gp_XYZ Zdir(C.Axis().Direction().XYZ());
323 dirxyz.SetLinearForm(cost0,Xdir,sint0,Ydir,Cosa/Sina,Zdir);
325 pt1.SetXYZ(pt1.XYZ()+dirxyz);
326 dirxyz.SetLinearForm(cost1,Xdir,sint1,Ydir,Cosa/Sina,Zdir);
328 pt2.SetXYZ(pt2.XYZ()+dirxyz);
331 Coefcst = (Coefcst1 - Coefnz)/Cosa;
333 if (Abs(Coefcst) < norm2) {
339 prm = Sqrt(norm1 - Coefcst*Coefcst);
340 Standard_Real cost0,sint0,cost1,sint1;
342 cost0 = (Coefcos*Coefcst - Coefsin*prm)/norm1;
343 cost1 = (Coefcos*Coefcst + Coefsin*prm)/norm1;
345 sint0 = ( Coefcos*prm + Coefsin*Coefcst)/norm1;
346 sint1 = (-Coefcos*prm + Coefsin*Coefcst)/norm1;
348 gp_XYZ Xdir(C.Position().XDirection().XYZ());
349 gp_XYZ Ydir(C.Position().YDirection().XYZ());
350 gp_XYZ Zdir(C.Axis().Direction().XYZ());
355 dirxyz.SetLinearForm(cost0,Xdir,sint0,Ydir,-Cosa/Sina,Zdir);
357 pt3.SetXYZ(pt3.XYZ()+dirxyz);
358 dirxyz.SetLinearForm(cost1,Xdir,sint1,Ydir,-Cosa/Sina,Zdir);
360 pt4.SetXYZ(pt4.XYZ()+dirxyz);
369 done = Standard_True;
372 void Contap_ContAna::Perform (const gp_Cone& C,
375 done = Standard_False;
377 Standard_Real Tgtalpha = Tan(C.SemiAngle());
379 gp_XYZ apexeye(Eye.XYZ());
380 apexeye.Subtract(C.Apex().XYZ());
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;
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;
392 // dir1.SetXYZ(apexeye);
394 // else if (Abs(Coefcst) < norm2) {
396 if (Abs(Coefcst) < norm2) {
401 // It is required to solve Coefcos*cos(t) + Coefsin*sin(t) = Coefcst
402 // and the director vectors of solutions are
403 // cos(t0) * XDirection + sin(t0) * YDirection + ZDirection/Tgtalpha
404 // By setting cos(phi) = Coefcos/Sqrt(Coefcos**2 + Coefsin**2) and
405 // sin(phi) = Coefsin/Sqrt(Coefcos**2 + Coefsin**2)
406 // and by using trigonometric relations the values of cosinus
407 // and sinus to the solutions are obtained.
409 prm = Sqrt(norm1 - Coefcst*Coefcst);
410 Standard_Real cost0,sint0,cost1,sint1;
412 cost0 = (Coefcos*Coefcst - Coefsin*prm)/norm1;
413 cost1 = (Coefcos*Coefcst + Coefsin*prm)/norm1;
415 sint0 = ( Coefcos*prm + Coefsin*Coefcst)/norm1;
416 sint1 = (-Coefcos*prm + Coefsin*Coefcst)/norm1;
418 gp_XYZ Xdir(C.Position().XDirection().XYZ());
419 gp_XYZ Ydir(C.Position().YDirection().XYZ());
420 gp_XYZ Zdir(C.Axis().Direction().XYZ());
422 dirxyz.SetLinearForm(cost0,Xdir,sint0,Ydir,1./Tgtalpha,Zdir);
424 pt1.SetXYZ(pt1.XYZ()+dirxyz);
425 dirxyz.SetLinearForm(cost1,Xdir,sint1,Ydir,1./Tgtalpha,Zdir);
427 pt2.SetXYZ(pt2.XYZ()+dirxyz);
432 done = Standard_True;
435 gp_Lin Contap_ContAna::Line (const Standard_Integer Index) const
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();}
442 return gp_Lin(pt1,dir1);
444 return gp_Lin(pt2,dir2);
446 return gp_Lin(pt3,dir3);
448 return gp_Lin(pt4,dir4);
450 Standard_OutOfRange::Raise("Program error in Contap_ContAna");