1 // File: GccIter_Lin2d2Tan.gxx
2 // Created: Fri Dec 20 15:00:23 1991
6 //========================================================================
7 // CREATION D UNE LIGNE TANGENTE A DEUX COURBES. +
8 //========================================================================
10 #include <StdFail_NotDone.hxx>
11 #include <GccEnt_BadQualifier.hxx>
13 #include <gp_Dir2d.hxx>
14 #include <gp_Vec2d.hxx>
15 #include <gp_Circ2d.hxx>
16 #include <math_Vector.hxx>
17 #include <math_Matrix.hxx>
18 #include <math_FunctionSetRoot.hxx>
19 #include <math_FunctionRoot.hxx>
22 GccIter_Lin2d2Tan (const GccEnt_QualifiedCirc& Qualified1 ,
23 const TheQualifiedCurve& Qualified2 ,
24 const Standard_Real Param2 ,
25 const Standard_Real Tolang ) {
30 Standard_Real Tol = Abs(Tolang);
32 WellDone = Standard_False;
33 if (Qualified1.IsEnclosed()) { GccEnt_BadQualifier::Raise(); }
34 gp_Circ2d C1 = Qualified1.Qualified();
35 TheCurve Cu2 = Qualified2.Qualified();
36 Standard_Real U1 = TheCurveTool::FirstParameter(Cu2);
37 Standard_Real U2 = TheCurveTool::LastParameter(Cu2);
38 GccIter_FuncTCirCu func(C1,Cu2);
39 math_FunctionRoot sol(func,Param2,TheCurveTool::EpsX(Cu2,Abs(Tolang)),U1,U2,100);
41 Standard_Real Usol = sol.Root();
42 // gp_Pnt2d Origine,Pt;
43 // Modified by Sergey KHROMOV - Thu Apr 5 17:39:47 2001 Begin
45 func.Value(Usol, Norm);
46 if (Abs(Norm) < Tolang) {
47 // Modified by Sergey KHROMOV - Thu Apr 5 17:39:48 2001 End
51 TheCurveTool::D2(Cu2,Usol,Origine,Vect1,Vect2);
52 gp_Vec2d Vdir(C1.Location().XY() - Origine.XY());
53 Standard_Real sign1 = Vect1.Dot(Vdir);
54 if (sign1 <= 0. ) { Vect1.Reverse(); }
55 Standard_Real sign2 = Vect2.Crossed(Vect1);
56 if (Qualified2.IsUnqualified() ||
57 (Qualified2.IsEnclosing() && sign2<=0.) ||
58 (Qualified2.IsOutside() && sign1 <= 0. && sign2 >= 0.) ||
59 (Qualified2.IsEnclosed() && sign1 >= 0. && sign2 >= 0.)) {
60 if (Qualified1.IsUnqualified() ||
61 (Qualified1.IsOutside() && Vect1.Angle(Vdir) <= 0.) ||
62 (Qualified1.IsEnclosing() && Vect1.Angle(Vdir) >= 0.)) {
63 gp_Dir2d direc(Vect1);
64 Standard_Real R1 = C1.Radius();
65 gp_XY normal(-R1*direc.Y(),R1*direc.X());
66 sign1 = Vect1.Crossed(Vdir);
67 if (Qualified1.IsEnclosing()) {
68 pnttg1sol = gp_Pnt2d(C1.Location().XY()-normal);
70 else if (Qualified1.IsOutside()) {
71 pnttg1sol = gp_Pnt2d(C1.Location().XY()+normal);
75 pnttg1sol = gp_Pnt2d(C1.Location().XY()-normal);
78 pnttg1sol = gp_Pnt2d(C1.Location().XY()+normal);
81 // if (gp_Vec2d(direc.XY()).Angle(gp_Vec2d(pnttg1sol,Origine)) <= Tol) {
83 linsol = gp_Lin2d(pnttg1sol,direc);
84 WellDone = Standard_True;
85 qualifier1 = Qualified1.Qualifier();
86 qualifier2 = Qualified2.Qualifier();
89 par2sol = pnttg2sol.Distance(pnttg1sol);
98 GccIter_Lin2d2Tan (const TheQualifiedCurve& Qualified1 ,
99 const TheQualifiedCurve& Qualified2 ,
100 const Standard_Real Param1 ,
101 const Standard_Real Param2 ,
102 const Standard_Real Tolang ) {
105 WellDone = Standard_False;
106 if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() ||
107 Qualified1.IsOutside() || Qualified1.IsUnqualified()) ||
108 !(Qualified2.IsEnclosed() || Qualified2.IsEnclosing() ||
109 Qualified2.IsOutside() || Qualified2.IsUnqualified())) {
110 GccEnt_BadQualifier::Raise();
113 TheCurve Cu1 = Qualified1.Qualified();
114 TheCurve Cu2 = Qualified2.Qualified();
115 GccIter_FuncTCuCu Func(Cu1,Cu2);
116 math_Vector Umin(1,2);
117 math_Vector Umax(1,2);
118 math_Vector Ufirst(1,2);
119 math_Vector tol(1,2);
120 Umin(1) = TheCurveTool::FirstParameter(Cu1);
121 Umin(2) = TheCurveTool::FirstParameter(Cu2);
122 Umax(1) = TheCurveTool::LastParameter(Cu1);
123 Umax(2) = TheCurveTool::LastParameter(Cu2);
126 tol(1) = TheCurveTool::EpsX(Cu1,Abs(Tolang));
127 tol(2) = TheCurveTool::EpsX(Cu2,Abs(Tolang));
128 math_FunctionSetRoot Root(Func,Ufirst,tol,Umin,Umax);
131 // Modified by Sergey KHROMOV - Thu Apr 5 17:45:00 2001 Begin
132 math_Vector Norm(1,2);
133 Func.Value(Ufirst, Norm);
134 if (Abs(Norm(1)) < Tolang && Abs(Norm(2)) < Tolang) {
135 // Modified by Sergey KHROMOV - Thu Apr 5 17:45:01 2001 End
136 gp_Pnt2d point1,point2;
137 gp_Vec2d Vect11,Vect12,Vect21,Vect22;
138 TheCurveTool::D2(Cu1,Ufirst(1),point1,Vect11,Vect12);
139 TheCurveTool::D2(Cu2,Ufirst(2),point2,Vect21,Vect22);
140 gp_Vec2d Vec(point1.XY(),point2.XY());
141 Standard_Real Angle1 = Vec.Angle(Vect12);
142 Standard_Real sign1 = Vect11.Dot(Vec);
143 if (Qualified1.IsUnqualified() ||
144 (Qualified1.IsEnclosing() && Angle1 >= 0.) ||
145 (Qualified1.IsOutside() && Angle1 <= 0. && sign1 <= 0.) ||
146 (Qualified1.IsEnclosed() && Angle1 <= 0. && sign1 >= 0.)) {
147 Angle1 = Vec.Angle(Vect22);
148 sign1 = Vect21.Dot(Vec);
149 if (Qualified2.IsUnqualified() ||
150 (Qualified2.IsEnclosing() && Angle1 >= 0.) ||
151 (Qualified2.IsOutside() && Angle1 <= 0. && sign1 <= 0.) ||
152 (Qualified2.IsEnclosed() && Angle1 <= 0. && sign1 >= 0.)) {
153 qualifier1 = Qualified1.Qualifier();
154 qualifier2 = Qualified2.Qualifier();
160 par2sol = pnttg2sol.Distance(pnttg1sol);
161 gp_Dir2d dir(pnttg2sol.X()-pnttg1sol.X(),pnttg2sol.Y()-pnttg1sol.Y());
162 linsol = gp_Lin2d(pnttg1sol,dir);
163 WellDone = Standard_True;
171 GccIter_Lin2d2Tan (const TheQualifiedCurve& Qualified1 ,
172 const gp_Pnt2d& ThePoint ,
173 const Standard_Real Param1 ,
174 const Standard_Real Tolang ) {
178 WellDone = Standard_False;
179 if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() ||
180 Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
181 GccEnt_BadQualifier::Raise();
184 TheCurve Cu1 = Qualified1.Qualified();
185 Standard_Real U1 = TheCurveTool::FirstParameter(Cu1);
186 Standard_Real U2 = TheCurveTool::LastParameter(Cu1);
187 GccIter_FuncTCuPt func(Cu1,ThePoint);
188 math_FunctionRoot sol(func,Param1,TheCurveTool::EpsX(Cu1,Abs(Tolang)),U1,U2,100);
190 Standard_Real Usol = sol.Root();
191 // Modified by Sergey KHROMOV - Thu Apr 5 17:45:17 2001 Begin
193 func.Value(Usol, Norm);
194 if (Abs(Norm) < Tolang) {
195 // Modified by Sergey KHROMOV - Thu Apr 5 17:45:19 2001 End
199 TheCurveTool::D2(Cu1,Usol,Origine,Vect1,Vect2);
200 gp_Vec2d Vdir(ThePoint.XY()-Origine.XY());
201 Standard_Real sign1 = Vect1.Dot(Vdir);
202 Standard_Real sign2 = Vect2.Crossed(Vdir);
203 if (Qualified1.IsUnqualified() ||
204 (Qualified1.IsEnclosing() &&
205 ((sign1 >= 0. && sign2 <= 0.) || (sign1 <= 0. && sign2 <= 0.))) ||
206 (Qualified1.IsOutside() && sign1 <= 0. && sign2 >= 0.) ||
207 (Qualified1.IsEnclosed() && sign1 >= 0. && sign2 >= 0.)) {
208 WellDone = Standard_True;
209 linsol = gp_Lin2d(Origine,gp_Dir2d(Vdir));
210 qualifier1 = Qualified1.Qualifier();
211 qualifier2 = GccEnt_noqualifier;
213 pnttg2sol = ThePoint;
216 pararg2 = ThePoint.Distance(Origine);
223 Standard_Boolean GccIter_Lin2d2Tan::
224 IsDone () const { return WellDone; }
226 gp_Lin2d GccIter_Lin2d2Tan::
227 ThisSolution () const
229 if (!WellDone) StdFail_NotDone::Raise();
233 void GccIter_Lin2d2Tan::
234 WhichQualifier (GccEnt_Position& Qualif1 ,
235 GccEnt_Position& Qualif2 ) const
237 if (!WellDone) { StdFail_NotDone::Raise(); }
239 Qualif1 = qualifier1;
240 Qualif2 = qualifier2;
244 void GccIter_Lin2d2Tan::
245 Tangency1 (Standard_Real& ParSol ,
246 Standard_Real& ParArg ,
247 gp_Pnt2d& Pnt) const {
248 if (!WellDone) { StdFail_NotDone::Raise(); }
256 void GccIter_Lin2d2Tan::
257 Tangency2 (Standard_Real& ParSol ,
258 Standard_Real& ParArg ,
259 gp_Pnt2d& Pnt) const {
260 if (!WellDone) { StdFail_NotDone::Raise(); }