Commit | Line | Data |
---|---|---|
7fd59977 | 1 | // File: GccAna_Circ2d2TanRad_2.cxx |
2 | // Created: Tue Sep 24 09:12:49 1991 | |
3 | // Author: Remi GILET | |
4 | // <reg@topsn2> | |
5 | ||
6 | #include <GccAna_Circ2d2TanRad.jxx> | |
7 | ||
8 | #include <gp_Circ2d.hxx> | |
9 | #include <ElCLib.hxx> | |
10 | #include <gp_Dir2d.hxx> | |
11 | #include <gp_Lin2d.hxx> | |
12 | #include <IntAna2d_AnaIntersection.hxx> | |
13 | #include <IntAna2d_IntPoint.hxx> | |
14 | #include <Standard_NegativeValue.hxx> | |
15 | #include <GccEnt_BadQualifier.hxx> | |
16 | ||
0d969553 | 17 | // circulare tangent to a circle a point and a given radius |
7fd59977 | 18 | //============================================================= |
19 | ||
20 | //======================================================================== | |
0d969553 Y |
21 | // Initialize WellDone to false. + |
22 | // Return circle C1. + | |
23 | // Leave with error if the construction is impossible. + | |
24 | // Create parallel to C1 in the proper direction. + | |
25 | // Create circle with center in Point1 of radius Radius. + | |
26 | // Intersect the parallel and the circle. + | |
27 | // ==> The center point of the solution. + | |
28 | // Create the solution that will be added to already found solutions. + | |
29 | // Fill the fields. + | |
7fd59977 | 30 | //======================================================================== |
31 | ||
32 | GccAna_Circ2d2TanRad:: | |
33 | GccAna_Circ2d2TanRad (const GccEnt_QualifiedCirc& Qualified1 , | |
34 | const gp_Pnt2d& Point2 , | |
35 | const Standard_Real Radius , | |
36 | const Standard_Real Tolerance ): | |
37 | qualifier1(1,4) , | |
38 | qualifier2(1,4), | |
39 | TheSame1(1,4) , | |
40 | TheSame2(1,4) , | |
41 | cirsol(1,4) , | |
42 | pnttg1sol(1,4) , | |
43 | pnttg2sol(1,4) , | |
44 | par1sol(1,4) , | |
45 | par2sol(1,4) , | |
46 | pararg1(1,4) , | |
47 | pararg2(1,4) | |
48 | { | |
49 | ||
50 | gp_Dir2d dirx(1.0,0.0); | |
51 | Standard_Real Tol = Abs(Tolerance); | |
52 | NbrSol = 0; | |
53 | WellDone = Standard_False; | |
54 | if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() || | |
55 | Qualified1.IsOutside() || Qualified1.IsUnqualified())) { | |
56 | GccEnt_BadQualifier::Raise(); | |
57 | return; | |
58 | } | |
59 | Standard_Integer i ; | |
60 | for ( i = 1 ; i <= 4 ; i++) { | |
61 | TheSame1(i) = 0; | |
62 | TheSame2(i) = 0; | |
63 | } | |
64 | Standard_Real deport = 0.; | |
65 | Standard_Integer signe = 0; | |
66 | Standard_Integer nbsol = 0; | |
67 | gp_Circ2d C1 = Qualified1.Qualified(); | |
68 | TColgp_Array1OfCirc2d C(1,4); | |
69 | Standard_Real R1 = C1.Radius(); | |
70 | Standard_Real distance = (C1.Location()).Distance(Point2); | |
71 | Standard_Real dispc1 = C1.Distance(Point2); | |
72 | gp_Dir2d dir1(Point2.XY()-(C1.Location().XY())); | |
73 | gp_Pnt2d center1(C1.Location()); | |
74 | if (Radius < 0.0) { Standard_NegativeValue::Raise(); } | |
75 | else { | |
76 | if ( dispc1-Radius*2.0 > Tol) { WellDone = Standard_True; } | |
77 | else if (Qualified1.IsEnclosed()) { | |
78 | // ================================= | |
79 | if ((distance-R1>Tol)||(Radius-R1>Tol)) { WellDone = Standard_True; } | |
80 | else { | |
81 | if (Abs(distance-R1) < Tol) { | |
82 | nbsol = -1; | |
83 | deport = R1-Radius; | |
84 | signe = 1; | |
85 | } | |
86 | else { | |
87 | C(1) = gp_Circ2d(C1.XAxis(),Abs(Radius-R1)); | |
88 | C(2) = gp_Circ2d(gp_Ax2d(Point2,dirx),Radius); | |
89 | nbsol = 1; | |
90 | } | |
91 | } | |
92 | } | |
93 | else if (Qualified1.IsEnclosing()) { | |
94 | // ================================== | |
95 | if ((Tol<R1-distance)||(Tol<R1-Radius)) { WellDone = Standard_True; } | |
96 | else { | |
97 | if (Abs(distance-R1) < Tol) { | |
98 | nbsol = -1; | |
99 | deport = R1-Radius; | |
100 | signe = 1; | |
101 | } | |
102 | else { | |
103 | C(1) = gp_Circ2d(C1.XAxis(),Abs(Radius-R1)); | |
104 | C(2) = gp_Circ2d(gp_Ax2d(Point2,dirx),Radius); | |
105 | nbsol = 1; | |
106 | } | |
107 | } | |
108 | } | |
109 | else if (Qualified1.IsOutside()) { | |
110 | // ================================ | |
111 | if (Tol < R1-distance) { WellDone = Standard_True; } | |
112 | else if ((Abs(distance-R1) < Tol) || (Abs(dispc1-Radius*2.0) < Tol)) { | |
113 | nbsol = -1; | |
114 | deport = R1+Radius; | |
115 | signe = -1; | |
116 | } | |
117 | else { | |
118 | C(1) = gp_Circ2d(C1.XAxis(),Radius+R1); | |
119 | C(2) = gp_Circ2d(gp_Ax2d(Point2,dirx),Radius); | |
120 | nbsol = 1; | |
121 | } | |
122 | } | |
123 | else if (Qualified1.IsUnqualified()) { | |
124 | // ==================================== | |
125 | if (Abs(dispc1-Radius*2.0) < Tol) { | |
126 | WellDone = Standard_True; | |
127 | gp_Pnt2d Center(center1.XY()+(distance-Radius)*dir1.XY()); | |
128 | cirsol(1) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius); | |
129 | // ================================================== | |
130 | if (Abs(Center.Distance(center1)-R1) < Tol) { | |
131 | qualifier1(1) = GccEnt_enclosed; | |
132 | } | |
133 | else { qualifier1(1) = GccEnt_outside; } | |
134 | qualifier2(1) = GccEnt_noqualifier; | |
135 | pnttg1sol(1) = gp_Pnt2d(Center.XY()-Radius*dir1.XY()); | |
136 | pnttg2sol(1) = Point2; | |
137 | WellDone = Standard_True; | |
138 | NbrSol = 1; | |
139 | } | |
140 | else if ((Abs(R1-Radius)<Tol) && (Abs(distance-R1)<Tol)){ | |
141 | cirsol(1) = gp_Circ2d(C1); | |
142 | // ========================= | |
143 | qualifier1(1) = GccEnt_unqualified; | |
144 | qualifier2(1) = GccEnt_noqualifier; | |
145 | TheSame1(1) = 1; | |
146 | pnttg2sol(1) = Point2; | |
147 | WellDone = Standard_True; | |
148 | NbrSol = 1; | |
149 | C(1) = gp_Circ2d(C1.XAxis(),Radius+R1); | |
150 | C(2) = gp_Circ2d(gp_Ax2d(Point2,dirx),Radius); | |
151 | nbsol = 1; | |
152 | } | |
153 | else { | |
154 | C(1) = gp_Circ2d(C1.XAxis(),Abs(Radius-R1)); | |
155 | C(2) = gp_Circ2d(gp_Ax2d(Point2,dirx),Radius); | |
156 | C(3) = gp_Circ2d(C1.XAxis(),Radius+R1); | |
157 | C(4) = gp_Circ2d(gp_Ax2d(Point2,dirx),Radius); | |
158 | nbsol = 2; | |
159 | } | |
160 | } | |
161 | if (nbsol > 0) { | |
162 | for (Standard_Integer j = 1 ; j <= nbsol ; j++) { | |
163 | IntAna2d_AnaIntersection Intp(C(2*j-1),C(2*j)); | |
164 | if (Intp.IsDone()) { | |
165 | if (!Intp.IsEmpty()) { | |
166 | for (i = 1 ; i <= Intp.NbPoints() ; i++) { | |
167 | NbrSol++; | |
168 | gp_Pnt2d Center(Intp.Point(i).Value()); | |
169 | cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius); | |
170 | // ======================================================= | |
171 | Standard_Real distcc1 = center1.Distance(Center); | |
172 | if (!Qualified1.IsUnqualified()) { | |
173 | qualifier1(NbrSol) = Qualified1.Qualifier(); | |
174 | } | |
175 | else if (Abs(distcc1+Radius-R1) < Tol) { | |
176 | qualifier1(NbrSol) = GccEnt_enclosed; | |
177 | } | |
178 | else if (Abs(distcc1-R1-Radius) < Tol) { | |
179 | qualifier1(NbrSol) = GccEnt_outside; | |
180 | } | |
181 | else { qualifier1(NbrSol) = GccEnt_enclosing; } | |
182 | qualifier2(NbrSol) = GccEnt_noqualifier; | |
183 | dir1 = gp_Dir2d(Center.XY()-center1.XY()); | |
184 | #ifdef DEB | |
185 | gp_Dir2d dir2(Center.XY()-Point2.XY()); | |
186 | #endif | |
187 | if ((Center.Distance(center1) > C1.Radius()) && | |
188 | (Radius < Center.Distance(center1)+C1.Radius())) { | |
189 | pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()-Radius*dir1.XY()); | |
190 | } | |
191 | else if ((Center.Distance(center1) < C1.Radius()) && | |
192 | (Radius < C1.Radius())) { | |
193 | pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius*dir1.XY()); | |
194 | } | |
195 | else { | |
196 | pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()-Radius*dir1.XY()); | |
197 | } | |
198 | pnttg2sol(NbrSol) = Point2; | |
199 | } | |
200 | } | |
201 | WellDone = Standard_True; | |
202 | } | |
203 | } | |
204 | } | |
205 | else if (nbsol < 0) { | |
206 | gp_Pnt2d Center(center1.XY()+deport*dir1.XY()); | |
207 | cirsol(1) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius); | |
208 | // ================================================== | |
209 | qualifier1(1) = Qualified1.Qualifier(); | |
210 | qualifier2(1) = GccEnt_noqualifier; | |
211 | if (Abs(deport) <= Tol && Abs(Radius-R1) <= Tol) { | |
212 | TheSame1(1) = 1; | |
213 | } | |
214 | else { | |
215 | pnttg1sol(1) = gp_Pnt2d(Center.XY()+signe*Radius*dir1.XY()); | |
216 | } | |
217 | pnttg2sol(1) = Point2; | |
218 | WellDone = Standard_True; | |
219 | NbrSol = 1; | |
220 | } | |
221 | } | |
222 | for (i = 1 ; i <= NbrSol ; i++) { | |
223 | par1sol(i)=ElCLib::Parameter(cirsol(i),pnttg1sol(i)); | |
224 | if (TheSame1(i) == 0) { | |
225 | pararg1(i)=ElCLib::Parameter(C1,pnttg1sol(i)); | |
226 | } | |
227 | par2sol(i) = ElCLib::Parameter(cirsol(i),pnttg2sol(i)); | |
228 | pararg2(i) = 0.; | |
229 | } | |
230 | } | |
231 | ||
232 | ||
233 | ||
234 | ||
235 |