0023939: Incorrect circle parameter in IntAna
[occt.git] / src / GeomliteTest / GeomliteTest_API2dCommands.cxx
1 // Created on: 1995-01-11
2 // Created by: Remi LEQUETTE
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
5 //
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
10 //
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 //
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
20
21 // modified : pmn 11/04/97 : mis dans GeomliteTest
22
23
24 #include <GeomliteTest.hxx>
25 #include <Geom2d_Curve.hxx>
26 #include <Draw.hxx>
27 #include <Draw_Interpretor.hxx>
28 #include <DrawTrSurf.hxx>
29 #include <Draw_Appli.hxx>
30 #include <DrawTrSurf_Curve2d.hxx>
31 #include <Geom2dAPI_ProjectPointOnCurve.hxx>
32 #include <Geom2dAPI_ExtremaCurveCurve.hxx>
33 #include <Geom2dAPI_PointsToBSpline.hxx>
34 #include <Geom2dAPI_InterCurveCurve.hxx>
35 #include <Geom2d_Line.hxx>
36 #include <Geom2d_TrimmedCurve.hxx>
37 #include <TColgp_Array1OfPnt2d.hxx>
38 #include <gp_Pnt.hxx>
39 #include <Draw_Marker2D.hxx>
40 #include <Draw_Color.hxx>
41 #include <Draw_MarkerShape.hxx>
42 #include <TColStd_Array1OfReal.hxx>
43 #include <GeomAbs_Shape.hxx>
44 #include <Precision.hxx>
45 #include <Geom2d_Circle.hxx>
46 #include <IntAna2d_AnaIntersection.hxx>
47 #include <IntAna2d_IntPoint.hxx>
48
49 #include <stdio.h>
50 #ifdef WNT
51 Standard_IMPORT Draw_Viewer dout;
52 #endif
53
54 //=======================================================================
55 //function : proj
56 //purpose  : 
57 //=======================================================================
58
59 static Standard_Integer proj (Draw_Interpretor& di, Standard_Integer n, const char** a)
60 {
61   if ( n < 4) return 1;
62
63   gp_Pnt2d P(Draw::Atof(a[2]),Draw::Atof(a[3]));
64
65   char name[100];
66
67   Handle(Geom2d_Curve) GC = DrawTrSurf::GetCurve2d(a[1]);
68
69   if (GC.IsNull())
70     return 1;
71
72   Geom2dAPI_ProjectPointOnCurve proj(P,GC,GC->FirstParameter(),
73                                           GC->LastParameter());
74   
75   for ( Standard_Integer i = 1; i <= proj.NbPoints(); i++) {
76     gp_Pnt2d P1 = proj.Point(i);
77     Handle(Geom2d_Line) L = new Geom2d_Line(P,gp_Vec2d(P,P1));
78     Handle(Geom2d_TrimmedCurve) CT = 
79       new Geom2d_TrimmedCurve(L, 0., P.Distance(P1));
80     Sprintf(name,"%s%d","ext_",i);
81     char* temp = name; // portage WNT
82     DrawTrSurf::Set(temp, CT);
83     di << name << " ";
84   }
85
86   return 0;
87 }
88
89 //=======================================================================
90 //function : appro
91 //purpose  : 
92 //=======================================================================
93
94 static Standard_Integer appro(Draw_Interpretor& di, Standard_Integer n, const char** a)
95 {
96   // Approximation et interpolation 2d
97
98   // 2dappro
99   //     - affiche la tolerance
100   // 2dappro tol
101   //     - change la tolerance
102   // 2dappro result nbpoint 
103   //     - saisie interactive
104   // 2dappro result nbpoint curve 
105   //     - calcule des points sur la courbe
106   // 2dappro result nbpoint x1 y1 x2 y2 .. 
107   //     - tableau de points
108   // 2dappro result nbpoint x1 dx y1 y2 ..
109   //     - tableau de points (x1,y1) (x1+dx,y2) ... avec x = t
110   
111
112   static Standard_Real Tol2d = 1.e-6;
113
114   if (n < 3) {
115     if (n == 2) 
116       Tol2d = Draw::Atof(a[1]);
117     
118     di << "Tolerance for 2d approx : "<< Tol2d << "\n";
119     return 0;
120   }
121
122
123   Standard_Integer i, Nb = Draw::Atoi(a[2]);
124   
125   Standard_Boolean hasPoints = Standard_True;
126   TColgp_Array1OfPnt2d Points(1, Nb);
127   TColStd_Array1OfReal YValues(1,Nb);
128   Standard_Real X0=0,DX=0;
129   
130   Handle(Draw_Marker2D) mark;
131   
132   if (n == 3)  {
133     // saisie interactive
134     Standard_Integer id,XX,YY,b;
135     dout.Select(id,XX,YY,b);
136     Standard_Real zoom = dout.Zoom(id);
137
138     Points(1) = gp_Pnt2d( ((Standard_Real)XX)/zoom, 
139                           ((Standard_Real)YY)/zoom );
140     
141     mark = new Draw_Marker2D( Points(1), Draw_X, Draw_vert); 
142     
143     dout << mark;
144     
145     for (i = 2; i<=Nb; i++) {
146       dout.Select(id,XX,YY,b);
147       Points(i) = gp_Pnt2d( ((Standard_Real)XX)/zoom, 
148                             ((Standard_Real)YY)/zoom );
149       mark = new Draw_Marker2D( Points(i), Draw_X, Draw_vert); 
150       dout << mark;
151     }
152   }    
153   else {
154     if ( n == 4) {
155     // points sur courbe
156       Handle(Geom2d_Curve) GC = DrawTrSurf::GetCurve2d(a[3]);
157       if ( GC.IsNull()) 
158         return 1;
159
160       Standard_Real U, U1, U2;
161       U1 = GC->FirstParameter();
162       U2 = GC->LastParameter();
163       Standard_Real Delta = ( U2 - U1) / (Nb-1);
164       for ( i = 1 ; i <= Nb; i++) {
165         U = U1 + (i-1) * Delta;
166         Points(i) = GC->Value(U);
167       }
168     }
169
170     else {
171       // test points ou ordonnees
172       hasPoints = Standard_False;
173       Standard_Integer nc = n - 3;
174       if (nc == 2 * Nb) {
175         // points
176         nc = 3;
177         for (i = 1; i <= Nb; i++) {
178           Points(i).SetCoord(Draw::Atof(a[nc]),Draw::Atof(a[nc+1]));
179           nc += 2;
180         }
181       }
182       else if (nc - 2 == Nb) {
183         // YValues
184         nc = 5;
185         X0 = Draw::Atof(a[3]);
186         DX = Draw::Atof(a[4]);
187         for (i = 1; i <= Nb; i++) {
188           YValues(i) = Draw::Atof(a[nc]);
189           Points(i).SetCoord(X0+(i-1)*DX,YValues(i));
190           nc++;
191         }
192       }
193       else
194         return 1;
195     }
196     // display the points
197     for ( i = 1 ; i <= Nb; i++) {
198       mark = new Draw_Marker2D( Points(i), Draw_X, Draw_vert); 
199       dout << mark;
200     }
201   }
202   dout.Flush();
203   Standard_Integer Dmin = 3;
204   Standard_Integer Dmax = 8;
205   
206   Handle(Geom2d_BSplineCurve) TheCurve;
207   if (hasPoints)
208     TheCurve = Geom2dAPI_PointsToBSpline(Points,Dmin,Dmax,GeomAbs_C2,Tol2d);
209   else
210     TheCurve = Geom2dAPI_PointsToBSpline(YValues,X0,DX,Dmin,Dmax,GeomAbs_C2,Tol2d);
211   
212   DrawTrSurf::Set(a[1], TheCurve);
213   di << a[1];
214
215   return 0;
216
217 }
218
219 //=======================================================================
220 //function : extrema
221 //purpose  : 
222 //=======================================================================
223
224 static Standard_Integer extrema(Draw_Interpretor& di, Standard_Integer n, const char** a)
225 {
226   if ( n<3) return 1;
227
228   Handle(Geom2d_Curve)   GC1, GC2;
229
230   Standard_Real U1f,U1l,U2f,U2l;
231
232   GC1 = DrawTrSurf::GetCurve2d(a[1]);
233   if ( GC1.IsNull())
234     return 1;
235   U1f = GC1->FirstParameter();
236   U1l = GC1->LastParameter();
237
238   GC2 = DrawTrSurf::GetCurve2d(a[2]);
239   if ( GC2.IsNull())
240     return 1;
241   U2f = GC2->FirstParameter();
242   U2l = GC2->LastParameter();
243
244   char name[100];
245
246   Geom2dAPI_ExtremaCurveCurve Ex(GC1,GC2,U1f,U1l,U2f,U2l);
247
248 // modified by APV (compilation error - LINUX)
249 //  for ( Standard_Integer i = 1; i <= Ex.NbExtrema(); i++) {
250   Standard_Integer i;
251   const Standard_Integer aNExtr = Ex.NbExtrema();
252   for ( i = 1; i <= aNExtr; i++) {
253 // modified by APV (compilation error - LINUX)
254
255     gp_Pnt2d P1,P2;
256     Ex.Points(i,P1,P2);
257     di << "dist " << i << ": " << Ex.Distance(i) << " \n";
258     if (Ex.Distance(i) <= Precision::PConfusion()) {
259       Handle(Draw_Marker2D) mark = new Draw_Marker2D( P1, Draw_X, Draw_vert); 
260       dout << mark;
261       dout.Flush();
262     }
263     else {
264       Handle(Geom2d_Line) L = new Geom2d_Line(P1,gp_Vec2d(P1,P2));
265       Handle(Geom2d_TrimmedCurve) CT = 
266         new Geom2d_TrimmedCurve(L, 0., P1.Distance(P2));
267       Sprintf(name,"%s%d","ext_",i);
268       char* temp = name; // portage WNT
269       DrawTrSurf::Set(temp, CT);
270       di << name << " ";
271     }
272   }
273   if (i==1)
274     di << "No solutions!\n";
275
276   return 0;
277 }
278
279
280 //=======================================================================
281 //function : intersect
282 //purpose  : 
283 //=======================================================================
284
285 static Standard_Integer intersect(Draw_Interpretor& di, Standard_Integer n, const char** a)
286 {
287   if( n < 2) 
288   {
289     cout<< "2dintersect curve curve [Tol]"<<endl;
290     return 1;
291   }
292   Standard_Integer k = 1;
293   Handle(Geom2d_Curve) C1 = DrawTrSurf::GetCurve2d(a[k++]);
294   if ( C1.IsNull()) 
295     return 1;
296
297   Standard_Real Tol = 0.001;
298   Geom2dAPI_InterCurveCurve Intersector;
299
300   Handle(Geom2d_Curve) C2;
301   if ( k < n ) {
302     C2 = DrawTrSurf::GetCurve2d(a[k++]);
303     if ( C2.IsNull())
304       return 1;
305   }
306   if(k < n)
307     Tol = Draw::Atof(a[k]);
308
309   if(!C2.IsNull())
310   {
311     Intersector.Init(C1,C2,Tol);
312   }
313   else {
314     Intersector.Init(C1, Tol);
315   }
316
317   Standard_Integer i;
318
319   for ( i = 1; i <= Intersector.NbPoints(); i++) {
320     gp_Pnt2d P = Intersector.Point(i);
321     di<<"Intersection point "<<i<<" : "<<P.X()<<" "<<P.Y()<<"\n";
322     Handle(Draw_Marker2D) mark = new Draw_Marker2D( P, Draw_X, Draw_vert); 
323     dout << mark;
324   }
325   dout.Flush();
326
327   Handle(Geom2d_Curve) S1,S2;
328   Handle(DrawTrSurf_Curve2d) CD;
329   for ( i = 1; i <= Intersector.NbSegments(); i++) {
330     Intersector.Segment(i,S1,S2);
331     CD = new DrawTrSurf_Curve2d(S1, Draw_bleu, 30);
332     dout << CD;
333     CD = new DrawTrSurf_Curve2d(S2, Draw_violet, 30);
334     dout << CD;
335   }
336   
337   dout.Flush();
338
339   return 0;
340 }
341
342 //=======================================================================
343 //function : intersect
344 //purpose  : 
345 //=======================================================================
346
347 static Standard_Integer intersect_ana(Draw_Interpretor& di, Standard_Integer n, const char** a)
348 {
349   if( n < 2) 
350   {
351     cout<< "2dintana circle circle "<<endl;
352     return 1;
353   }
354   
355   Handle(Geom2d_Curve) C1 = DrawTrSurf::GetCurve2d(a[1]);
356   if ( C1.IsNull() && !C1->IsKind(STANDARD_TYPE(Geom2d_Circle))) 
357     return 1;
358
359   Handle(Geom2d_Curve) C2 = DrawTrSurf::GetCurve2d(a[2]);
360   if ( C2.IsNull() && !C2->IsKind(STANDARD_TYPE(Geom2d_Circle)))
361     return 1;
362
363   Handle(Geom2d_Circle) aCir1 = Handle(Geom2d_Circle)::DownCast(C1);
364   Handle(Geom2d_Circle) aCir2 = Handle(Geom2d_Circle)::DownCast(C2);
365
366   IntAna2d_AnaIntersection Intersector(aCir1->Circ2d(), aCir2->Circ2d());
367
368   Standard_Integer i;
369
370   for ( i = 1; i <= Intersector.NbPoints(); i++) {
371     gp_Pnt2d P = Intersector.Point(i).Value();
372     di<<"Intersection point "<<i<<" : "<<P.X()<<" "<<P.Y()<<"\n";
373         di<<"parameter on the fist: "<<Intersector.Point(i).ParamOnFirst();
374         di<<" parameter on the second: "<<Intersector.Point(i).ParamOnSecond()<<"\n";
375     Handle(Draw_Marker2D) mark = new Draw_Marker2D( P, Draw_X, Draw_vert); 
376     dout << mark;
377   }
378   dout.Flush();
379
380   return 0;
381 }
382
383
384
385 void GeomliteTest::API2dCommands(Draw_Interpretor& theCommands)
386 {
387   static Standard_Boolean done = Standard_False;
388   if (done) return;
389
390   const char *g;
391
392   done = Standard_True;
393   g = "GEOMETRY curves and surfaces analysis";
394
395   theCommands.Add("2dproj", "proj curve x y",__FILE__, proj,g);
396
397   g = "GEOMETRY approximations";
398
399   theCommands.Add("2dapprox", "2dapprox result nbpoint [curve] [[x] y [x] y...]",__FILE__, 
400                   appro,g);
401   theCommands.Add("2dinterpole", "2dinterpole result nbpoint [curve] [[x] y [x] y ...]",__FILE__, 
402                   appro,g);
403
404   g = "GEOMETRY curves and surfaces analysis";
405
406   theCommands.Add("2dextrema", "extrema curve curve",__FILE__,
407                   extrema,g);
408
409   g = "GEOMETRY intersections";
410
411   theCommands.Add("2dintersect", "intersect curve curve [Tol]",__FILE__,
412                   intersect,g);
413
414   theCommands.Add("2dintanalytical", "intersect curve curve using IntAna",__FILE__,
415                   intersect_ana,g);
416 }