1 // Created on: 1991-10-07
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 of the BISSECTICE between two CIRCLES. +
19 //=========================================================================
21 #include <GccAna_Circ2dBisec.hxx>
22 #include <GccEnt_BadQualifier.hxx>
23 #include <GccInt_BCirc.hxx>
24 #include <GccInt_BElips.hxx>
25 #include <GccInt_BHyper.hxx>
26 #include <GccInt_Bisec.hxx>
27 #include <GccInt_BLine.hxx>
28 #include <GccInt_BParab.hxx>
30 #include <gp_Circ2d.hxx>
31 #include <gp_Dir2d.hxx>
32 #include <gp_Hypr2d.hxx>
33 #include <gp_Vec2d.hxx>
35 #include <IntAna2d_AnaIntersection.hxx>
36 #include <Precision.hxx>
37 #include <Standard_ConstructionError.hxx>
38 #include <Standard_OutOfRange.hxx>
39 #include <StdFail_NotDone.hxx>
41 //=========================================================================
43 GccAna_Circ2dBisec (const gp_Circ2d& Circ1 ,
44 const gp_Circ2d& Circ2 ) {
46 //=========================================================================
47 // Initialization of fields : +
48 // - circle1 (Circle : first argument.) +
49 // - circle2 (Line : second argument.) +
50 // - intersection (Integer showing the smallest position +
51 // of two circles correspondingly to each other.) +
52 // - sameradius (Booleen showing if the two circles have +
53 // the same radius or not.) +
54 // - NbrSol (Integer showing the number of solutions.) +
55 // - WellDone (Boolean showing succes or failure of the algo.). +
56 //=========================================================================
58 WellDone = Standard_False;
59 Standard_Real Tol=Precision::Confusion();
61 Standard_Real R1 = Circ1.Radius();
62 Standard_Real R2 = Circ2.Radius();
63 if (Abs(R1-R2) <= Tol) { sameradius = Standard_True; }
64 else { sameradius = Standard_False; }
66 circle1 = gp_Circ2d(Circ2);
67 circle2 = gp_Circ2d(Circ1);
68 R1 = circle1.Radius();
69 R2 = circle2.Radius();
72 circle1 = gp_Circ2d(Circ1);
73 circle2 = gp_Circ2d(Circ2);
75 Standard_Real dist = circle2.Location().Distance(circle1.Location());
76 if (R1-dist-R2 > Tol) {
79 WellDone = Standard_True;
81 else if (Abs(R1-dist-R2) <= Tol) {
85 WellDone = Standard_True;
89 WellDone = Standard_True;
92 else if ((dist+R2-R1 > Tol) && (R1-dist+R2 > Tol)) {
96 WellDone = Standard_True;
100 WellDone = Standard_True;
103 else if (Abs(R1-dist+R2) <= Tol) {
107 WellDone = Standard_True;
111 WellDone = Standard_True;
118 WellDone = Standard_True;
122 WellDone = Standard_True;
127 //=========================================================================
129 // Return the coordinates of centers of circles circle1 and circle2 +
130 // (xcencir1, ycencir1, xcencir2, ycencir2). +
131 // Also return the radiuses of two circles R1 and R2. +
132 //=========================================================================
134 Handle(GccInt_Bisec) GccAna_Circ2dBisec::
135 ThisSolution (const Standard_Integer Index) const {
137 Standard_Real Tol = 1.e-14;
138 Handle(GccInt_Bisec) bissol;
140 if (!WellDone) { throw StdFail_NotDone(); }
141 else if (Index <= 0 || Index > NbrSol) { throw Standard_OutOfRange(); }
143 Standard_Real xcencir1 = circle1.Location().X();
144 Standard_Real ycencir1 = circle1.Location().Y();
145 Standard_Real xcencir2 = circle2.Location().X();
146 Standard_Real ycencir2 = circle2.Location().Y();
147 Standard_Real dist = circle1.Location().Distance(circle2.Location());
149 gp_Pnt2d pcen((xcencir1+xcencir2)/2.0,(ycencir1+ycencir2)/2.0);
150 gp_Dir2d dircen,medcen;
152 dircen.SetCoord(xcencir2-xcencir1,ycencir2-ycencir1);
153 medcen.SetCoord(ycencir2-ycencir1,xcencir1-xcencir2);
155 gp_Dir2d dirx(1.0,0.0);
156 gp_Ax2d acenx(pcen,dirx);
157 gp_Ax2d acencen(pcen,dircen);
159 Standard_Real R1 = circle1.Radius();
160 Standard_Real R2 = circle2.Radius();
162 if ((NbrSol == 1) && (intersection == 0)) {
168 gp_Circ2d C(acenx,R);
169 bissol = new GccInt_BCirc(C);
170 // =============================
172 else if ((NbrSol == 2) && (intersection == 1)) {
174 gp_Elips2d E(acencen,
175 (R1+R2)/2.0,Sqrt((R1*R1+R2*R2-dist*dist)/4.+R1*R2/2.));
176 bissol = new GccInt_BElips(E);
177 // =============================
179 else if (Index == 2) {
180 gp_Lin2d L(circle1.Location(),
182 bissol = new GccInt_BLine(L);
183 // =============================
186 else if ((NbrSol == 2) && (intersection == 0)) {
188 if (Abs(xcencir2-xcencir1)<Tol && Abs(ycencir2-ycencir1)< Tol) {
189 gp_Circ2d C(acenx,(R1+R2)/2.0);
190 bissol = new GccInt_BCirc(C);
191 // =============================
194 gp_Elips2d E(acencen,
195 (R1+R2)/2.0,Sqrt((R1*R1+R2*R2-dist*dist)/4.+R1*R2/2.));
196 bissol = new GccInt_BElips(E);
197 // ==============================
200 else if (Index == 2) {
201 if (Abs(xcencir2-xcencir1)< Tol && Abs(ycencir2-ycencir1)< Tol) {
202 gp_Circ2d C(acencen,(R1-R2)/2.);
203 bissol = new GccInt_BCirc(C);
204 // =============================
207 gp_Elips2d E(acencen,
208 (R1-R2)/2.0,Sqrt((R1*R1+R2*R2-dist*dist)/4.-R1*R2/2.));
209 bissol = new GccInt_BElips(E);
210 // ==============================
214 else if (intersection == 2) {
217 gp_Lin2d L(pcen,medcen);
218 bissol = new GccInt_BLine(L);
219 // =============================
221 else if (Index == 2) {
222 gp_Elips2d E(acencen,
223 R1,Sqrt(R1*R1-dist*dist/4.0));
224 bissol = new GccInt_BElips(E);
225 // ==============================
231 H1 = gp_Hypr2d(acencen,
232 (R1-R2)/2.0,Sqrt(dist*dist-(R1-R2)*(R1-R2))/2.0);
233 bissol = new GccInt_BHyper(H1);
234 // ===============================
236 else if (Index == 2) {
237 gp_Hypr2d H1(acencen,
238 (R1-R2)/2.0,Sqrt(dist*dist-(R1-R2)*(R1-R2))/2.0);
239 bissol = new GccInt_BHyper(H1.OtherBranch());
240 // ===============================
242 else if (Index == 3) {
243 gp_Elips2d E(acencen,
244 (R1+R2)/2.0,Sqrt((R1*R1+R2*R2-dist*dist)/4.+R1*R2/2.));
245 bissol = new GccInt_BElips(E);
246 // ==============================
250 else if (intersection == 3) {
253 gp_Lin2d L(pcen, dircen);
254 bissol = new GccInt_BLine(L);
255 // =============================
257 else if (Index == 2) {
258 gp_Lin2d L(pcen, medcen);
259 bissol = new GccInt_BLine(L);
260 // =============================
265 gp_Lin2d L(pcen, dircen);
266 bissol = new GccInt_BLine(L);
267 // =============================
269 else if (Index == 2) {
270 gp_Hypr2d H1(acencen,
271 (R1-R2)/2.0,Sqrt(dist*dist-(R1-R2)*(R1-R2))/2.0);
272 bissol = new GccInt_BHyper(H1);
273 // ===============================
275 else if (Index == 3) {
276 gp_Hypr2d H1(acencen,
277 (R1-R2)/2.0,Sqrt(dist*dist-(R1-R2)*(R1-R2))/2.0);
278 bissol = new GccInt_BHyper(H1.OtherBranch());
279 // ===============================
283 else if (intersection == 4) {
286 gp_Lin2d L(pcen,medcen);
287 bissol = new GccInt_BLine(L);
288 // =============================
290 else if (Index == 2) {
291 gp_Hypr2d H1(acencen,R1,Sqrt(dist*dist-4*R1*R1)/2.0);
292 bissol = new GccInt_BHyper(H1);
293 // ===============================
295 else if (Index == 3) {
296 gp_Hypr2d H1(acencen,R1,Sqrt(dist*dist-4*R1*R1)/2.0);
297 bissol = new GccInt_BHyper(H1.OtherBranch());
298 // ===============================
303 gp_Hypr2d H1(acencen,
304 (R1-R2)/2.0,Sqrt(dist*dist-(R1-R2)*(R1-R2))/2.0);
305 bissol = new GccInt_BHyper(H1);
306 // ===============================
308 else if (Index == 2) {
309 gp_Hypr2d H1(acencen,
310 (R1-R2)/2.0,Sqrt(dist*dist-(R1-R2)*(R1-R2))/2.0);
311 bissol = new GccInt_BHyper(H1.OtherBranch());
312 // ===============================
314 else if (Index == 3) {
315 gp_Hypr2d H1(acencen,
316 (R1+R2)/2.0,Sqrt(dist*dist-(R1+R2)*(R1+R2))/2.0);
317 bissol = new GccInt_BHyper(H1);
318 // ===============================
320 else if (Index == 4) {
321 gp_Hypr2d H1(acencen,
322 (R1+R2)/2.0,Sqrt(dist*dist-(R1+R2)*(R1+R2))/2.0);
323 bissol = new GccInt_BHyper(H1.OtherBranch());
324 // ===============================
332 //=========================================================================
334 Standard_Boolean GccAna_Circ2dBisec::
335 IsDone () const { return WellDone; }
337 Standard_Integer GccAna_Circ2dBisec::NbSolutions () const
339 if (!WellDone) throw StdFail_NotDone();