summaryrefslogtreecommitdiff
path: root/inc/IntCurve_ExactIntersectionPoint.gxx
blob: d689b82e4e3a63aeeb664b06efb9d869f750c180 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
// File:	IntCurve_ExactIntersectionPoint.gxx
// Created:	Wed Dec 15 16:18:55 1999
// Author:	Atelier CAS2000
//		<cas@cageox.paris1.matra-dtv.fr>


#include <math_Vector.hxx>
#include <math_FunctionSetRoot.hxx>
#include <math_NewtonFunctionSetRoot.hxx>
#include <gp_Vec2d.hxx>



//======================================================================
//===   
//======================================================================
IntCurve_ExactIntersectionPoint::IntCurve_ExactIntersectionPoint(const TheCurve& C1,const TheCurve& C2,const Standard_Real Tol)
    : done(Standard_False),
      nbroots(0),
      myTol(Tol*Tol),
      FctDist(C1,C2),
      ToleranceVector(1,2),
      BInfVector(1,2),
      BSupVector(1,2),
      StartingPoint(1,2),
      Root(1,2),
      anErrorOccurred(Standard_False)
    {
      ToleranceVector.Value(1) = TheCurveTool::EpsX(C1);
      ToleranceVector.Value(2) = TheCurveTool::EpsX(C2);
    }
  //----------------------------------------------------------------------
void IntCurve_ExactIntersectionPoint::Perform( const IntCurve_ThePolygon2d& Poly1
					      ,const IntCurve_ThePolygon2d& Poly2
					      ,Standard_Integer&            NumSegOn1
					      ,Standard_Integer&            NumSegOn2
					      ,Standard_Real&               ParamOnSeg1
					      ,Standard_Real&               ParamOnSeg2) {
    //----------------------------------------------------------------------
    //-- On prend comme bornes de recherches  : 
    //--
    //--   Segment      :      i-1        i           i+1        i+2      
    //--
    //--                  |---------|-----X-------|---------|----------|
    //--                Inf                                Sup
    //--                  
    if(NumSegOn1 >= Poly1.NbSegments() && ParamOnSeg1==0.0) { 
      NumSegOn1--; ParamOnSeg1 = 1.0;
    }
    if(NumSegOn2 >= Poly2.NbSegments() && ParamOnSeg2==0.0) { 
      NumSegOn2--; ParamOnSeg2 = 1.0;
    }
    if(NumSegOn1 <=0) { 
      NumSegOn1=1; ParamOnSeg1 = 0.0;
    }
    if(NumSegOn2 <=0) { 
      NumSegOn2=1; ParamOnSeg2 = 0.0;
    }
    
    StartingPoint.Value(1) = Poly1.ApproxParamOnCurve(NumSegOn1,ParamOnSeg1);
    if(NumSegOn1<=2) BInfVector.Value(1)= Poly1.InfParameter(); 
    else  BInfVector.Value(1)= Poly1.ApproxParamOnCurve(NumSegOn1-1,(Standard_Real)0.0); 
    if(NumSegOn1 >= (Poly1.NbSegments() -2)) BSupVector.Value(1)= Poly1.SupParameter();
    else BSupVector.Value(1)= Poly1.ApproxParamOnCurve(NumSegOn1+2,(Standard_Real)0.0);
    
    StartingPoint.Value(2) = Poly2.ApproxParamOnCurve(NumSegOn2,ParamOnSeg2);
    if(NumSegOn2<=2) BInfVector.Value(2)= Poly2.InfParameter();
    else BInfVector.Value(2)= Poly2.ApproxParamOnCurve(NumSegOn2-1,(Standard_Real)0.0);
    if(NumSegOn2 >= (Poly2.NbSegments() -2)) BSupVector.Value(2)= Poly2.SupParameter();
    else BSupVector.Value(2)= Poly2.ApproxParamOnCurve(NumSegOn2+2,(Standard_Real)0.0);
    

    IntCurve_ExactIntersectionPoint::MathPerform();
    if(nbroots == 0) { 
//      Standard_Real DeflectionOn1 = Poly1.DeflectionOverEstimation();
      Poly1.DeflectionOverEstimation();
//      Standard_Real DeflectionOn2 = Poly2.DeflectionOverEstimation();
      Poly2.DeflectionOverEstimation();
      // if(DeflectionOn2 > Poly1.BeginOfSeg(NumSegOn1).Distance(Poly1.EndOfSeg(NumSegOn1))) {
	{
	//-- On risque de donner des bornes sur la courbe 1 trop etroites. 
	Standard_Integer diff=1;
	Standard_Real AnBinfVector = BInfVector.Value(1);
	Standard_Real AnBsupVector = BSupVector.Value(1);
	//---------------- On elargit les bornes par la gauche --------------------
	do { 
	  diff++;
	  if((NumSegOn1-diff)<=1) { 
	    BInfVector.Value(1)= Poly1.InfParameter(); 
	    diff=0;
	  }
	  else BInfVector.Value(1)= Poly1.ApproxParamOnCurve(NumSegOn1-diff,(Standard_Real)0.0); 
	  IntCurve_ExactIntersectionPoint::MathPerform();
	  //-- le 18 nov 97 
	  if(diff>3) diff+=NumSegOn1/2;	  
	}
	while( nbroots==0 && diff!=0);
	//---------------- On elargit les bornes par la droite --------------------	
	if(nbroots==0) { 
	  BInfVector.Value(1) = AnBinfVector;
	  diff=1;
	  do { 
	    diff++;
	    if((NumSegOn1+diff) >= (Poly1.NbSegments() -1)) { 
	      BSupVector.Value(1)= Poly1.SupParameter();
	      diff=0;
	    }
	    else BSupVector.Value(1)= Poly1.ApproxParamOnCurve(NumSegOn1+1+diff,(Standard_Real)0.0);
	    IntCurve_ExactIntersectionPoint::MathPerform();
	    //-- le 18 nov 97 
	    if(diff>3) diff+=1+(Poly1.NbSegments()-NumSegOn1)/2;
	  }
	  while( nbroots==0 && diff!=0);
	}
	BSupVector.Value(1) = AnBsupVector;
      }
    
      if(nbroots==0) { 
	//-- On risque de donner des bornes sur la courbe 1 trop etroites. 
	Standard_Integer diff=1;
	Standard_Real AnBinfVector = BInfVector.Value(2);
	Standard_Real AnBsupVector = BSupVector.Value(2);
	//---------------- On elargit les bornes par la gauche --------------------
	do { 
	  diff++;
	  if((NumSegOn2-diff)<=1) { 
	    BInfVector.Value(2)= Poly2.InfParameter(); 
	    diff=0;
	  }
	  else BInfVector.Value(2)= Poly2.ApproxParamOnCurve(NumSegOn2-diff,(Standard_Real)0.0); 
	  IntCurve_ExactIntersectionPoint::MathPerform();
	  //-- le 18 nov 97 
	  if(diff>3) diff+=NumSegOn2/2;
	}
	while( nbroots==0 && diff!=0);
	//---------------- On elargit les bornes par la droite --------------------	
	if(nbroots==0) { 
	  BInfVector.Value(2) = AnBinfVector;
	  diff=1;
	  do { 
	    diff++;
	    if((NumSegOn2+diff) >= (Poly2.NbSegments() -1)) { 
	      BSupVector.Value(2)= Poly2.SupParameter();
	      diff=0;
	    }
	    else BSupVector.Value(2)= Poly2.ApproxParamOnCurve(NumSegOn2+1+diff,(Standard_Real)0.0);
	    IntCurve_ExactIntersectionPoint::MathPerform();
	    //-- le 18 nov 97 
	    if(diff>3) diff+=1+(Poly2.NbSegments()-NumSegOn2)/2;
	  }
	  while( nbroots==0 && diff!=0);
	}
	BSupVector.Value(2) = AnBsupVector;
      }
    }
  }
  //----------------------------------------------------------------------
