Commit | Line | Data |
---|---|---|
7fd59977 | 1 | // File GccAna_Circ2d3Tan.cxx_5, REG 08/07/91 |
2 | // init. de MinRad et MaxRad (PRO15604), JCT 09/10/98 | |
3 | ||
4 | #include <GccAna_Circ2d3Tan.jxx> | |
5 | ||
6 | #include <ElCLib.hxx> | |
7 | #include <IntAna2d_AnaIntersection.hxx> | |
8 | #include <IntAna2d_IntPoint.hxx> | |
9 | #include <gp_Lin2d.hxx> | |
10 | #include <gp_Circ2d.hxx> | |
11 | #include <gp_Dir2d.hxx> | |
12 | #include <TColStd_Array1OfReal.hxx> | |
13 | #include <GccAna_CircLin2dBisec.hxx> | |
14 | #include <GccAna_LinPnt2dBisec.hxx> | |
15 | #include <GccInt_IType.hxx> | |
16 | #include <GccInt_BLine.hxx> | |
17 | #include <GccInt_BParab.hxx> | |
18 | #include <IntAna2d_Conic.hxx> | |
19 | #include <GccEnt_BadQualifier.hxx> | |
20 | ||
0d969553 Y |
21 | //=========================================================================== |
22 | // Creation of a circle tangent to a circle, a straight line and a point. + | |
23 | //=========================================================================== | |
7fd59977 | 24 | |
25 | GccAna_Circ2d3Tan:: | |
26 | GccAna_Circ2d3Tan (const GccEnt_QualifiedCirc& Qualified1 , | |
27 | const GccEnt_QualifiedLin& Qualified2 , | |
28 | const gp_Pnt2d& Point3 , | |
29 | const Standard_Real Tolerance ): | |
30 | ||
31 | //========================================================================= | |
0d969553 | 32 | // Initialization of fields. + |
7fd59977 | 33 | //========================================================================= |
34 | ||
35 | cirsol(1,4) , | |
36 | qualifier1(1,4) , | |
37 | qualifier2(1,4) , | |
38 | qualifier3(1,4) , | |
39 | TheSame1(1,4) , | |
40 | TheSame2(1,4) , | |
41 | TheSame3(1,4) , | |
42 | pnttg1sol(1,4) , | |
43 | pnttg2sol(1,4) , | |
44 | pnttg3sol(1,4) , | |
45 | par1sol(1,4) , | |
46 | par2sol(1,4) , | |
47 | par3sol(1,4) , | |
48 | pararg1(1,4) , | |
49 | pararg2(1,4) , | |
50 | pararg3(1,4) | |
51 | { | |
52 | ||
53 | gp_Dir2d dirx(1.0,0.0); | |
54 | Standard_Real Tol = Abs(Tolerance); | |
55 | Standard_Real MaxRad = 1e10, MinRad = 1e-6; | |
56 | WellDone = Standard_False; | |
57 | NbrSol = 0; | |
58 | if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() || | |
59 | Qualified1.IsOutside() || Qualified1.IsUnqualified()) || | |
60 | !(Qualified2.IsEnclosed() || | |
61 | Qualified2.IsOutside() || Qualified2.IsUnqualified())) { | |
62 | GccEnt_BadQualifier::Raise(); | |
63 | return; | |
64 | } | |
65 | ||
66 | //========================================================================= | |
0d969553 | 67 | // Processing. + |
7fd59977 | 68 | //========================================================================= |
69 | ||
70 | gp_Circ2d C1(Qualified1.Qualified()); | |
71 | gp_Lin2d L2(Qualified2.Qualified()); | |
72 | Standard_Real R1 = C1.Radius(); | |
73 | gp_Pnt2d center1(C1.Location()); | |
74 | gp_Pnt2d origin2(L2.Location()); | |
75 | gp_Dir2d dir2(L2.Direction()); | |
76 | gp_Dir2d normL2(-dir2.Y(),dir2.X()); | |
77 | ||
78 | TColStd_Array1OfReal Radius(1,2); | |
79 | GccAna_CircLin2dBisec Bis1(C1,L2); | |
80 | GccAna_LinPnt2dBisec Bis2(L2,Point3); | |
81 | if (Bis1.IsDone() && Bis2.IsDone()) { | |
82 | Standard_Integer nbsolution1 = Bis1.NbSolutions(); | |
83 | for (Standard_Integer i = 1 ; i <= nbsolution1; i++) { | |
84 | Handle(GccInt_Bisec) Sol1 = Bis1.ThisSolution(i); | |
85 | Handle(GccInt_Bisec) Sol2 = Bis2.ThisSolution(); | |
86 | GccInt_IType typ1 = Sol1->ArcType(); | |
87 | GccInt_IType typ2 = Sol2->ArcType(); | |
88 | IntAna2d_AnaIntersection Intp; | |
89 | if (typ1 == GccInt_Lin) { | |
90 | if (typ2 == GccInt_Lin) { | |
91 | Intp.Perform(Sol1->Line(),Sol2->Line()); | |
92 | } | |
93 | else if (typ2 == GccInt_Par) { | |
94 | Intp.Perform(Sol1->Line(),IntAna2d_Conic(Sol2->Parabola())); | |
95 | } | |
96 | } | |
97 | else if (typ1 == GccInt_Par) { | |
98 | if (typ2 == GccInt_Lin) { | |
99 | Intp.Perform(Sol2->Line(),IntAna2d_Conic(Sol1->Parabola())); | |
100 | } | |
101 | else if (typ2 == GccInt_Par) { | |
102 | Intp.Perform(Sol1->Parabola(),IntAna2d_Conic(Sol2->Parabola())); | |
103 | } | |
104 | } | |
105 | if (Intp.IsDone()) { | |
106 | if (!Intp.IsEmpty()) { | |
107 | for (Standard_Integer j = 1 ; j <= Intp.NbPoints() ; j++) { | |
108 | gp_Pnt2d Center(Intp.Point(j).Value()); | |
109 | Standard_Real dist1 = Center.Distance(C1.Location()); | |
110 | Standard_Real dist2 = L2.Distance(Center); | |
111 | Standard_Real dist3 = Center.Distance(Point3); | |
112 | Standard_Integer nbsol1 = 0; | |
113 | Standard_Integer nbsol2 = 0; | |
114 | Standard_Integer nbsol3 = 0; | |
115 | Standard_Boolean ok = Standard_False; | |
116 | if (Qualified1.IsEnclosed()) { | |
117 | if (dist1-R1 < Tolerance) { | |
118 | Radius(1) = Abs(R1-dist1); | |
119 | nbsol1 = 1; | |
120 | ok = Standard_True; | |
121 | } | |
122 | } | |
123 | else if (Qualified1.IsOutside()) { | |
124 | if (R1-dist1 < Tolerance) { | |
125 | Radius(1) = Abs(R1-dist1); | |
126 | nbsol1 = 1; | |
127 | ok = Standard_True; | |
128 | } | |
129 | } | |
130 | else if (Qualified1.IsEnclosing()) { | |
131 | ok = Standard_True; | |
132 | nbsol1 = 1; | |
133 | Radius(1) = Abs(R1-dist1); | |
134 | } | |
135 | else if (Qualified1.IsUnqualified()) { | |
136 | ok = Standard_True; | |
137 | nbsol1 = 2; | |
138 | Radius(1) = Abs(R1-dist1); | |
139 | Radius(2) = R1+dist1; | |
140 | } | |
141 | if (Qualified2.IsEnclosed() && ok) { | |
142 | if ((((L2.Location().X()-Center.X())*(-L2.Direction().Y()))+ | |
143 | ((L2.Location().Y()-Center.Y())*(L2.Direction().X())))<=0){ | |
144 | for (Standard_Integer ii = 1 ; ii <= nbsol1 ; ii++) { | |
145 | if (Abs(dist2-Radius(ii)) < Tol) { | |
146 | ok = Standard_True; | |
147 | nbsol2 = 1; | |
148 | Radius(1) = Radius(ii); | |
149 | } | |
150 | } | |
151 | } | |
152 | } | |
153 | else if (Qualified2.IsOutside() && ok) { | |
154 | if ((((L2.Location().X()-Center.X())*(-L2.Direction().Y()))+ | |
155 | ((L2.Location().Y()-Center.Y())*(L2.Direction().X())))>=0){ | |
156 | for (Standard_Integer ii = 1 ; ii <= nbsol1 ; ii++) { | |
157 | if (Abs(dist2-Radius(ii)) < Tol) { | |
158 | ok = Standard_True; | |
159 | nbsol2 = 1; | |
160 | Radius(1) = Radius(ii); | |
161 | } | |
162 | } | |
163 | } | |
164 | } | |
165 | else if (Qualified2.IsUnqualified() && ok) { | |
166 | for (Standard_Integer ii = 1 ; ii <= nbsol1 ; ii++) { | |
167 | if (Abs(dist2-Radius(ii)) < Tol) { | |
168 | ok = Standard_True; | |
169 | nbsol2 = 1; | |
170 | Radius(1) = Radius(ii); | |
171 | } | |
172 | } | |
173 | } | |
174 | if (Abs(dist3-Radius(1)) <= Tol && ok) { | |
175 | ok = Standard_True; | |
176 | nbsol3 = 1; | |
177 | } | |
178 | if (ok) { | |
179 | for (Standard_Integer k = 1 ; k <= nbsol3 ; k++) { | |
180 | if (NbrSol==4) | |
181 | break; | |
0d969553 | 182 | // pop : if the radius is too great - no creation |
7fd59977 | 183 | if (Radius(k) > MaxRad) break; |
184 | if (Abs(Radius(k)) < MinRad) break; | |
185 | ||
186 | NbrSol++; | |
187 | cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius(k)); | |
188 | // ========================================================== | |
189 | Standard_Real distcc1 = Center.Distance(center1); | |
190 | if (!Qualified1.IsUnqualified()) { | |
191 | qualifier1(NbrSol) = Qualified1.Qualifier(); | |
192 | } | |
193 | else if (Abs(distcc1+Radius(k)-R1) < Tol) { | |
194 | qualifier1(NbrSol) = GccEnt_enclosed; | |
195 | } | |
196 | else if (Abs(distcc1-R1-Radius(k)) < Tol) { | |
197 | qualifier1(NbrSol) = GccEnt_outside; | |
198 | } | |
199 | else { qualifier1(NbrSol) = GccEnt_enclosing; } | |
200 | gp_Dir2d dc2(origin2.XY()-Center.XY()); | |
201 | if (!Qualified2.IsUnqualified()) { | |
202 | qualifier2(NbrSol) = Qualified2.Qualifier(); | |
203 | } | |
204 | else if (dc2.Dot(normL2) > 0.0) { | |
205 | qualifier2(NbrSol) = GccEnt_outside; | |
206 | } | |
207 | else { qualifier2(NbrSol) = GccEnt_enclosed; } | |
208 | qualifier3(NbrSol) = GccEnt_noqualifier; | |
209 | if (Center.Distance(C1.Location()) <= Tolerance && | |
210 | Abs(Radius(k)-R1) <= Tolerance) { | |
211 | TheSame1(NbrSol) = 1; | |
212 | } | |
213 | else { | |
214 | TheSame1(NbrSol) = 0; | |
215 | // modified by NIZHNY-EAP Mon Nov 1 13:48:21 1999 ___BEGIN___ | |
216 | // gp_Dir2d dc(C1.Location().XY()-Center.XY()); | |
217 | gp_Dir2d dc(Center.XY()-C1.Location().XY()); | |
218 | // modified by NIZHNY-EAP Mon Nov 1 13:48:55 1999 ___END___ | |
219 | pnttg1sol(NbrSol)=gp_Pnt2d(Center.XY()+Radius(k)*dc.XY()); | |
220 | par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol), | |
221 | pnttg1sol(NbrSol)); | |
222 | pararg1(NbrSol)=ElCLib::Parameter(C1,pnttg1sol(NbrSol)); | |
223 | } | |
224 | TheSame2(NbrSol) = 0; | |
225 | TheSame3(NbrSol) = 0; | |
226 | gp_Dir2d dc(L2.Location().XY()-Center.XY()); | |
227 | Standard_Real sign = dc.Dot(gp_Dir2d(-L2.Direction().Y(), | |
228 | L2.Direction().X())); | |
229 | dc = gp_Dir2d(sign*gp_XY(-L2.Direction().Y(), | |
230 | L2.Direction().X())); | |
231 | pnttg2sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius(k)*dc.XY()); | |
232 | par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol), | |
233 | pnttg2sol(NbrSol)); | |
234 | pararg2(NbrSol)=ElCLib::Parameter(L2,pnttg2sol(NbrSol)); | |
235 | pnttg3sol(NbrSol) = Point3; | |
236 | par3sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol), | |
237 | pnttg3sol(NbrSol)); | |
238 | pararg3(NbrSol) = 0.; | |
239 | } | |
240 | } | |
241 | } | |
242 | } | |
243 | WellDone = Standard_True; | |
244 | } | |
245 | if (NbrSol==4) | |
246 | break; | |
247 | } | |
248 | } | |
249 | } |