1// Created on: 1999-12-15
2// Created by: Atelier CAS2000
3// Copyright (c) 1999-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 <math_Vector.hxx>
18#include <math_FunctionSetRoot.hxx>
19#include <math_NewtonFunctionSetRoot.hxx>
20#include <gp_Vec2d.hxx>
21
22
23
24//======================================================================
25//===
26//======================================================================
27IntCurve_ExactIntersectionPoint::IntCurve_ExactIntersectionPoint(const TheCurve& C1,const TheCurve& C2,const Standard_Real Tol)
28    : done(Standard_False),
29      nbroots(0),
30      myTol(Tol*Tol),
31      FctDist(C1,C2),
32      ToleranceVector(1,2),
33      BInfVector(1,2),
34      BSupVector(1,2),
35      StartingPoint(1,2),
36      Root(1,2),
37      anErrorOccurred(Standard_False)
38{
39  ToleranceVector.Value(1) = TheCurveTool::EpsX(C1);
40  ToleranceVector.Value(2) = TheCurveTool::EpsX(C2);
41}
42  //----------------------------------------------------------------------
43void IntCurve_ExactIntersectionPoint::Perform( const IntCurve_ThePolygon2d& Poly1
44					      ,const IntCurve_ThePolygon2d& Poly2
45					      ,Standard_Integer&            NumSegOn1
46					      ,Standard_Integer&            NumSegOn2
47					      ,Standard_Real&               ParamOnSeg1
48					      ,Standard_Real&               ParamOnSeg2)
49{
50  //----------------------------------------------------------------------
51  //-- On prend comme bornes de recherches  :
52  //--
53  //--   Segment      :      i-1        i           i+1        i+2
54  //--
55  //--                  |---------|-----X-------|---------|----------|
56  //--                Inf                                Sup
57  //--
58  if(NumSegOn1 >= Poly1.NbSegments() && ParamOnSeg1==0.0) {
59    NumSegOn1--; ParamOnSeg1 = 1.0;
60  }
61  if(NumSegOn2 >= Poly2.NbSegments() && ParamOnSeg2==0.0) {
62    NumSegOn2--; ParamOnSeg2 = 1.0;
63  }
64  if(NumSegOn1 <=0) {
65    NumSegOn1=1; ParamOnSeg1 = 0.0;
66  }
67  if(NumSegOn2 <=0) {
68    NumSegOn2=1; ParamOnSeg2 = 0.0;
69  }
70
71  StartingPoint.Value(1) = Poly1.ApproxParamOnCurve(NumSegOn1,ParamOnSeg1);
72  if(NumSegOn1<=2) BInfVector.Value(1)= Poly1.InfParameter();
73  else  BInfVector.Value(1)= Poly1.ApproxParamOnCurve(NumSegOn1-1,(Standard_Real)0.0);
74  if(NumSegOn1 >= (Poly1.NbSegments() -2)) BSupVector.Value(1)= Poly1.SupParameter();
75  else BSupVector.Value(1)= Poly1.ApproxParamOnCurve(NumSegOn1+2,(Standard_Real)0.0);
76
77  StartingPoint.Value(2) = Poly2.ApproxParamOnCurve(NumSegOn2,ParamOnSeg2);
78  if(NumSegOn2<=2) BInfVector.Value(2)= Poly2.InfParameter();
79  else BInfVector.Value(2)= Poly2.ApproxParamOnCurve(NumSegOn2-1,(Standard_Real)0.0);
80  if(NumSegOn2 >= (Poly2.NbSegments() -2)) BSupVector.Value(2)= Poly2.SupParameter();
81  else BSupVector.Value(2)= Poly2.ApproxParamOnCurve(NumSegOn2+2,(Standard_Real)0.0);
82
83
84  IntCurve_ExactIntersectionPoint::MathPerform();
85  if(nbroots == 0) {
86    //      Standard_Real DeflectionOn1 = Poly1.DeflectionOverEstimation();
87    Poly1.DeflectionOverEstimation();
88    //      Standard_Real DeflectionOn2 = Poly2.DeflectionOverEstimation();
89    Poly2.DeflectionOverEstimation();
90    // if(DeflectionOn2 > Poly1.BeginOfSeg(NumSegOn1).Distance(Poly1.EndOfSeg(NumSegOn1))) {
91    {
92      //-- On risque de donner des bornes sur la courbe 1 trop etroites.
93      Standard_Integer diff=1;
94      Standard_Real AnBinfVector = BInfVector.Value(1);
95      Standard_Real AnBsupVector = BSupVector.Value(1);
96      //---------------- On elargit les bornes par la gauche --------------------
97      do {
98        diff++;
99        if((NumSegOn1-diff)<=1) {
100          BInfVector.Value(1)= Poly1.InfParameter();
101          diff=0;
102        }
103        else BInfVector.Value(1)= Poly1.ApproxParamOnCurve(NumSegOn1-diff,(Standard_Real)0.0);
104        IntCurve_ExactIntersectionPoint::MathPerform();
105        //-- le 18 nov 97
106        if(diff>3) diff+=NumSegOn1/2;
107      }
108      while( nbroots==0 && diff!=0);
109      //---------------- On elargit les bornes par la droite --------------------
110      if(nbroots==0) {
111        BInfVector.Value(1) = AnBinfVector;
112        diff=1;
113        do {
114          diff++;
115          if((NumSegOn1+diff) >= (Poly1.NbSegments() -1)) {
116            BSupVector.Value(1)= Poly1.SupParameter();
117            diff=0;
118          }
119          else BSupVector.Value(1)= Poly1.ApproxParamOnCurve(NumSegOn1+1+diff,(Standard_Real)0.0);
120          IntCurve_ExactIntersectionPoint::MathPerform();
121          //-- le 18 nov 97
122          if(diff>3) diff+=1+(Poly1.NbSegments()-NumSegOn1)/2;
123        }
124        while( nbroots==0 && diff!=0);
125      }
126      BSupVector.Value(1) = AnBsupVector;
127    }
128
129    if(nbroots==0) {
130      //-- On risque de donner des bornes sur la courbe 1 trop etroites.
131      Standard_Integer diff=1;
132      Standard_Real AnBinfVector = BInfVector.Value(2);
133      Standard_Real AnBsupVector = BSupVector.Value(2);
134      //---------------- On elargit les bornes par la gauche --------------------
135      do {
136        diff++;
137        if((NumSegOn2-diff)<=1) {
138          BInfVector.Value(2)= Poly2.InfParameter();
139          diff=0;
140        }
141        else BInfVector.Value(2)= Poly2.ApproxParamOnCurve(NumSegOn2-diff,(Standard_Real)0.0);
142        IntCurve_ExactIntersectionPoint::MathPerform();
143        //-- le 18 nov 97
144        if(diff>3) diff+=NumSegOn2/2;
145      }
146      while( nbroots==0 && diff!=0);
147      //---------------- On elargit les bornes par la droite --------------------
148      if(nbroots==0)
149      {
150        BInfVector.Value(2) = AnBinfVector;
151        diff=1;
152        do {
153          diff++;
154          if((NumSegOn2+diff) >= (Poly2.NbSegments() -1)) {
155            BSupVector.Value(2)= Poly2.SupParameter();
156            diff=0;
157          }
158          else BSupVector.Value(2)= Poly2.ApproxParamOnCurve(NumSegOn2+1+diff,(Standard_Real)0.0);
159          IntCurve_ExactIntersectionPoint::MathPerform();
160          //-- le 18 nov 97
161          if(diff>3) diff+=1+(Poly2.NbSegments()-NumSegOn2)/2;
162        }
163        while( nbroots==0 && diff!=0);
164      }
165      BSupVector.Value(2) = AnBsupVector;
166    }
167  }
168}
169  //----------------------------------------------------------------------
170void IntCurve_ExactIntersectionPoint::Perform( const Standard_Real Uo
171	       ,const Standard_Real Vo
172	       ,const Standard_Real UInf
173	       ,const Standard_Real VInf
174	       ,const Standard_Real USup
175	       ,const Standard_Real VSup) {
176
177    done = Standard_True;
178
179    BInfVector.Value(1) = UInf;
180    BInfVector.Value(2) = VInf;
181    BSupVector.Value(1) = USup;
182    BSupVector.Value(2) = VSup;
183    StartingPoint.Value(1) = Uo;
184    StartingPoint.Value(2) = Vo;
185
186    IntCurve_ExactIntersectionPoint::MathPerform();
187
188  }
189  //----------------------------------------------------------------------
190Standard_Integer IntCurve_ExactIntersectionPoint::NbRoots() const { return(nbroots); }
191  //----------------------------------------------------------------------
192
193void IntCurve_ExactIntersectionPoint::Roots(Standard_Real& U,Standard_Real& V) {
194    U=Root.Value(1);
195    V=Root.Value(2);
196  }
197  //----------------------------------------------------------------------
198
199void IntCurve_ExactIntersectionPoint::MathPerform(void)
200{
201  math_FunctionSetRoot Fct(FctDist, ToleranceVector, 60);
202  Fct.Perform(FctDist, StartingPoint, BInfVector, BSupVector);
203
204  if(Fct.IsDone()) {
205    Fct.Root(Root); nbroots = 1;
206    math_Vector XY(1,2);
207    FctDist.Value(Root,XY);
208    Standard_Real dist2 = ((XY(1)*XY(1)+XY(2)*XY(2)));
209
210    if(dist2 > myTol)
211    {
212      nbroots = 0;
213    }
214  }
215  else {
216    anErrorOccurred = Standard_True;
217    nbroots = 0;
218  }
219}
220
221//======================================================================
222
223Standard_Boolean IntCurve_ExactIntersectionPoint::AnErrorOccurred() const
224{
225  return anErrorOccurred;
226}
227