void IntCurve_ExactIntersectionPoint::Perform( const Standard_Real Uo
	       ,const Standard_Real Vo
	       ,const Standard_Real UInf
	       ,const Standard_Real VInf
	       ,const Standard_Real USup
	       ,const Standard_Real VSup) { 
    
    done = Standard_True;
    
    BInfVector.Value(1) = UInf;
    BInfVector.Value(2) = VInf;
    BSupVector.Value(1) = USup;
    BSupVector.Value(2) = VSup;
    StartingPoint.Value(1) = Uo;
    StartingPoint.Value(2) = Vo;
    
    IntCurve_ExactIntersectionPoint::MathPerform();
    
  }
  //----------------------------------------------------------------------
Standard_Integer IntCurve_ExactIntersectionPoint::NbRoots() const { return(nbroots); } 
  //----------------------------------------------------------------------

void IntCurve_ExactIntersectionPoint::Roots(Standard_Real& U,Standard_Real& V) {
    U=Root.Value(1);
    V=Root.Value(2); 
  }
  //----------------------------------------------------------------------

void IntCurve_ExactIntersectionPoint::MathPerform(void) {
    math_FunctionSetRoot Fct( FctDist
			     ,StartingPoint
			     ,ToleranceVector
			     ,BInfVector
			     ,BSupVector
			     ,50);
    
    if(Fct.IsDone()) { 
      Fct.Root(Root); nbroots = 1; 
      math_Vector XY(1,2);
      FctDist.Value(Root,XY);
      Standard_Real dist2 = ((XY(1)*XY(1)+XY(2)*XY(2)));
      if(dist2 > myTol) nbroots = 0;
    }
    else { 
      anErrorOccurred = Standard_True;
      nbroots = 0; 
    }
  }
    
//======================================================================

Standard_Boolean IntCurve_ExactIntersectionPoint::AnErrorOccurred() const
{
  return anErrorOccurred;
}