Commit | Line | Data |
---|---|---|
7fd59977 | 1 | // File: GccAna_Circ2d2TanOn_1.cxx |
2 | // Created: Thu Jan 2 15:50:43 1992 | |
3 | // Author: Remi GILET | |
4 | // <reg@topsn3> | |
5 | ||
6 | #include <GccAna_Circ2d2TanOn.jxx> | |
7 | ||
8 | #include <ElCLib.hxx> | |
9 | #include <gp_Dir2d.hxx> | |
10 | #include <gp_Ax2d.hxx> | |
11 | #include <IntAna2d_AnaIntersection.hxx> | |
12 | #include <IntAna2d_IntPoint.hxx> | |
13 | #include <GccAna_CircLin2dBisec.hxx> | |
14 | #include <GccInt_IType.hxx> | |
15 | #include <GccInt_BCirc.hxx> | |
16 | #include <IntAna2d_Conic.hxx> | |
17 | #include <GccEnt_BadQualifier.hxx> | |
18 | ||
19 | //========================================================================= | |
0d969553 Y |
20 | // Creation of a circle tangent to Circle C1 and a straight line L2. + |
21 | // centered on a straight line. + | |
22 | // We start by making difference between cases that we are going to + | |
23 | // proceess separately. + | |
24 | // In general case: + | |
7fd59977 | 25 | // ==================== + |
0d969553 Y |
26 | // We calculate bissectrices to C1 and L2 that give us + |
27 | // all possibles locations of centers of all circles tangent to C1 and L2+ + | |
28 | // We intersect these bissectrices with straight line OnLine which gives + | |
29 | // us points among which we'll choose the solutions. + | |
30 | // The choices are made basing on Qualifiers of C1 and L2. + | |
7fd59977 | 31 | //========================================================================= |
32 | ||
33 | GccAna_Circ2d2TanOn:: | |
34 | GccAna_Circ2d2TanOn (const GccEnt_QualifiedCirc& Qualified1 , | |
35 | const GccEnt_QualifiedLin& Qualified2 , | |
36 | const gp_Lin2d& OnLine , | |
37 | const Standard_Real Tolerance ): | |
38 | cirsol(1,4) , | |
39 | qualifier1(1,4) , | |
40 | qualifier2(1,4), | |
41 | TheSame1(1,4) , | |
42 | TheSame2(1,4) , | |
43 | pnttg1sol(1,4) , | |
44 | pnttg2sol(1,4) , | |
45 | pntcen(1,4) , | |
46 | par1sol(1,4) , | |
47 | par2sol(1,4) , | |
48 | pararg1(1,4) , | |
49 | pararg2(1,4) , | |
50 | parcen3(1,4) | |
51 | { | |
52 | ||
53 | TheSame1.Init(0); | |
54 | TheSame2.Init(0); | |
55 | WellDone = Standard_False; | |
56 | NbrSol = 0; | |
57 | if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() || | |
58 | Qualified1.IsOutside() || Qualified1.IsUnqualified()) || | |
59 | !(Qualified2.IsEnclosed() || | |
60 | Qualified2.IsOutside() || Qualified2.IsUnqualified())) { | |
61 | GccEnt_BadQualifier::Raise(); | |
62 | return; | |
63 | } | |
64 | Standard_Real Tol = Abs(Tolerance); | |
65 | Standard_Real Radius=0; | |
66 | Standard_Boolean ok = Standard_False; | |
67 | gp_Dir2d dirx(1.,0.); | |
68 | gp_Circ2d C1 = Qualified1.Qualified(); | |
69 | gp_Lin2d L2 = Qualified2.Qualified(); | |
70 | Standard_Real R1 = C1.Radius(); | |
71 | gp_Pnt2d center1(C1.Location()); | |
72 | gp_Pnt2d origin2(L2.Location()); | |
73 | gp_Dir2d dirL2(L2.Direction()); | |
74 | gp_Dir2d normL2(-dirL2.Y(),dirL2.X()); | |
75 | ||
76 | //========================================================================= | |
0d969553 | 77 | // Processing of limit cases. + |
7fd59977 | 78 | //========================================================================= |
79 | ||
80 | Standard_Real distcl = OnLine.Distance(center1); | |
81 | gp_Pnt2d pinterm(center1.XY()+distcl* | |
82 | gp_XY(-OnLine.Direction().Y(),OnLine.Direction().X())); | |
83 | if (OnLine.Distance(pinterm) > Tolerance) { | |
84 | pinterm = gp_Pnt2d(center1.XY()+distcl* | |
85 | gp_XY(-OnLine.Direction().Y(),OnLine.Direction().X())); | |
86 | } | |
87 | Standard_Real dist2 = L2.Distance(pinterm); | |
88 | if (Qualified1.IsEnclosed() || Qualified1.IsOutside()) { | |
89 | if (Abs(distcl-R1-dist2) <= Tol) { ok = Standard_True; } | |
90 | } | |
91 | else if (Qualified1.IsEnclosing()) { | |
92 | if (Abs(dist2-distcl-R1) <= Tol) { ok = Standard_True; } | |
93 | } | |
94 | else if (Qualified1.IsUnqualified()) { ok = Standard_True; } | |
95 | else { | |
96 | GccEnt_BadQualifier::Raise(); | |
97 | return; | |
98 | } | |
99 | if (ok) { | |
100 | if (Qualified2.IsOutside()) { | |
101 | gp_Pnt2d pbid(pinterm.XY()+dist2*gp_XY(-dirL2.Y(),dirL2.X())); | |
102 | if (L2.Distance(pbid) <= Tol) { WellDone = Standard_True; } | |
103 | } | |
104 | else if (Qualified2.IsEnclosed()) { | |
105 | gp_Pnt2d pbid(pinterm.XY()-dist2*gp_XY(-dirL2.Y(),dirL2.X())); | |
106 | if (L2.Distance(pbid) <= Tol) { WellDone = Standard_True; } | |
107 | } | |
108 | else if (Qualified2.IsUnqualified()) { WellDone = Standard_False; } | |
109 | else { | |
110 | GccEnt_BadQualifier::Raise(); | |
111 | return; | |
112 | } | |
113 | } | |
114 | if (WellDone) { | |
115 | NbrSol++; | |
116 | cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(pinterm,dirx),dist2); | |
117 | // ======================================================= | |
118 | gp_Dir2d dc1(center1.XY()-pinterm.XY()); | |
119 | gp_Dir2d dc2(origin2.XY()-pinterm.XY()); | |
120 | Standard_Real distcc1 = pinterm.Distance(center1); | |
121 | if (!Qualified1.IsUnqualified()) { | |
122 | qualifier1(NbrSol) = Qualified1.Qualifier(); | |
123 | } | |
124 | else if (Abs(distcc1+dist2-R1) < Tol) { | |
125 | qualifier1(NbrSol) = GccEnt_enclosed; | |
126 | } | |
127 | else if (Abs(distcc1-R1-dist2) < Tol) { | |
128 | qualifier1(NbrSol) = GccEnt_outside; | |
129 | } | |
130 | else { qualifier1(NbrSol) = GccEnt_enclosing; } | |
131 | if (!Qualified2.IsUnqualified()) { | |
132 | qualifier2(NbrSol) = Qualified2.Qualifier(); | |
133 | } | |
134 | else if (dc2.Dot(normL2) > 0.0) { | |
135 | qualifier2(NbrSol) = GccEnt_outside; | |
136 | } | |
137 | else { qualifier2(NbrSol) = GccEnt_enclosed; } | |
138 | ||
139 | Standard_Real sign = dc2.Dot(gp_Dir2d(-dirL2.Y(),dirL2.X())); | |
140 | dc2 = gp_Dir2d(sign*gp_XY(-dirL2.Y(),dirL2.X())); | |
141 | pnttg1sol(NbrSol) = gp_Pnt2d(pinterm.XY()+dist2*dc1.XY()); | |
142 | pnttg2sol(NbrSol) = gp_Pnt2d(pinterm.XY()+dist2*dc2.XY()); | |
143 | par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),pnttg1sol(NbrSol)); | |
144 | pararg1(NbrSol)=ElCLib::Parameter(C1,pnttg1sol(NbrSol)); | |
145 | par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),pnttg2sol(NbrSol)); | |
146 | pararg2(NbrSol)=ElCLib::Parameter(L2,pnttg2sol(NbrSol)); | |
147 | pntcen(NbrSol) = cirsol(NbrSol).Location(); | |
148 | parcen3(NbrSol)=ElCLib::Parameter(OnLine,pntcen(NbrSol)); | |
149 | return; | |
150 | } | |
151 | ||
152 | //========================================================================= | |
0d969553 | 153 | // General case. + |
7fd59977 | 154 | //========================================================================= |
155 | ||
156 | GccAna_CircLin2dBisec Bis(C1,L2); | |
157 | if (Bis.IsDone()) { | |
158 | Standard_Integer nbsolution = Bis.NbSolutions(); | |
159 | for (Standard_Integer i = 1 ; i <= nbsolution; i++) { | |
160 | Handle(GccInt_Bisec) Sol = Bis.ThisSolution(i); | |
161 | GccInt_IType type = Sol->ArcType(); | |
162 | IntAna2d_AnaIntersection Intp; | |
163 | if (type == GccInt_Lin) { | |
164 | Intp.Perform(OnLine,Sol->Line()); | |
165 | } | |
166 | else if (type == GccInt_Par) { | |
167 | Intp.Perform(OnLine,IntAna2d_Conic(Sol->Parabola())); | |
168 | } | |
169 | if (Intp.IsDone()) { | |
170 | if (!Intp.IsEmpty()) { | |
171 | for (Standard_Integer j = 1 ; j <= Intp.NbPoints() ; j++) { | |
172 | gp_Pnt2d Center(Intp.Point(j).Value()); | |
173 | Standard_Real dist1 = Center.Distance(center1); | |
174 | dist2 = L2.Distance(Center); | |
175 | // Standard_Integer nbsol = 1; | |
176 | ok = Standard_False; | |
177 | if (Qualified1.IsEnclosed()) { | |
178 | if (dist1-R1 < Tolerance) { | |
179 | if (Abs(Abs(R1-dist1)-dist2)<Tolerance) { ok=Standard_True; } | |
180 | } | |
181 | } | |
182 | else if (Qualified1.IsOutside()) { | |
183 | if (R1-dist1 < Tolerance) { | |
184 | if (Abs(Abs(R1-dist1)-dist2)<Tolerance) { ok=Standard_True; } | |
185 | } | |
186 | } | |
187 | else if (Qualified1.IsEnclosing() || Qualified1.IsUnqualified()) { | |
188 | ok = Standard_True; | |
189 | } | |
190 | if (Qualified2.IsEnclosed() && ok) { | |
191 | if ((((origin2.X()-Center.X())*(-dirL2.Y()))+ | |
192 | ((origin2.Y()-Center.Y())*(dirL2.X())))<=0){ | |
193 | ok = Standard_True; | |
194 | Radius = dist2; | |
195 | } | |
196 | } | |
197 | else if (Qualified2.IsOutside() && ok) { | |
198 | if ((((origin2.X()-Center.X())*(-dirL2.Y()))+ | |
199 | ((origin2.Y()-Center.Y())*(dirL2.X())))>=0){ | |
200 | ok = Standard_True; | |
201 | Radius = dist2; | |
202 | } | |
203 | } | |
204 | else if (Qualified2.IsUnqualified() && ok) { | |
205 | ok = Standard_True; | |
206 | Radius = dist2; | |
207 | } | |
208 | if (ok) { | |
209 | NbrSol++; | |
210 | cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius); | |
211 | // ======================================================= | |
212 | gp_Dir2d dc1(center1.XY()-Center.XY()); | |
213 | gp_Dir2d dc2(origin2.XY()-Center.XY()); | |
214 | Standard_Real distcc1 = Center.Distance(center1); | |
215 | if (!Qualified1.IsUnqualified()) { | |
216 | qualifier1(NbrSol) = Qualified1.Qualifier(); | |
217 | } | |
218 | else if (Abs(distcc1+Radius-R1) < Tol) { | |
219 | qualifier1(NbrSol) = GccEnt_enclosed; | |
220 | } | |
221 | else if (Abs(distcc1-R1-Radius) < Tol) { | |
222 | qualifier1(NbrSol) = GccEnt_outside; | |
223 | } | |
224 | else { qualifier1(NbrSol) = GccEnt_enclosing; } | |
225 | if (!Qualified2.IsUnqualified()) { | |
226 | qualifier2(NbrSol) = Qualified2.Qualifier(); | |
227 | } | |
228 | else if (dc2.Dot(normL2) > 0.0) { | |
229 | qualifier2(NbrSol) = GccEnt_outside; | |
230 | } | |
231 | else { qualifier2(NbrSol) = GccEnt_enclosed; } | |
232 | if (Center.Distance(center1) <= Tolerance && | |
233 | Abs(Radius-C1.Radius()) <= Tolerance) { | |
234 | TheSame1(NbrSol) = 1; | |
235 | } | |
236 | else { | |
237 | TheSame1(NbrSol) = 0; | |
238 | pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius*dc1.XY()); | |
239 | par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol), | |
240 | pnttg1sol(NbrSol)); | |
241 | pararg1(NbrSol)=ElCLib::Parameter(C1,pnttg1sol(NbrSol)); | |
242 | } | |
243 | TheSame2(NbrSol) = 0; | |
244 | Standard_Real sign = dc2.Dot(gp_Dir2d(-dirL2.Y(),dirL2.X())); | |
245 | dc2 = gp_Dir2d(sign*gp_XY(-dirL2.Y(),dirL2.X())); | |
246 | pnttg2sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius*dc2.XY()); | |
247 | par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol), | |
248 | pnttg2sol(NbrSol)); | |
249 | pararg2(NbrSol)=ElCLib::Parameter(L2,pnttg2sol(NbrSol)); | |
250 | pntcen(NbrSol) = Center; | |
251 | parcen3(NbrSol)=ElCLib::Parameter(OnLine,pntcen(NbrSol)); | |
252 | } | |
253 | } | |
254 | } | |
255 | WellDone = Standard_True; | |
256 | } | |
257 | } | |
258 | } | |
259 | } | |
260 | ||
261 | ||
262 | ||
263 | ||
264 | ||
265 |