0022048: Visualization, AIS_InteractiveContext - single object selection should alway...
[occt.git] / src / IntCurve / IntCurve_IConicTool.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
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//======================================================================
55IntCurve_IConicTool::IntCurve_IConicTool(void) {
56//###### PLACER LE TYPE NON DEFINI ######
57}
58
59
60IntCurve_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//======================================================================
70IntCurve_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//======================================================================
76IntCurve_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//======================================================================
85IntCurve_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//======================================================================
94IntCurve_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//======================================================================
102IntCurve_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//----------------------------------------------------------------------
110gp_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//----------------------------------------------------------------------
123void 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//----------------------------------------------------------------------
138void 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//----------------------------------------------------------------------
155Standard_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
216gp_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
299Standard_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