b311480e |
1 | // Copyright (c) 1995-1999 Matra Datavision |
2 | // Copyright (c) 1999-2012 OPEN CASCADE SAS |
3 | // |
4 | // The content of this file is subject to the Open CASCADE Technology Public |
5 | // License Version 6.5 (the "License"). You may not use the content of this file |
6 | // except in compliance with the License. Please obtain a copy of the License |
7 | // at http://www.opencascade.org and read it completely before using this file. |
8 | // |
9 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its |
10 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. |
11 | // |
12 | // The Original Code and all software distributed under the License is |
13 | // distributed on an "AS IS" basis, without warranty of any kind, and the |
14 | // Initial Developer hereby disclaims all such warranties, including without |
15 | // limitation, any warranties of merchantability, fitness for a particular |
16 | // purpose or non-infringement. Please see the License for the specific terms |
17 | // and conditions governing the rights and limitations under the License. |
18 | |
7fd59977 |
19 | #include <IntCurve_IConicTool.ixx> |
20 | #include <ElCLib.hxx> |
21 | #include <gp.hxx> |
b311480e |
22 | |
7fd59977 |
23 | |
24 | #define Object_To_Abs Abs_To_Object.Inverted() |
25 | //====================================================================== |
26 | #define Elips_a prm1 |
27 | #define Elips_b prm2 |
28 | #define Elips_c prm3 |
29 | |
30 | #define Elips_aa (Elips_a*Elips_a) |
31 | #define Elips_bb (Elips_b*Elips_b) |
32 | #define Elips_x0 (Axis.Location().X()) |
33 | #define Elips_y0 (Axis.Location().Y()) |
34 | //====================================================================== |
35 | #define Hypr_a prm1 |
36 | #define Hypr_b prm2 |
37 | #define Hypr_aa (Hypr_a * Hypr_a) |
38 | #define Hypr_bb (Hypr_b * Hypr_b) |
39 | //====================================================================== |
40 | #define Line_a prm1 |
41 | #define Line_b prm2 |
42 | #define Line_c prm3 |
43 | //====================================================================== |
44 | #define Circle_r prm1 |
45 | #define Circle_x0 prm2 |
46 | #define Circle_y0 prm3 |
47 | //====================================================================== |
48 | #define Parab_f prm1 |
49 | #define Parab_2p prm2 |
50 | |
51 | //====================================================================== |
52 | IntCurve_IConicTool::IntCurve_IConicTool(void) { |
53 | //###### PLACER LE TYPE NON DEFINI ###### |
54 | } |
55 | |
56 | |
57 | IntCurve_IConicTool::IntCurve_IConicTool(const IntCurve_IConicTool& ITool) { |
58 | prm1=ITool.prm1; |
59 | prm2=ITool.prm2; |
60 | prm3=ITool.prm3; |
61 | Axis=ITool.Axis; |
62 | Abs_To_Object=ITool.Abs_To_Object; |
63 | type=ITool.type; |
64 | } |
65 | //====================================================================== |
66 | //====================================================================== |
67 | IntCurve_IConicTool::IntCurve_IConicTool(const gp_Lin2d& Line) { |
68 | Line.Coefficients(Line_a,Line_b,Line_c); |
69 | Axis = gp_Ax22d(Line.Position(),Standard_True); |
70 | type = GeomAbs_Line; |
71 | } |
72 | //====================================================================== |
73 | IntCurve_IConicTool::IntCurve_IConicTool(const gp_Elips2d& Elips) { |
74 | Elips_a = Elips.MajorRadius(); |
75 | Elips_b = Elips.MinorRadius(); |
76 | Elips_c = sqrt(Elips_a*Elips_a-Elips_b*Elips_b); |
77 | Axis = Elips.Axis(); |
78 | Abs_To_Object.SetTransformation(gp::OX2d(),Axis.XAxis()); |
79 | type = GeomAbs_Ellipse; |
80 | } |
81 | //====================================================================== |
82 | IntCurve_IConicTool::IntCurve_IConicTool(const gp_Circ2d& C) { |
83 | Circle_r=C.Radius(); |
84 | Axis=C.Axis(); |
85 | Circle_x0=Axis.Location().X(); |
86 | Circle_y0=Axis.Location().Y(); |
87 | Abs_To_Object.SetTransformation(gp::OX2d(),Axis.XAxis()); |
88 | type = GeomAbs_Circle; |
89 | } |
90 | //====================================================================== |
91 | IntCurve_IConicTool::IntCurve_IConicTool(const gp_Parab2d& P) { |
92 | Parab_f=P.Focal(); |
93 | Parab_2p=4.0*Parab_f; |
94 | Axis=P.Axis(); |
95 | Abs_To_Object.SetTransformation(gp::OX2d(),Axis.XAxis()); |
96 | type = GeomAbs_Parabola; |
97 | } |
98 | //====================================================================== |
99 | IntCurve_IConicTool::IntCurve_IConicTool(const gp_Hypr2d& H) { |
100 | Hypr_a = H.MajorRadius(); |
101 | Hypr_b = H.MinorRadius(); |
102 | Axis = H.Axis(); |
103 | Abs_To_Object.SetTransformation(gp::OX2d(),Axis.XAxis()); |
104 | type = GeomAbs_Hyperbola; |
105 | } |
106 | //---------------------------------------------------------------------- |
107 | gp_Pnt2d IntCurve_IConicTool::Value(const Standard_Real X) const { |
108 | switch(type) { |
109 | case GeomAbs_Line: return(ElCLib::LineValue(X,Axis.XAxis())); |
110 | case GeomAbs_Ellipse: return(ElCLib::EllipseValue(X,Axis,Elips_a,Elips_b)); |
111 | case GeomAbs_Circle: return(ElCLib::CircleValue(X,Axis,Circle_r)); |
112 | case GeomAbs_Parabola: return(ElCLib::ParabolaValue(X,Axis,Parab_f)); |
113 | case GeomAbs_Hyperbola: return(ElCLib::HyperbolaValue(X,Axis,Hypr_a,Hypr_b)); |
114 | default: { cout<<"### Erreur sur le type de la courbe ###"; |
115 | return(gp_Pnt2d(0.0,0.0)); } |
116 | } |
117 | } |
118 | |
119 | //---------------------------------------------------------------------- |
120 | void IntCurve_IConicTool::D1(const Standard_Real X, |
121 | gp_Pnt2d& Pt, |
122 | gp_Vec2d& Tan) const { |
123 | |
124 | switch(type) { |
125 | case GeomAbs_Line: ElCLib::LineD1(X,Axis.XAxis(),Pt,Tan); break; |
126 | case GeomAbs_Ellipse: ElCLib::EllipseD1(X,Axis,Elips_a,Elips_b,Pt,Tan); break; |
127 | case GeomAbs_Circle: ElCLib::CircleD1(X,Axis,Circle_r,Pt,Tan); break; |
128 | case GeomAbs_Parabola: ElCLib::ParabolaD1(X,Axis,Parab_f,Pt,Tan); break; |
129 | case GeomAbs_Hyperbola: ElCLib::HyperbolaD1(X,Axis,Hypr_a,Hypr_b,Pt,Tan); break; |
130 | default: { cout<<"### Erreur sur le type de la courbe ###"; } |
131 | } |
132 | } |
133 | |
134 | //---------------------------------------------------------------------- |
135 | void IntCurve_IConicTool::D2(const Standard_Real X, |
136 | gp_Pnt2d& Pt, |
137 | gp_Vec2d& Tan, |
138 | gp_Vec2d& Norm) const { |
139 | |
140 | switch(type) { |
141 | case GeomAbs_Line: ElCLib::LineD1(X,Axis.XAxis(),Pt,Tan); Norm.SetCoord(0.0,0.0); break; |
142 | case GeomAbs_Ellipse: ElCLib::EllipseD2(X,Axis,Elips_a,Elips_b,Pt,Tan,Norm); break; |
143 | case GeomAbs_Circle: ElCLib::CircleD2(X,Axis,Circle_r,Pt,Tan,Norm); break; |
144 | case GeomAbs_Parabola: ElCLib::ParabolaD2(X,Axis,Parab_f,Pt,Tan,Norm); break; |
145 | case GeomAbs_Hyperbola: ElCLib::HyperbolaD2(X,Axis,Hypr_a,Hypr_b,Pt,Tan,Norm); break; |
146 | default: { cout<<"### Erreur sur le type de la courbe ###"; } |
147 | } |
148 | } |
149 | //---------------------------------------------------------------------- |
150 | #define AN_ELIPS 0 |
151 | //---------------------------------------------------------------------- |
152 | Standard_Real IntCurve_IConicTool::Distance(const gp_Pnt2d& ThePoint) const { |
153 | |
154 | switch(type) { |
155 | case GeomAbs_Line: |
156 | { |
157 | return(Line_a*ThePoint.X()+Line_b*ThePoint.Y()+Line_c); |
158 | } |
159 | |
160 | case GeomAbs_Ellipse: |
161 | { |
162 | #if AN_ELIPS |
163 | gp_Pnt2d P=ThePoint; |
164 | P.Transform(Abs_To_Object); |
165 | Standard_Real x=P.X(); |
166 | Standard_Real y2=P.Y() * P.Y(); |
167 | return(sqrt(y2+(x+Elips_c)*(x+Elips_c)) |
168 | +sqrt(y2+(x-Elips_c)*(x-Elips_c))-Elips_a-Elips_a); |
169 | #else |
170 | gp_Pnt2d P=ThePoint; |
171 | P.Transform(Abs_To_Object); |
172 | Standard_Real x=P.X(); |
173 | Standard_Real y=P.Y()*(Elips_a/Elips_b); |
174 | Standard_Real d=sqrt(x*x+y*y)-Elips_a; |
175 | return(d); |
176 | #endif |
177 | } |
178 | |
179 | case GeomAbs_Circle: |
180 | { |
181 | Standard_Real Dx=Circle_x0-ThePoint.X(); |
182 | Standard_Real Dy=Circle_y0-ThePoint.Y(); |
183 | return(sqrt(Dx*Dx+Dy*Dy)-Circle_r); |
184 | } |
185 | |
186 | case GeomAbs_Parabola: |
187 | { //-- Distance(X,Y) = Y**2 - 2 P X |
188 | gp_Pnt2d P=ThePoint; |
189 | P.Transform(Abs_To_Object); |
190 | return(P.Y()*P.Y()-Parab_2p*P.X()); |
191 | } |
192 | |
193 | case GeomAbs_Hyperbola: |
194 | { //-- Distance(X,Y) = (X/a)**2 - (Y/b)**2 -1 |
195 | //-- pour x>0 |
196 | //-- -(Y/b)**2 - 1 sinon ?? |
197 | //-- avec un gradient avec x -> Abs(x) |
198 | gp_Pnt2d P=ThePoint; |
199 | P.Transform(Abs_To_Object); |
200 | if(P.X()>0.0) |
201 | return((P.X()*P.X())/Hypr_aa |
202 | -(P.Y()*P.Y())/Hypr_bb -1.0); |
203 | else |
204 | return((-P.X()*P.X())/Hypr_aa |
205 | -(P.Y()*P.Y())/Hypr_bb -1.0); |
206 | } |
207 | default: { cout<<"### Erreur sur le type de la courbe ###"; |
208 | return(0.0); } |
209 | } |
210 | } |
211 | |
212 | |
213 | gp_Vec2d IntCurve_IConicTool::GradDistance(const gp_Pnt2d& ThePoint) const { |
214 | |
215 | switch(type) { |
216 | case GeomAbs_Line: return(gp_Vec2d(Line_a,Line_b)); |
217 | |
218 | case GeomAbs_Circle: { |
219 | gp_Pnt2d P=ThePoint; |
220 | P.Transform(Abs_To_Object); |
221 | Standard_Real Gradx=0.0; |
222 | Standard_Real Grady=0.0; |
223 | Standard_Real x=P.X(); |
224 | Standard_Real y=P.Y(); |
225 | Standard_Real temp1=sqrt(y*y+x*x); |
226 | if(temp1) { |
227 | Gradx=x/temp1; |
228 | Grady=y/temp1; |
229 | } |
230 | gp_Vec2d Gradient(Gradx,Grady); |
231 | Gradient.Transform(Object_To_Abs); |
232 | return(Gradient); |
233 | } |
234 | case GeomAbs_Ellipse: { |
235 | #if AN_ELIPS |
236 | gp_Pnt2d P=ThePoint; |
237 | P.Transform(Abs_To_Object); |
238 | Standard_Real Gradx=0.0; |
239 | Standard_Real Grady=0.0; |
240 | Standard_Real x=P.X(); |
241 | Standard_Real y=P.Y(); |
242 | Standard_Real xmc=x-Elips_c; |
243 | Standard_Real xpc=x+Elips_c; |
244 | Standard_Real temp1=sqrt(y*y+xmc*xmc); |
245 | Standard_Real temp2=sqrt(y*y+xpc*xpc); |
246 | if(temp2) { |
247 | Gradx=xpc/temp2; |
248 | Grady=y/temp2; |
249 | } |
250 | if(temp1) { |
251 | Gradx+=xmc/temp1; |
252 | Grady+=y/temp1; |
253 | } |
254 | gp_Vec2d Gradient(Gradx,Grady); |
255 | Gradient.Transform(Object_To_Abs); |
256 | return(Gradient); |
257 | #else |
258 | gp_Pnt2d P=ThePoint; |
259 | P.Transform(Abs_To_Object); |
260 | Standard_Real Gradx=0.0; |
261 | Standard_Real Grady=0.0; |
262 | Standard_Real x=P.X(); |
263 | Standard_Real y=P.Y()*(Elips_a/Elips_b); |
264 | Standard_Real temp1=sqrt(y*y+x*x); |
265 | if(temp1) { |
266 | Gradx=x/temp1; |
267 | Grady=(y*(Elips_a/Elips_b))/temp1; |
268 | } |
269 | gp_Vec2d Gradient(Gradx,Grady); |
270 | Gradient.Transform(Object_To_Abs); |
271 | return(Gradient); |
272 | #endif |
273 | } |
274 | |
275 | case GeomAbs_Parabola: { //-- Distance(X,Y) = Y**2 - 2 P X |
276 | gp_Pnt2d P=ThePoint; |
277 | P.Transform(Abs_To_Object); |
278 | gp_Vec2d Gradient(-Parab_2p,P.Y()+P.Y()); |
279 | Gradient.Transform(Object_To_Abs); |
280 | return(Gradient); |
281 | } |
282 | case GeomAbs_Hyperbola: { //-- Distance(X,Y) = (X/a)**2 - (Y/b)**2 -1 |
283 | gp_Pnt2d P=ThePoint; |
284 | P.Transform(Abs_To_Object); |
285 | //--### la Branche a X negatif doit ramener vers les X positifs |
286 | gp_Vec2d Gradient(2.0*Abs(P.X())/Hypr_aa,-2.0*P.Y()/Hypr_bb); |
287 | Gradient.Transform(Object_To_Abs); |
288 | return(Gradient); |
289 | } |
290 | default: { cout<<"### Erreur sur le type de la courbe ###"; |
291 | return(gp_Vec2d(0.0,0.0)); } |
292 | } |
293 | } |
294 | |
295 | |
296 | Standard_Real IntCurve_IConicTool::FindParameter(const gp_Pnt2d& P) const { |
297 | |
298 | Standard_Real Param=0; |
299 | |
300 | switch(type) { |
301 | |
302 | case GeomAbs_Line: |
303 | Param=ElCLib::LineParameter(Axis.XAxis(),P); |
304 | break; |
305 | |
306 | case GeomAbs_Circle: |
307 | Param=ElCLib::CircleParameter(Axis,P); |
c6541a0c |
308 | if(Param<0.0) { Param+=M_PI+M_PI; } |
7fd59977 |
309 | break; |
310 | |
311 | case GeomAbs_Ellipse: { |
312 | Param=ElCLib::EllipseParameter(Axis |
313 | ,Elips_a |
314 | ,Elips_b |
315 | ,P); |
c6541a0c |
316 | if (Param < 0.0) { Param+=M_PI+M_PI; } |
7fd59977 |
317 | break; |
318 | } |
319 | |
320 | case GeomAbs_Parabola: { |
321 | Param=ElCLib::ParabolaParameter(Axis,P); |
322 | break; |
323 | } |
324 | case GeomAbs_Hyperbola: { |
325 | Param=ElCLib::HyperbolaParameter(Axis |
326 | ,Hypr_a |
327 | ,Hypr_b |
328 | ,P); |
329 | break; |
330 | } |
7fd59977 |
331 | default: |
332 | break; |
7fd59977 |
333 | } |
334 | |
335 | return(Param); |
336 | } |
337 | |
338 | |