0023948: Wrong intersection between a surface of revolution and a plane.
[occt.git] / src / IntImpParGen / IntImpParGen.cxx
1 // Created on: 1992-06-10
2 // Created by: Laurent BUCHARD
3 // Copyright (c) 1992-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 #include <IntImpParGen.ixx>
18 #include <IntRes2d_Domain.hxx>
19 #include <IntRes2d_Position.hxx>
20 #include <IntRes2d_Transition.hxx>
21 #include <gp_Vec2d.hxx>
22 #include <gp_Pnt2d.hxx>
23
24
25
26
27 #include <IntImpParGen_Tool.hxx>
28 #include <gp.hxx>
29
30
31 #define TOLERANCE_ANGULAIRE     0.00000001
32 #define DERIVEE_PREMIERE_NULLE  0.000000000001
33 //----------------------------------------------------------------------
34 Standard_Real IntImpParGen::NormalizeOnDomain(Standard_Real& Param,
35                                               const IntRes2d_Domain& TheDomain) {
36   Standard_Real modParam = Param;
37   if(TheDomain.IsClosed()) {
38     Standard_Real Periode,t;
39     TheDomain.EquivalentParameters(t,Periode);
40     Periode-=t;
41     while(   modParam<TheDomain.FirstParameter()
42           && modParam+Periode < TheDomain.LastParameter()) {
43       modParam+=Periode;
44     }
45     while(   modParam>TheDomain.LastParameter()
46           && modParam-Periode > TheDomain.FirstParameter()) {
47       modParam-=Periode;
48     }
49   }  
50   return(modParam);
51 }
52 //----------------------------------------------------------------------
53 void IntImpParGen::DeterminePosition(IntRes2d_Position& Pos1,
54                                      const IntRes2d_Domain& TheDomain,
55                                      const gp_Pnt2d& Pnt1,
56                                      const Standard_Real Param1) {
57   
58   Pos1=IntRes2d_Middle;
59
60   if(TheDomain.HasFirstPoint()) { 
61     if(Pnt1.Distance(TheDomain.FirstPoint()) 
62        <= TheDomain.FirstTolerance()) {
63       Pos1=IntRes2d_Head;       
64     }
65   }
66    
67   if(TheDomain.HasLastPoint()) {
68     if(Pnt1.Distance(TheDomain.LastPoint()) 
69        <= TheDomain.LastTolerance()) {
70       if(Pos1==IntRes2d_Head) {
71         if(Abs(Param1-TheDomain.LastParameter())
72            < Abs(Param1-TheDomain.FirstParameter()))
73           Pos1=IntRes2d_End;    
74       }
75       else {
76         Pos1=IntRes2d_End; 
77       }
78     } 
79   }
80 }   
81 //----------------------------------------------------------------------
82 void IntImpParGen::DetermineTransition(const IntRes2d_Position    Pos1,
83                                        gp_Vec2d&                  Tan1,
84                                        const gp_Vec2d&            Norm1,
85                                        IntRes2d_Transition&       T1,
86                                        const IntRes2d_Position    Pos2,
87                                        gp_Vec2d&                  Tan2,
88                                        const gp_Vec2d&            Norm2,
89                                        IntRes2d_Transition&       T2,
90                                        const Standard_Real        ) {
91   
92   Standard_Boolean courbure1=Standard_True;
93   Standard_Boolean courbure2=Standard_True;
94   Standard_Boolean decide=Standard_True;
95       
96   T1.SetPosition(Pos1);
97   T2.SetPosition(Pos2);
98
99
100   if (Tan1.SquareMagnitude()<=DERIVEE_PREMIERE_NULLE) {
101     Tan1=Norm1;
102     courbure1=Standard_False;
103     if (Tan1.SquareMagnitude()<=DERIVEE_PREMIERE_NULLE) {    // transition undecided
104       decide=Standard_False;
105     }
106   }
107   
108   if (Tan2.SquareMagnitude()<=DERIVEE_PREMIERE_NULLE) {
109     Tan2=Norm2;
110     courbure2=Standard_False;
111     if (Tan2.SquareMagnitude()<=DERIVEE_PREMIERE_NULLE) {    // transition undecided
112       decide=Standard_False;
113     }
114   }
115   
116   if (!decide) {
117     T1.SetValue(Pos1);
118     T2.SetValue(Pos2);
119   }
120   else {
121     Standard_Real sgn=Tan1.Crossed(Tan2);
122     Standard_Real norm=Tan1.Magnitude()*Tan2.Magnitude();
123
124     if (Abs(sgn)<=TOLERANCE_ANGULAIRE*norm) {   // Transition TOUCH #########
125       Standard_Boolean opos=(Tan1.Dot(Tan2))<0;
126       if (!(courbure1||courbure2)) {
127         T1.SetValue(Standard_True,Pos1,IntRes2d_Unknown,opos);
128         T2.SetValue(Standard_True,Pos2,IntRes2d_Unknown,opos);
129       }
130       else {
131         gp_Vec2d Norm;
132         Tan1.Normalized();
133         Norm.SetCoord(-Tan1.Y(),Tan1.X());
134         Standard_Real Val1,Val2;
135         if (!courbure1) {
136           Val1=0.0;
137         }
138         else {
139           Val1=Norm.Dot(Norm1);
140         }
141         if (!courbure2) {
142           Val2=0.0;
143         }
144         else {
145           Val2=Norm.Dot(Norm2);
146         }
147         
148         if (Abs(Val1-Val2) <= TOLERANCE_ANGULAIRE) {
149           T1.SetValue(Standard_True,Pos1,IntRes2d_Unknown,opos);
150           T2.SetValue(Standard_True,Pos2,IntRes2d_Unknown,opos);
151         }
152         else if (Val2 > Val1) {
153           T2.SetValue(Standard_True,Pos2,IntRes2d_Inside,opos);
154           if (opos) {
155             T1.SetValue(Standard_True,Pos1,IntRes2d_Inside,opos);
156           }
157           else {
158             T1.SetValue(Standard_True,Pos1,IntRes2d_Outside,opos);
159           }
160         }
161         else {         // Val1 > Val2
162           T2.SetValue(Standard_True,Pos2,IntRes2d_Outside,opos);
163           if (opos) {
164             T1.SetValue(Standard_True,Pos1,IntRes2d_Outside,opos);
165           }
166           else {
167             T1.SetValue(Standard_True,Pos1,IntRes2d_Inside,opos);
168           }
169         }
170       }
171     }
172     else if (sgn<0) {
173       T1.SetValue(Standard_False,Pos1,IntRes2d_In);
174       T2.SetValue(Standard_False,Pos2,IntRes2d_Out);
175     }
176     else {     // sgn>0
177       T1.SetValue(Standard_False,Pos1,IntRes2d_Out);
178       T2.SetValue(Standard_False,Pos2,IntRes2d_In);
179     }
180   }
181 }
182
183 //----------------------------------------------------------------------
184 Standard_Boolean  IntImpParGen::DetermineTransition(const IntRes2d_Position    Pos1,
185                                                     gp_Vec2d&                  Tan1,
186                                                     IntRes2d_Transition&       T1,
187                                                     const IntRes2d_Position    Pos2,
188                                                     gp_Vec2d&                  Tan2,
189                                                     IntRes2d_Transition&       T2,
190                                                     const Standard_Real        ) {
191
192   T1.SetPosition(Pos1);
193   T2.SetPosition(Pos2);
194
195   Standard_Real Tan1Magnitude = Tan1.Magnitude();
196   if (Tan1Magnitude<=DERIVEE_PREMIERE_NULLE) {
197     return(Standard_False);
198   }
199
200   Standard_Real Tan2Magnitude = Tan2.Magnitude();  
201   if (Tan2Magnitude<=DERIVEE_PREMIERE_NULLE) {
202     return(Standard_False);
203   }
204
205   Standard_Real sgn=Tan1.Crossed(Tan2);
206   Standard_Real norm=Tan1Magnitude*Tan2Magnitude;
207   
208   if (Abs(sgn)<=TOLERANCE_ANGULAIRE*norm) {   // Transition TOUCH #########
209     return(Standard_False);
210   }
211   else if (sgn<0) {
212     T1.SetValue(Standard_False,Pos1,IntRes2d_In);
213     T2.SetValue(Standard_False,Pos2,IntRes2d_Out);
214   }
215   else {     // sgn>0
216     T1.SetValue(Standard_False,Pos1,IntRes2d_Out);
217     T2.SetValue(Standard_False,Pos2,IntRes2d_In);
218   }
219   return(Standard_True);
220 }
221
222
223
224
225
226
227
228
229