Commit | Line | Data |
---|---|---|
b311480e | 1 | // Copyright (c) 1995-1999 Matra Datavision |
973c2be1 | 2 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e | 3 | // |
973c2be1 | 4 | // This file is part of Open CASCADE Technology software library. |
b311480e | 5 | // |
d5f74e42 | 6 | // This library is free software; you can redistribute it and/or modify it under |
7 | // the terms of the GNU Lesser General Public License version 2.1 as published | |
973c2be1 | 8 | // by the Free Software Foundation, with special exception defined in the file |
9 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT | |
10 | // distribution for complete text of the license and disclaimer of any warranty. | |
b311480e | 11 | // |
973c2be1 | 12 | // Alternatively, this file may be used under the terms of Open CASCADE |
13 | // commercial license or contractual agreement. | |
b311480e | 14 | |
7fd59977 | 15 | |
42cf5bc1 | 16 | #include <gp_Circ2d.hxx> |
17 | #include <gp_Elips2d.hxx> | |
18 | #include <gp_Hypr2d.hxx> | |
19 | #include <gp_Lin2d.hxx> | |
20 | #include <gp_Parab2d.hxx> | |
7fd59977 | 21 | #include <gp_Vec2d.hxx> |
42cf5bc1 | 22 | #include <IntAna2d_AnaIntersection.hxx> |
23 | #include <IntAna2d_Conic.hxx> | |
24 | #include <IntAna2d_IntPoint.hxx> | |
25 | #include <Standard_OutOfRange.hxx> | |
26 | #include <StdFail_NotDone.hxx> | |
7fd59977 | 27 | |
28 | void IntAna2d_AnaIntersection::Perform (const gp_Circ2d& C1, | |
29 | const gp_Circ2d& C2) { | |
30 | ||
31 | done=Standard_False; | |
32 | Standard_Real d=C1.Location().Distance(C2.Location()); | |
33 | Standard_Real R1=C1.Radius(); | |
34 | Standard_Real R2=C2.Radius(); | |
35 | Standard_Real sum=R1+R2; | |
36 | Standard_Real dif=Abs(R1-R2); | |
37 | ||
38 | ||
39 | if (d<=RealEpsilon()) { // Cercle concentriques | |
40 | para=Standard_True; | |
41 | nbp=0; | |
42 | if (dif<=RealEpsilon()) { // Cercles confondus | |
43 | empt=Standard_False; | |
44 | iden=Standard_True; | |
45 | } | |
46 | else { // Cercles paralleles | |
47 | empt=Standard_True; | |
48 | iden=Standard_False; | |
49 | } | |
50 | } | |
51 | else if ((d-sum)>Epsilon(sum)) { // Cercles exterieurs l un a l autre | |
52 | // et No solution | |
53 | empt=Standard_True; | |
54 | para=Standard_False; | |
55 | iden=Standard_False; | |
56 | nbp=0; | |
57 | } | |
58 | else if (Abs(d-sum)<=Epsilon(sum)) { // Cercles exterieurs et tangents | |
59 | empt=Standard_False; | |
60 | para=Standard_False; | |
61 | iden=Standard_False; | |
62 | nbp=1; | |
63 | gp_Vec2d ax(C1.Location(),C2.Location()); | |
64 | gp_Vec2d Ox1(C1.XAxis().Direction()); | |
65 | gp_Vec2d Ox2(C2.XAxis().Direction()); | |
66 | ||
67 | Standard_Real XS = ( C1.Location().X()*R2 + C2.Location().X()*R1 ) / sum; | |
68 | Standard_Real YS = ( C1.Location().Y()*R2 + C2.Location().Y()*R1 ) / sum; | |
69 | Standard_Real ang1=Ox1.Angle(ax); // Resultat entre -PI et +PI | |
c6541a0c D |
70 | Standard_Real ang2=Ox2.Angle(ax) + M_PI; |
71 | if (ang1<0) {ang1=2*M_PI+ang1;} // On revient entre 0 et 2PI | |
7fd59977 | 72 | lpnt[0].SetValue(XS,YS,ang1,ang2); |
73 | } | |
3cb19cf1 | 74 | else if (((sum-d)>Epsilon(sum)) && ((d-dif)>Epsilon(d+dif))) { |
7fd59977 | 75 | empt=Standard_False; |
76 | para=Standard_False; | |
77 | iden=Standard_False; | |
78 | nbp=2; | |
79 | gp_Vec2d ax(C1.Location(),C2.Location()); | |
80 | gp_Vec2d Ox1(C1.XAxis().Direction()); | |
81 | gp_Vec2d Ox2(C2.XAxis().Direction()); | |
82 | Standard_Real ref1=Ox1.Angle(ax); // Resultat entre -PI et +PI | |
83 | Standard_Real ref2=Ox2.Angle(ax); // Resultat entre -PI et +PI | |
84 | ||
85 | Standard_Real l1=(d*d + R1*R1 -R2*R2)/(2.0*d); | |
3f16d970 | 86 | Standard_Real aDet = R1*R1-l1*l1; |
87 | if(aDet < 0.) { | |
88 | aDet = 0.; | |
89 | l1 = (l1 > 0 ? R1 : - R1); | |
90 | } | |
7fd59977 | 91 | Standard_Real h= Sqrt(R1*R1-l1*l1); |
92 | ||
93 | Standard_Real XS1= C1.Location().X() + l1*ax.X()/d - h*ax.Y()/d; | |
94 | Standard_Real YS1= C1.Location().Y() + l1*ax.Y()/d + h*ax.X()/d; | |
95 | ||
96 | Standard_Real XS2= C1.Location().X() + l1*ax.X()/d + h*ax.Y()/d; | |
97 | Standard_Real YS2= C1.Location().Y() + l1*ax.Y()/d - h*ax.X()/d; | |
98 | ||
99 | Standard_Real sint1=h /R1; | |
100 | Standard_Real cost1=l1/R1; | |
101 | ||
102 | Standard_Real sint2=h /R2; | |
103 | Standard_Real cost2=(l1-d)/R2; | |
104 | ||
105 | Standard_Real ang1,ang2; | |
106 | ||
107 | // ang1 et ang2 correspondent aux solutions avec sinus positif | |
108 | // si l'axe de reference est l'axe des centres C1C2 | |
109 | // On prend l'arccos entre pi/2 et 3pi/2, l'arcsin sinon. | |
110 | ||
111 | if (Abs(cost1)<=0.707) { | |
112 | ang1=ACos(cost1); | |
113 | } | |
114 | else { | |
115 | ang1=ASin(sint1); | |
c6541a0c | 116 | if (cost1<0.0) {ang1=M_PI-ang1;} |
7fd59977 | 117 | } |
118 | if (Abs(cost2)<=0.707) { | |
119 | ang2=ACos(cost2); | |
120 | } | |
121 | else { | |
122 | ang2=ASin(sint2); | |
c6541a0c | 123 | if (cost2<0.0) {ang2=M_PI-ang2;} |
7fd59977 | 124 | } |
125 | Standard_Real ang11=ref1+ang1; | |
126 | Standard_Real ang21=ref2+ang2; | |
127 | Standard_Real ang12=ref1-ang1; | |
128 | Standard_Real ang22=ref2-ang2; | |
129 | if (ang11<0.) { | |
c6541a0c | 130 | ang11=2*M_PI+ang11; |
7fd59977 | 131 | } |
c6541a0c D |
132 | else if (ang11>=2*M_PI) { |
133 | ang11=ang11-2*M_PI; | |
7fd59977 | 134 | } |
135 | if (ang21<0.) { | |
c6541a0c | 136 | ang21=2*M_PI+ang21; |
7fd59977 | 137 | } |
c6541a0c D |
138 | else if (ang21>=2*M_PI) { |
139 | ang21=ang21-2*M_PI; | |
7fd59977 | 140 | } |
141 | if (ang12<0.) { | |
c6541a0c | 142 | ang12=2*M_PI+ang12; |
7fd59977 | 143 | } |
c6541a0c D |
144 | else if (ang12>=2*M_PI) { |
145 | ang12=ang12-2*M_PI; | |
7fd59977 | 146 | } |
147 | if (ang22<0.) { | |
c6541a0c | 148 | ang22=2*M_PI+ang22; |
7fd59977 | 149 | } |
c6541a0c D |
150 | else if (ang22>=2*M_PI) { |
151 | ang22=ang22-2*M_PI; | |
7fd59977 | 152 | } |
153 | lpnt[0].SetValue(XS1,YS1,ang11,ang21); | |
154 | lpnt[1].SetValue(XS2,YS2,ang12,ang22); | |
155 | } | |
3f16d970 | 156 | else if (Abs(d-dif)<=Epsilon(sum)) { // Cercles tangents interieurs |
7fd59977 | 157 | empt=Standard_False; |
158 | para=Standard_False; | |
159 | iden=Standard_False; | |
160 | nbp=1; | |
161 | gp_Vec2d ax(C1.Location(),C2.Location()); | |
3f16d970 | 162 | if(C1.Radius() < C2.Radius()) |
163 | ax.Reverse(); | |
164 | ||
7fd59977 | 165 | gp_Vec2d Ox1(C1.XAxis().Direction()); |
166 | gp_Vec2d Ox2(C2.XAxis().Direction()); | |
167 | Standard_Real ang1=Ox1.Angle(ax); // Resultat entre -PI et +PI | |
168 | Standard_Real ang2=Ox2.Angle(ax); | |
c6541a0c D |
169 | if (ang1<0) {ang1=2*M_PI+ang1;} // On revient entre 0 et 2PI |
170 | if (ang2<0) {ang2=2*M_PI+ang2;} // On revient entre 0 et 2PI | |
7fd59977 | 171 | Standard_Real XS = ( C1.Location().X()*R2 - C2.Location().X()*R1 ) / (R2 - R1); |
172 | Standard_Real YS = ( C1.Location().Y()*R2 - C2.Location().Y()*R1 ) / (R2 - R1); | |
173 | lpnt[0].SetValue(XS,YS,ang1,ang2); | |
174 | } | |
175 | else { // On doit avoir d<dif-Resol et d<>0 donc | |
176 | // 1 cercle dans l autre et no solution | |
177 | empt=Standard_True; | |
178 | para=Standard_False; | |
179 | iden=Standard_False; | |
180 | nbp=0; | |
181 | } | |
182 | done=Standard_True; | |
183 | } | |
184 | ||
185 |