1 // Created on: 1991-12-20
2 // Created by: Remi GILET
3 // Copyright (c) 1991-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 //========================================================================
18 // CREATION D UNE LIGNE TANGENTE A DEUX COURBES. +
19 //========================================================================
21 #include <GccEnt_BadQualifier.hxx>
22 #include <GccEnt_QualifiedCirc.hxx>
23 #include <Geom2dGcc_CurveTool.hxx>
24 #include <Geom2dGcc_FunctionTanCirCu.hxx>
25 #include <Geom2dGcc_FunctionTanCuCu.hxx>
26 #include <Geom2dGcc_FunctionTanCuPnt.hxx>
27 #include <Geom2dGcc_Lin2d2TanIter.hxx>
28 #include <Geom2dGcc_QCurve.hxx>
29 #include <gp_Circ2d.hxx>
30 #include <gp_Dir2d.hxx>
31 #include <gp_Lin2d.hxx>
32 #include <gp_Pnt2d.hxx>
33 #include <gp_Vec2d.hxx>
35 #include <math_FunctionRoot.hxx>
36 #include <math_FunctionSetRoot.hxx>
37 #include <math_Matrix.hxx>
38 #include <math_Vector.hxx>
39 #include <StdFail_NotDone.hxx>
41 Geom2dGcc_Lin2d2TanIter::
42 Geom2dGcc_Lin2d2TanIter (const GccEnt_QualifiedCirc& Qualified1 ,
43 const Geom2dGcc_QCurve& Qualified2 ,
44 const Standard_Real Param2 ,
45 const Standard_Real Tolang ) {
51 //Standard_Real Tol = Abs(Tolang);
53 WellDone = Standard_False;
54 qualifier1 = GccEnt_noqualifier;
55 qualifier2 = GccEnt_noqualifier;
56 if (Qualified1.IsEnclosed()) { throw GccEnt_BadQualifier(); }
57 gp_Circ2d C1 = Qualified1.Qualified();
58 Geom2dAdaptor_Curve Cu2 = Qualified2.Qualified();
59 Standard_Real U1 = Geom2dGcc_CurveTool::FirstParameter(Cu2);
60 Standard_Real U2 = Geom2dGcc_CurveTool::LastParameter(Cu2);
61 Geom2dGcc_FunctionTanCirCu func(C1,Cu2);
62 math_FunctionRoot sol(func,Param2,Geom2dGcc_CurveTool::EpsX(Cu2,Abs(Tolang)),U1,U2,100);
64 Standard_Real Usol = sol.Root();
65 // gp_Pnt2d Origine,Pt;
66 // Modified by Sergey KHROMOV - Thu Apr 5 17:39:47 2001 Begin
68 func.Value(Usol, Norm);
69 if (Abs(Norm) < Tolang) {
70 // Modified by Sergey KHROMOV - Thu Apr 5 17:39:48 2001 End
74 Geom2dGcc_CurveTool::D2(Cu2,Usol,Origine,Vect1,Vect2);
75 gp_Vec2d Vdir(C1.Location().XY() - Origine.XY());
76 Standard_Real sign1 = Vect1.Dot(Vdir);
77 if (sign1 <= 0. ) { Vect1.Reverse(); }
78 Standard_Real sign2 = Vect2.Crossed(Vect1);
79 if (Qualified2.IsUnqualified() ||
80 (Qualified2.IsEnclosing() && sign2<=0.) ||
81 (Qualified2.IsOutside() && sign1 <= 0. && sign2 >= 0.) ||
82 (Qualified2.IsEnclosed() && sign1 >= 0. && sign2 >= 0.)) {
83 if (Qualified1.IsUnqualified() ||
84 (Qualified1.IsOutside() && Vect1.Angle(Vdir) <= 0.) ||
85 (Qualified1.IsEnclosing() && Vect1.Angle(Vdir) >= 0.)) {
86 gp_Dir2d direc(Vect1);
87 Standard_Real R1 = C1.Radius();
88 gp_XY normal(-R1*direc.Y(),R1*direc.X());
89 sign1 = Vect1.Crossed(Vdir);
90 if (Qualified1.IsEnclosing()) {
91 pnttg1sol = gp_Pnt2d(C1.Location().XY()-normal);
93 else if (Qualified1.IsOutside()) {
94 pnttg1sol = gp_Pnt2d(C1.Location().XY()+normal);
98 pnttg1sol = gp_Pnt2d(C1.Location().XY()-normal);
101 pnttg1sol = gp_Pnt2d(C1.Location().XY()+normal);
104 // if (gp_Vec2d(direc.XY()).Angle(gp_Vec2d(pnttg1sol,Origine)) <= Tol) {
106 linsol = gp_Lin2d(pnttg1sol,direc);
107 WellDone = Standard_True;
108 qualifier1 = Qualified1.Qualifier();
109 qualifier2 = Qualified2.Qualifier();
112 par2sol = pnttg2sol.Distance(pnttg1sol);
120 Geom2dGcc_Lin2d2TanIter::
121 Geom2dGcc_Lin2d2TanIter (const Geom2dGcc_QCurve& Qualified1 ,
122 const Geom2dGcc_QCurve& Qualified2 ,
123 const Standard_Real Param1 ,
124 const Standard_Real Param2 ,
125 const Standard_Real Tolang ) {
130 WellDone = Standard_False;
131 qualifier1 = GccEnt_noqualifier;
132 qualifier2 = GccEnt_noqualifier;
133 if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() ||
134 Qualified1.IsOutside() || Qualified1.IsUnqualified()) ||
135 !(Qualified2.IsEnclosed() || Qualified2.IsEnclosing() ||
136 Qualified2.IsOutside() || Qualified2.IsUnqualified())) {
137 throw GccEnt_BadQualifier();
140 Geom2dAdaptor_Curve Cu1 = Qualified1.Qualified();
141 Geom2dAdaptor_Curve Cu2 = Qualified2.Qualified();
142 Geom2dGcc_FunctionTanCuCu Func(Cu1,Cu2);
143 math_Vector Umin(1,2);
144 math_Vector Umax(1,2);
145 math_Vector Ufirst(1,2);
146 math_Vector tol(1,2);
147 Umin(1) = Geom2dGcc_CurveTool::FirstParameter(Cu1);
148 Umin(2) = Geom2dGcc_CurveTool::FirstParameter(Cu2);
149 Umax(1) = Geom2dGcc_CurveTool::LastParameter(Cu1);
150 Umax(2) = Geom2dGcc_CurveTool::LastParameter(Cu2);
153 tol(1) = Geom2dGcc_CurveTool::EpsX(Cu1,Abs(Tolang));
154 tol(2) = Geom2dGcc_CurveTool::EpsX(Cu2,Abs(Tolang));
155 math_FunctionSetRoot Root(Func, tol);
156 Root.Perform(Func, Ufirst, Umin, Umax);
159 // Modified by Sergey KHROMOV - Thu Apr 5 17:45:00 2001 Begin
160 math_Vector Norm(1,2);
161 Func.Value(Ufirst, Norm);
162 if (Abs(Norm(1)) < Tolang && Abs(Norm(2)) < Tolang) {
163 // Modified by Sergey KHROMOV - Thu Apr 5 17:45:01 2001 End
164 gp_Pnt2d point1,point2;
165 gp_Vec2d Vect11,Vect12,Vect21,Vect22;
166 Geom2dGcc_CurveTool::D2(Cu1,Ufirst(1),point1,Vect11,Vect12);
167 Geom2dGcc_CurveTool::D2(Cu2,Ufirst(2),point2,Vect21,Vect22);
168 gp_Vec2d Vec(point1.XY(),point2.XY());
169 Standard_Real Angle1 = Vec.Angle(Vect12);
170 Standard_Real sign1 = Vect11.Dot(Vec);
171 if (Qualified1.IsUnqualified() ||
172 (Qualified1.IsEnclosing() && Angle1 >= 0.) ||
173 (Qualified1.IsOutside() && Angle1 <= 0. && sign1 <= 0.) ||
174 (Qualified1.IsEnclosed() && Angle1 <= 0. && sign1 >= 0.)) {
175 Angle1 = Vec.Angle(Vect22);
176 sign1 = Vect21.Dot(Vec);
177 if (Qualified2.IsUnqualified() ||
178 (Qualified2.IsEnclosing() && Angle1 >= 0.) ||
179 (Qualified2.IsOutside() && Angle1 <= 0. && sign1 <= 0.) ||
180 (Qualified2.IsEnclosed() && Angle1 <= 0. && sign1 >= 0.)) {
181 qualifier1 = Qualified1.Qualifier();
182 qualifier2 = Qualified2.Qualifier();
188 par2sol = pnttg2sol.Distance(pnttg1sol);
189 gp_Dir2d dir(pnttg2sol.X()-pnttg1sol.X(),pnttg2sol.Y()-pnttg1sol.Y());
190 linsol = gp_Lin2d(pnttg1sol,dir);
191 WellDone = Standard_True;
198 Geom2dGcc_Lin2d2TanIter::
199 Geom2dGcc_Lin2d2TanIter (const Geom2dGcc_QCurve& Qualified1 ,
200 const gp_Pnt2d& ThePoint ,
201 const Standard_Real Param1 ,
202 const Standard_Real Tolang ) {
208 WellDone = Standard_False;
209 qualifier1 = GccEnt_noqualifier;
210 qualifier2 = GccEnt_noqualifier;
211 if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() ||
212 Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
213 throw GccEnt_BadQualifier();
216 Geom2dAdaptor_Curve Cu1 = Qualified1.Qualified();
217 Standard_Real U1 = Geom2dGcc_CurveTool::FirstParameter(Cu1);
218 Standard_Real U2 = Geom2dGcc_CurveTool::LastParameter(Cu1);
219 Geom2dGcc_FunctionTanCuPnt func(Cu1,ThePoint);
220 math_FunctionRoot sol(func,Param1,Geom2dGcc_CurveTool::EpsX(Cu1,Abs(Tolang)),U1,U2,100);
222 Standard_Real Usol = sol.Root();
223 // Modified by Sergey KHROMOV - Thu Apr 5 17:45:17 2001 Begin
225 func.Value(Usol, Norm);
226 if (Abs(Norm) < Tolang) {
227 // Modified by Sergey KHROMOV - Thu Apr 5 17:45:19 2001 End
231 Geom2dGcc_CurveTool::D2(Cu1,Usol,Origine,Vect1,Vect2);
232 gp_Vec2d Vdir(ThePoint.XY()-Origine.XY());
233 Standard_Real sign1 = Vect1.Dot(Vdir);
234 Standard_Real sign2 = Vect2.Crossed(Vdir);
235 if (Qualified1.IsUnqualified() ||
236 (Qualified1.IsEnclosing() &&
237 ((sign1 >= 0. && sign2 <= 0.) || (sign1 <= 0. && sign2 <= 0.))) ||
238 (Qualified1.IsOutside() && sign1 <= 0. && sign2 >= 0.) ||
239 (Qualified1.IsEnclosed() && sign1 >= 0. && sign2 >= 0.)) {
240 WellDone = Standard_True;
241 linsol = gp_Lin2d(Origine,gp_Dir2d(Vdir));
242 qualifier1 = Qualified1.Qualifier();
243 qualifier2 = GccEnt_noqualifier;
245 pnttg2sol = ThePoint;
248 pararg2 = ThePoint.Distance(Origine);
255 Standard_Boolean Geom2dGcc_Lin2d2TanIter::
256 IsDone () const { return WellDone; }
258 gp_Lin2d Geom2dGcc_Lin2d2TanIter::
259 ThisSolution () const
261 if (!WellDone) throw StdFail_NotDone();
265 void Geom2dGcc_Lin2d2TanIter::
266 WhichQualifier (GccEnt_Position& Qualif1 ,
267 GccEnt_Position& Qualif2 ) const
269 if (!WellDone) { throw StdFail_NotDone(); }
271 Qualif1 = qualifier1;
272 Qualif2 = qualifier2;
276 void Geom2dGcc_Lin2d2TanIter::
277 Tangency1 (Standard_Real& ParSol ,
278 Standard_Real& ParArg ,
279 gp_Pnt2d& Pnt) const {
280 if (!WellDone) { throw StdFail_NotDone(); }
288 void Geom2dGcc_Lin2d2TanIter::
289 Tangency2 (Standard_Real& ParSol ,
290 Standard_Real& ParArg ,
291 gp_Pnt2d& Pnt) const {
292 if (!WellDone) { throw StdFail_NotDone(); }