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