1 // Created on: 1992-01-02
2 // Created by: Remi GILET
3 // Copyright (c) 1992-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.
19 #include <GccAna_Circ2d2TanOn.hxx>
20 #include <GccAna_Lin2dBisec.hxx>
21 #include <GccEnt_BadQualifier.hxx>
22 #include <GccEnt_QualifiedCirc.hxx>
23 #include <GccEnt_QualifiedLin.hxx>
25 #include <gp_Ax2d.hxx>
26 #include <gp_Circ2d.hxx>
27 #include <gp_Dir2d.hxx>
28 #include <gp_Lin2d.hxx>
29 #include <gp_Pnt2d.hxx>
30 #include <IntAna2d_AnaIntersection.hxx>
31 #include <IntAna2d_IntPoint.hxx>
32 #include <Standard_OutOfRange.hxx>
33 #include <StdFail_NotDone.hxx>
36 GccAna_Circ2d2TanOn (const GccEnt_QualifiedLin& Qualified1 ,
37 const GccEnt_QualifiedLin& Qualified2 ,
38 const gp_Circ2d& OnCirc ,
39 const Standard_Real ):
56 WellDone = Standard_False;
60 if (!(Qualified1.IsEnclosed() ||
61 Qualified1.IsOutside() || Qualified1.IsUnqualified()) ||
62 !(Qualified2.IsEnclosed() ||
63 Qualified2.IsOutside() || Qualified2.IsUnqualified())) {
64 throw GccEnt_BadQualifier();
67 gp_Lin2d L1(Qualified1.Qualified());
68 gp_Lin2d L2(Qualified2.Qualified());
69 GccAna_Lin2dBisec Bis(L1,L2);
70 Standard_Integer i=0,j=0;
71 Standard_Integer nbsol = 0;
72 Standard_Real sgn = 1.;
74 Standard_Boolean ok = Standard_False;
75 gp_Dir2d D1(L1.Direction());
76 gp_Dir2d D2(L2.Direction());
77 gp_Dir2d Dnor1(-D1.Y(),D1.X());
78 gp_Dir2d Dnor2(-D2.Y(),D2.X());
79 gp_XY XYnor1(-D1.Y(),D1.X());
80 gp_XY XYnor2(-D2.Y(),D2.X());
81 gp_Pnt2d originL1(L1.Location());
82 gp_Pnt2d originL2(L2.Location());
83 gp_XY Dloc(originL1.XY()-originL2.XY());
84 if (D1.Angle(D2) <= gp::Resolution()) {
85 if (Qualified1.IsEnclosed()) {
86 if (Dloc.Dot(XYnor1) <= 0.) { ok = Standard_True; }
87 else { ok = Standard_False; }
89 else if (Qualified1.IsOutside()) {
90 if (Dloc.Dot(XYnor1) >= 0.) { ok = Standard_True; }
91 else { ok = Standard_False; }
93 else {ok = Standard_True; }
94 if (Qualified2.IsEnclosed()) {
95 if (Dloc.Dot(XYnor2) >= 0.) { ok = Standard_True; }
96 else { ok = Standard_False; }
98 else if (Qualified2.IsOutside()) {
99 if (Dloc.Dot(XYnor2) <= 0.) { ok = Standard_True; }
100 else { ok = Standard_False; }
102 else {ok = Standard_True; }
104 IntAna2d_AnaIntersection Intp(Bis.ThisSolution(1),OnCirc);
106 WellDone = Standard_True;
107 if (!Intp.IsEmpty()) {
108 for (Standard_Integer l = 1 ; l <= Intp.NbPoints() ; l++) {
110 gp_Pnt2d pt(Intp.Point(l).Value());
111 gp_Ax2d axe(pt,dirx);
112 cirsol(NbrSol) = gp_Circ2d(axe,L1.Distance(pt));
113 // ===============================================
114 gp_Dir2d dc1(originL1.XY()-pt.XY());
115 gp_Dir2d dc2(originL2.XY()-pt.XY());
116 if (!Qualified1.IsUnqualified()) {
117 qualifier1(NbrSol) = Qualified1.Qualifier();
119 else if (dc1.Dot(Dnor1) > 0.0) {
120 qualifier1(NbrSol) = GccEnt_outside;
122 else { qualifier1(NbrSol) = GccEnt_enclosed; }
123 if (!Qualified2.IsUnqualified()) {
124 qualifier2(NbrSol) = Qualified2.Qualifier();
126 else if (dc2.Dot(Dnor2) > 0.0) {
127 qualifier2(NbrSol) = GccEnt_outside;
129 else { qualifier2(NbrSol) = GccEnt_enclosed; }
135 else if (Qualified1.IsEnclosed() && Qualified2.IsEnclosed()) {
136 //============================================================
138 if (Bis.NbSolutions() == 2) {
146 else if (Qualified1.IsEnclosed() && Qualified2.IsOutside()) {
147 //===========================================================
149 if (Bis.NbSolutions() >= 1) {
153 if (D1.Angle(D2) >= 0.0) { sgn = -1.; }
157 else if (Qualified1.IsOutside() && Qualified2.IsEnclosed()) {
158 //===========================================================
160 if (Bis.NbSolutions() >= 1) {
164 if (D1.Angle(D2) <= 0.0) { sgn = -1.; }
168 else if (Qualified1.IsOutside() && Qualified2.IsOutside()) {
169 //==========================================================
171 if (Bis.NbSolutions() >= 1) {
178 else if (Qualified1.IsUnqualified() && Qualified2.IsEnclosed()) {
179 //=============================================================
182 if (Bis.NbSolutions() >= 1) {
186 if (D1.Angle(D2) >= 0.0) { s = -1.; }
190 else if (Qualified1.IsUnqualified() && Qualified2.IsOutside()) {
191 //==============================================================
194 if (Bis.NbSolutions() >= 1) {
198 if (D1.Angle(D2) >= 0.0) {
204 else if (Qualified1.IsEnclosed() && Qualified2.IsUnqualified()) {
205 //===============================================================
208 if (Bis.NbSolutions() >= 1) {
212 if (D1.Angle(D2) >= 0.0) { sgn = -1.; }
216 else if (Qualified1.IsOutside() && Qualified2.IsUnqualified()) {
217 //==============================================================
220 if (Bis.NbSolutions() >= 1) {
224 if (D1.Angle(D2) <= 0.0) {
230 else if (Qualified1.IsUnqualified() && Qualified2.IsUnqualified()) {
231 //==================================================================
238 Standard_Integer kk = 0;
239 for (Standard_Integer k = i ; k <= i+j-1 ; k++) {
241 IntAna2d_AnaIntersection Intp(Bis.ThisSolution(k),OnCirc);
243 if (!Intp.IsEmpty()) {
244 for (Standard_Integer l = 1 ; l <= Intp.NbPoints() ; l++) {
245 gp_Vec2d V(Intp.Point(l).Value(),
246 Bis.ThisSolution(k).Location());
247 if ((kk==1 && sgn*V.Dot(Bis.ThisSolution(k).Direction())>=0.0)||
248 (kk==2 && sgn*s*V.Dot(Bis.ThisSolution(k).Direction())>=0.0)
251 gp_Pnt2d pt(Intp.Point(i).Value());
252 gp_Ax2d axe(pt,dirx);
253 cirsol(NbrSol) = gp_Circ2d(axe,
254 // ===============================
255 L1.Distance(Intp.Point(l).Value()));
256 // ===================================
257 gp_Dir2d dc1(originL1.XY()-pt.XY());
258 gp_Dir2d dc2(originL2.XY()-pt.XY());
259 if (!Qualified1.IsUnqualified()) {
260 qualifier1(NbrSol) = Qualified1.Qualifier();
262 else if (dc1.Dot(Dnor1) > 0.0) {
263 qualifier1(NbrSol) = GccEnt_outside;
265 else { qualifier1(NbrSol) = GccEnt_enclosed; }
266 if (!Qualified2.IsUnqualified()) {
267 qualifier2(NbrSol) = Qualified2.Qualifier();
269 else if (dc2.Dot(Dnor2) > 0.0) {
270 qualifier2(NbrSol) = GccEnt_outside;
272 else { qualifier2(NbrSol) = GccEnt_enclosed; }
276 WellDone = Standard_True;
282 for (i =1 ; i <= NbrSol ; i++) {
283 gp_Pnt2d pbid(cirsol(i).Location());
284 Standard_Real Radius = cirsol(i).Radius();
285 gp_Dir2d dc2(originL1.XY()-pbid.XY());
286 Standard_Real sign = dc2.Dot(gp_Dir2d(-L1.Direction().Y(),
287 L1.Direction().X()));
288 dc2 = gp_Dir2d(sign*gp_XY(-L1.Direction().Y(),L1.Direction().X()));
289 pnttg1sol(i) = gp_Pnt2d(pbid.XY()+Radius*dc2.XY());
290 dc2 = gp_Dir2d(originL2.XY()-pbid.XY());
291 sign = dc2.Dot(gp_Dir2d(-L2.Direction().Y(),L2.Direction().X()));
292 dc2 = gp_Dir2d(sign*gp_XY(-L2.Direction().Y(),L2.Direction().X()));
293 pnttg2sol(i) = gp_Pnt2d(pbid.XY()+Radius*dc2.XY());
295 par1sol(i)=ElCLib::Parameter(cirsol(i),pnttg1sol(i));
296 pararg1(i)=ElCLib::Parameter(L1,pnttg1sol(i));
297 par2sol(i)=ElCLib::Parameter(cirsol(i),pnttg2sol(i));
298 pararg2(i)=ElCLib::Parameter(L2,pnttg2sol(i));
299 parcen3(i)=ElCLib::Parameter(OnCirc,pntcen(i));