Commit | Line | Data |
---|---|---|
7fd59977 | 1 | // File: GccAna_Circ2dBisec.cxx |
2 | // Created: Mon Oct 7 16:17:54 1991 | |
3 | // Author: Remi GILET | |
4 | // <reg@phobox> | |
5 | ||
6 | ||
7 | //========================================================================= | |
0d969553 | 8 | // CREATION of the BISSECTICE between two CIRCLES. + |
7fd59977 | 9 | //========================================================================= |
10 | ||
11 | #include <GccAna_Circ2dBisec.ixx> | |
12 | ||
13 | #include <gp_XY.hxx> | |
14 | #include <gp_Dir2d.hxx> | |
15 | #include <gp_Vec2d.hxx> | |
16 | #include <gp_Circ2d.hxx> | |
17 | #include <gp_Hypr2d.hxx> | |
18 | #include <gp.hxx> | |
19 | #include <Standard_ConstructionError.hxx> | |
20 | #include <Standard_OutOfRange.hxx> | |
21 | #include <GccInt_BParab.hxx> | |
22 | #include <GccInt_BLine.hxx> | |
23 | #include <GccInt_BElips.hxx> | |
24 | #include <GccInt_BCirc.hxx> | |
25 | #include <GccInt_BHyper.hxx> | |
26 | #include <GccEnt_BadQualifier.hxx> | |
27 | #include <StdFail_NotDone.hxx> | |
28 | #include <IntAna2d_AnaIntersection.hxx> | |
29 | #include <Precision.hxx> | |
30 | //========================================================================= | |
31 | ||
32 | GccAna_Circ2dBisec:: | |
33 | GccAna_Circ2dBisec (const gp_Circ2d& Circ1 , | |
34 | const gp_Circ2d& Circ2 ) { | |
35 | ||
36 | //========================================================================= | |
0d969553 Y |
37 | // Initialization of fields : + |
38 | // - circle1 (Circle : first argument.) + | |
39 | // - circle2 (Line : second argument.) + | |
40 | // - intersection (Integer showing the smallest position + | |
41 | // of two circles correspondingly to each other.) + | |
42 | // - sameradius (Booleen showing if the two circles have + | |
43 | // the same radius or not.) + | |
44 | // - NbrSol (Integer showing the number of solutions.) + | |
45 | // - WellDone (Boolean showing succes or failure of the algo.). + | |
7fd59977 | 46 | //========================================================================= |
47 | ||
48 | WellDone = Standard_False; | |
49 | Standard_Real Tol=Precision::Confusion(); | |
50 | ||
51 | Standard_Real R1 = Circ1.Radius(); | |
52 | Standard_Real R2 = Circ2.Radius(); | |
53 | if (Abs(R1-R2) <= Tol) { sameradius = Standard_True; } | |
54 | else { sameradius = Standard_False; } | |
55 | if (R1 < R2) { | |
56 | circle1 = gp_Circ2d(Circ2); | |
57 | circle2 = gp_Circ2d(Circ1); | |
58 | R1 = circle1.Radius(); | |
59 | R2 = circle2.Radius(); | |
60 | } | |
61 | else { | |
62 | circle1 = gp_Circ2d(Circ1); | |
63 | circle2 = gp_Circ2d(Circ2); | |
64 | } | |
65 | Standard_Real dist = circle2.Location().Distance(circle1.Location()); | |
66 | if (R1-dist-R2 > Tol) { | |
67 | intersection = 0; | |
68 | NbrSol = 2; | |
69 | WellDone = Standard_True; | |
70 | } | |
71 | else if (Abs(R1-dist-R2) <= Tol) { | |
72 | intersection = 1; | |
73 | if (sameradius) { | |
74 | NbrSol = 0; | |
75 | WellDone = Standard_True; | |
76 | } | |
77 | else { | |
78 | NbrSol = 2; | |
79 | WellDone = Standard_True; | |
80 | } | |
81 | } | |
82 | else if ((dist+R2-R1 > Tol) && (R1-dist+R2 > Tol)) { | |
83 | intersection = 2; | |
84 | if (sameradius) { | |
85 | NbrSol = 2; | |
86 | WellDone = Standard_True; | |
87 | } | |
88 | else { | |
89 | NbrSol = 3; | |
90 | WellDone = Standard_True; | |
91 | } | |
92 | } | |
93 | else if (Abs(R1-dist+R2) <= Tol) { | |
94 | intersection = 3; | |
95 | if (sameradius) { | |
96 | NbrSol = 2; | |
97 | WellDone = Standard_True; | |
98 | } | |
99 | else { | |
100 | NbrSol = 3; | |
101 | WellDone = Standard_True; | |
102 | } | |
103 | } | |
104 | else { | |
105 | intersection = 4; | |
106 | if (sameradius) { | |
107 | NbrSol = 3; | |
108 | WellDone = Standard_True; | |
109 | } | |
110 | else { | |
111 | NbrSol = 4; | |
112 | WellDone = Standard_True; | |
113 | } | |
114 | } | |
115 | } | |
116 | ||
117 | //========================================================================= | |
0d969553 Y |
118 | // Processing. + |
119 | // Return the coordinates of centers of circles circle1 and circle2 + | |
7fd59977 | 120 | // (xcencir1, ycencir1, xcencir2, ycencir2). + |
0d969553 | 121 | // Also return the radiuses of two circles R1 and R2. + |
7fd59977 | 122 | //========================================================================= |
123 | ||
124 | Handle(GccInt_Bisec) GccAna_Circ2dBisec:: | |
125 | ThisSolution (const Standard_Integer Index) const { | |
126 | ||
127 | Standard_Real Tol = 1.e-14; | |
128 | Handle(GccInt_Bisec) bissol; | |
129 | ||
130 | if (!WellDone) { StdFail_NotDone::Raise(); } | |
131 | else if (Index <= 0 || Index > NbrSol) { Standard_OutOfRange::Raise(); } | |
132 | else { | |
133 | Standard_Real xcencir1 = circle1.Location().X(); | |
134 | Standard_Real ycencir1 = circle1.Location().Y(); | |
135 | Standard_Real xcencir2 = circle2.Location().X(); | |
136 | Standard_Real ycencir2 = circle2.Location().Y(); | |
137 | Standard_Real dist = circle1.Location().Distance(circle2.Location()); | |
138 | ||
139 | gp_Pnt2d pcen((xcencir1+xcencir2)/2.0,(ycencir1+ycencir2)/2.0); | |
140 | gp_Dir2d dircen,medcen; | |
141 | if (dist > Tol) { | |
142 | dircen.SetCoord(xcencir2-xcencir1,ycencir2-ycencir1); | |
143 | medcen.SetCoord(ycencir2-ycencir1,xcencir1-xcencir2); | |
144 | } | |
145 | gp_Dir2d dirx(1.0,0.0); | |
146 | gp_Ax2d acenx(pcen,dirx); | |
147 | gp_Ax2d acencen(pcen,dircen); | |
148 | ||
149 | Standard_Real R1 = circle1.Radius(); | |
150 | Standard_Real R2 = circle2.Radius(); | |
151 | ||
152 | if ((NbrSol == 1) && (intersection == 0)) { | |
153 | Standard_Real R; | |
154 | if (Index == 1) | |
155 | R = (R1+R2)/2.0; | |
156 | else | |
157 | R = (R1-R2)/2.0; | |
158 | gp_Circ2d C(acenx,R); | |
159 | bissol = new GccInt_BCirc(C); | |
160 | // ============================= | |
161 | } | |
162 | else if ((NbrSol == 2) && (intersection == 1)) { | |
163 | if (Index == 1) { | |
164 | gp_Elips2d E(acencen, | |
165 | (R1+R2)/2.0,Sqrt((R1*R1+R2*R2-dist*dist)/4.+R1*R2/2.)); | |
166 | bissol = new GccInt_BElips(E); | |
167 | // ============================= | |
168 | } | |
169 | else if (Index == 2) { | |
170 | gp_Lin2d L(circle1.Location(), | |
171 | dircen); | |
172 | bissol = new GccInt_BLine(L); | |
173 | // ============================= | |
174 | } | |
175 | } | |
176 | else if ((NbrSol == 2) && (intersection == 0)) { | |
177 | if (Index == 1) { | |
178 | if (Abs(xcencir2-xcencir1)<Tol && Abs(ycencir2-ycencir1)< Tol) { | |
179 | gp_Circ2d C(acenx,(R1+R2)/2.0); | |
180 | bissol = new GccInt_BCirc(C); | |
181 | // ============================= | |
182 | } | |
183 | else { | |
184 | gp_Elips2d E(acencen, | |
185 | (R1+R2)/2.0,Sqrt((R1*R1+R2*R2-dist*dist)/4.+R1*R2/2.)); | |
186 | bissol = new GccInt_BElips(E); | |
187 | // ============================== | |
188 | } | |
189 | } | |
190 | else if (Index == 2) { | |
191 | if (Abs(xcencir2-xcencir1)< Tol && Abs(ycencir2-ycencir1)< Tol) { | |
192 | gp_Circ2d C(acencen,(R1-R2)/2.); | |
193 | bissol = new GccInt_BCirc(C); | |
194 | // ============================= | |
195 | } | |
196 | else { | |
197 | gp_Elips2d E(acencen, | |
198 | (R1-R2)/2.0,Sqrt((R1*R1+R2*R2-dist*dist)/4.-R1*R2/2.)); | |
199 | bissol = new GccInt_BElips(E); | |
200 | // ============================== | |
201 | } | |
202 | } | |
203 | } | |
204 | else if (intersection == 2) { | |
205 | if (sameradius) { | |
206 | if (Index == 1) { | |
207 | gp_Lin2d L(pcen,medcen); | |
208 | bissol = new GccInt_BLine(L); | |
209 | // ============================= | |
210 | } | |
211 | else if (Index == 2) { | |
212 | gp_Elips2d E(acencen, | |
213 | R1,Sqrt(R1*R1-dist*dist/4.0)); | |
214 | bissol = new GccInt_BElips(E); | |
215 | // ============================== | |
216 | } | |
217 | } | |
218 | else { | |
219 | if (Index == 1) { | |
220 | gp_Hypr2d H1; | |
221 | H1 = gp_Hypr2d(acencen, | |
222 | (R1-R2)/2.0,Sqrt(dist*dist-(R1-R2)*(R1-R2))/2.0); | |
223 | bissol = new GccInt_BHyper(H1); | |
224 | // =============================== | |
225 | } | |
226 | else if (Index == 2) { | |
227 | gp_Hypr2d H1(acencen, | |
228 | (R1-R2)/2.0,Sqrt(dist*dist-(R1-R2)*(R1-R2))/2.0); | |
229 | bissol = new GccInt_BHyper(H1.OtherBranch()); | |
230 | // =============================== | |
231 | } | |
232 | else if (Index == 3) { | |
233 | gp_Elips2d E(acencen, | |
234 | (R1+R2)/2.0,Sqrt((R1*R1+R2*R2-dist*dist)/4.+R1*R2/2.)); | |
235 | bissol = new GccInt_BElips(E); | |
236 | // ============================== | |
237 | } | |
238 | } | |
239 | } | |
240 | else if (intersection == 3) { | |
241 | if (sameradius) { | |
242 | if (Index == 1) { | |
243 | gp_Lin2d L(pcen, dircen); | |
244 | bissol = new GccInt_BLine(L); | |
245 | // ============================= | |
246 | } | |
247 | else if (Index == 2) { | |
248 | gp_Lin2d L(pcen, medcen); | |
249 | bissol = new GccInt_BLine(L); | |
250 | // ============================= | |
251 | } | |
252 | } | |
253 | else { | |
254 | if (Index == 1) { | |
255 | gp_Lin2d L(pcen, dircen); | |
256 | bissol = new GccInt_BLine(L); | |
257 | // ============================= | |
258 | } | |
259 | else if (Index == 2) { | |
260 | gp_Hypr2d H1(acencen, | |
261 | (R1-R2)/2.0,Sqrt(dist*dist-(R1-R2)*(R1-R2))/2.0); | |
262 | bissol = new GccInt_BHyper(H1); | |
263 | // =============================== | |
264 | } | |
265 | else if (Index == 3) { | |
266 | gp_Hypr2d H1(acencen, | |
267 | (R1-R2)/2.0,Sqrt(dist*dist-(R1-R2)*(R1-R2))/2.0); | |
268 | bissol = new GccInt_BHyper(H1.OtherBranch()); | |
269 | // =============================== | |
270 | } | |
271 | } | |
272 | } | |
273 | else if (intersection == 4) { | |
274 | if (sameradius) { | |
275 | if (Index == 1) { | |
276 | gp_Lin2d L(pcen,medcen); | |
277 | bissol = new GccInt_BLine(L); | |
278 | // ============================= | |
279 | } | |
280 | else if (Index == 2) { | |
281 | gp_Hypr2d H1(acencen,R1,Sqrt(dist*dist-4*R1*R1)/2.0); | |
282 | bissol = new GccInt_BHyper(H1); | |
283 | // =============================== | |
284 | } | |
285 | else if (Index == 3) { | |
286 | gp_Hypr2d H1(acencen,R1,Sqrt(dist*dist-4*R1*R1)/2.0); | |
287 | bissol = new GccInt_BHyper(H1.OtherBranch()); | |
288 | // =============================== | |
289 | } | |
290 | } | |
291 | else { | |
292 | if (Index == 1) { | |
293 | gp_Hypr2d H1(acencen, | |
294 | (R1-R2)/2.0,Sqrt(dist*dist-(R1-R2)*(R1-R2))/2.0); | |
295 | bissol = new GccInt_BHyper(H1); | |
296 | // =============================== | |
297 | } | |
298 | else if (Index == 2) { | |
299 | gp_Hypr2d H1(acencen, | |
300 | (R1-R2)/2.0,Sqrt(dist*dist-(R1-R2)*(R1-R2))/2.0); | |
301 | bissol = new GccInt_BHyper(H1.OtherBranch()); | |
302 | // =============================== | |
303 | } | |
304 | else if (Index == 3) { | |
305 | gp_Hypr2d H1(acencen, | |
306 | (R1+R2)/2.0,Sqrt(dist*dist-(R1+R2)*(R1+R2))/2.0); | |
307 | bissol = new GccInt_BHyper(H1); | |
308 | // =============================== | |
309 | } | |
310 | else if (Index == 4) { | |
311 | gp_Hypr2d H1(acencen, | |
312 | (R1+R2)/2.0,Sqrt(dist*dist-(R1+R2)*(R1+R2))/2.0); | |
313 | bissol = new GccInt_BHyper(H1.OtherBranch()); | |
314 | // =============================== | |
315 | } | |
316 | } | |
317 | } | |
318 | } | |
319 | return bissol; | |
320 | } | |
321 | ||
322 | //========================================================================= | |
323 | ||
324 | Standard_Boolean GccAna_Circ2dBisec:: | |
325 | IsDone () const { return WellDone; } | |
326 | ||
327 | Standard_Integer GccAna_Circ2dBisec::NbSolutions () const | |
328 | { | |
329 | if (!WellDone) StdFail_NotDone::Raise(); | |
330 | ||
331 | return NbrSol; | |
332 | } |