0022048: Visualization, AIS_InteractiveContext - single object selection should alway...
[occt.git] / src / IntAna2d / IntAna2d_AnaIntersection_2.cxx
CommitLineData
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
28void 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