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