0024573: Wrong result of 2d-offset algorithm on customer's shape
[occt.git] / src / Bisector / Bisector_BisecAna.cxx
CommitLineData
b311480e 1// Created on: 1992-10-19
2// Created by: Remi GILET
3// Copyright (c) 1992-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
973c2be1 8// This library is free software; you can redistribute it and / or modify it
9// under the terms of the GNU Lesser General Public version 2.1 as published
10// by the Free Software Foundation, with special exception defined in the file
11// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12// distribution for complete text of the license and disclaimer of any warranty.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
17// Modified by skv - Fri Jul 1 16:23:17 2005 IDEM(Airbus)
18// Modified by skv - Wed Jul 7 17:21:09 2004 IDEM(Airbus)
19
20#include <Bisector_BisecAna.ixx>
21#include <Geom2d_Line.hxx>
22#include <Geom2d_Circle.hxx>
23#include <Geom2d_Parabola.hxx>
24#include <Geom2d_Hyperbola.hxx>
25#include <Geom2d_Ellipse.hxx>
26#include <Geom2dAdaptor_Curve.hxx>
27#include <Geom2d_TrimmedCurve.hxx>
28#include <GccInt_IType.hxx>
29#include <GccInt_BLine.hxx>
30#include <GccAna_Circ2dBisec.hxx>
31#include <GccAna_Pnt2dBisec.hxx>
32#include <GccAna_CircLin2dBisec.hxx>
33#include <GccAna_Lin2dBisec.hxx>
34#include <GccAna_CircPnt2dBisec.hxx>
35#include <GccAna_LinPnt2dBisec.hxx>
36#include <gp.hxx>
37#include <gp_Pnt2d.hxx>
38#include <ElCLib.hxx>
39#include <StdFail_NotDone.hxx>
40#include <IntAna2d_AnaIntersection.hxx>
41#include <IntAna2d_IntPoint.hxx>
42#include <IntRes2d_Domain.hxx>
43#include <IntRes2d_Domain.hxx>
44#include <IntRes2d_IntersectionSegment.hxx>
45#include <Geom2dInt_GInter.hxx>
46#include <Standard_NotImplemented.hxx>
47#include <Precision.hxx>
48
49static Standard_Boolean Degenerate(Handle(GccInt_Bisec)& aBisector,
50 const Standard_Real Tolerance);
51
52//=============================================================================
53//function :
54//=============================================================================
55Bisector_BisecAna::Bisector_BisecAna()
56{
57}
58
59//=============================================================================
0d969553
Y
60// calcul the distance betweem the point and the bissectrice. +
61// and orientation of the bissectrice. +
62// apoint : point of passage. +
63// abisector : calculated bissectrice. +
64// afirstvector : first vector. \ +
65// asecondvector : second vector./ to choose the proper sector. +
66// adirection : shows if the bissectrice is interior or exterior. +
67// aparameter : out : the start parameter of the bissectrice. +
68// asense : out : the direction of the bissectrice. +
69// astatus : out : shows if the bissectrice is preserved. +
7fd59977 70//=============================================================================
71Standard_Real Bisector_BisecAna::Distance (
72 const gp_Pnt2d& apoint,
73 const Handle(GccInt_Bisec)& abisector,
74 const gp_Vec2d& afirstvector ,
75 const gp_Vec2d& asecondvector,
76 const Standard_Real adirection,
77 Standard_Real& aparameter,
78 Standard_Boolean& asense,
79 Standard_Boolean& astatus)
80{
81 astatus = Standard_True;
82
83 gp_Hypr2d gphyperbola;
84 gp_Parab2d gpparabola ;
85 gp_Elips2d gpellipse ;
86 gp_Circ2d gpcircle ;
87 gp_Lin2d gpline ;
88
89 Standard_Real distance = 0.;
90 gp_Vec2d tangent;
91 gp_Pnt2d point;
92
93 GccInt_IType type = abisector->ArcType();
94
95 if (type == GccInt_Lin) {
96 gpline = abisector->Line();
97 aparameter = ElCLib::Parameter(gpline,apoint);
98 ElCLib::D1(aparameter,gpline,point,tangent);
99 }
100 else if (type == GccInt_Cir) {
101 gpcircle = abisector->Circle();
102 aparameter = ElCLib::Parameter(gpcircle,apoint);
103 ElCLib::D1(aparameter,gpcircle,point,tangent);
104 }
105 else if (type == GccInt_Hpr) {
106 gphyperbola = abisector->Hyperbola();
107 aparameter = ElCLib::Parameter(gphyperbola,apoint);
108 ElCLib::D1(aparameter,gphyperbola,point,tangent);
109 }
110 else if (type == GccInt_Par) {
111 gpparabola = abisector->Parabola();
112 aparameter = ElCLib::Parameter(gpparabola,apoint);
113 ElCLib::D1(aparameter,gpparabola,point,tangent);
114 }
115 else if (type == GccInt_Ell) {
116 gpellipse = abisector->Ellipse();
117 aparameter = ElCLib::Parameter(gpellipse,apoint);
118 ElCLib::D1(aparameter,gpellipse,point,tangent);
119 }
120
121 distance = apoint.Distance(point);
122
123 gp_Dir2d afirstdir (afirstvector);
124 gp_Dir2d aseconddir(asecondvector);
125 gp_Dir2d tangdir (tangent);
126 gp_Dir2d secdirrev = aseconddir.Reversed();
127
128
0d969553 129// 1st passage to learn if the curve is in the proper sector
7fd59977 130
131 if(asense) {
0d969553
Y
132 // the status is determined only in case on curve ie:
133 // tangent to the bissectrice is bisectrice of two vectors.
7fd59977 134 Standard_Real SinPlat = 1.e-3;
0d969553
Y
135 if (Abs(afirstdir^aseconddir) < SinPlat) { //flat
136 if (afirstdir*aseconddir >= 0.0) { //tangent mixed
137 // correct if the scalar product is close to 1.
7fd59977 138 if (Abs(tangdir*afirstdir) < 0.5) {
139 astatus = Standard_False;
140 }
141 }
0d969553
Y
142 else { // opposed tangents.
143 // correct if the scalar product is close to 0.
7fd59977 144 if (Abs(tangdir*afirstdir) > 0.5 ) {
145 astatus = Standard_False;
146 }
147 }
148 }
149 else if ((afirstdir^tangdir)*(tangdir^aseconddir) < -1.E-8) {
150 astatus = Standard_False;
151 }
152 }
153 else {
154 asense = Standard_True;
155
156// Modified by Sergey KHROMOV - Tue Oct 22 16:35:51 2002 Begin
157// Replacement of -1.E-8 for a tolerance 1.e-4
158 Standard_Real aTol = 1.e-4;
159
0d969553 160 if ((afirstdir^secdirrev)*adirection < -0.1) { // input
7fd59977 161 if((afirstdir^tangdir)*adirection < aTol &&
162 (secdirrev^tangdir)*adirection < aTol) asense = Standard_False;
163 }
0d969553 164 else if((afirstdir^secdirrev)*adirection > 0.1) { // output
7fd59977 165 if((afirstdir^tangdir)*adirection < aTol ||
166 (secdirrev^tangdir)*adirection < aTol) asense = Standard_False;
167 }
0d969553 168 else { // flat
7fd59977 169 if (afirstdir.Dot(secdirrev) > 0.) { // tangent
170 if ((afirstdir^tangdir)*adirection < 0.) asense = Standard_False;
171 }
0d969553 172 else{ // turn back
7fd59977 173// Modified by Sergey KHROMOV - Thu Oct 31 14:16:53 2002
174// if ((afirstdir.Dot(tangdir))*adirection > 0.) asense = Standard_False;
175 if (afirstdir.Dot(tangdir) < 0.) asense = Standard_False;
176// Modified by Sergey KHROMOV - Thu Oct 31 14:16:54 2002
177 }
178 }
179// Modified by Sergey KHROMOV - Tue Oct 22 16:35:51 2002 End
180 }
181 return distance;
182}
183
184//===========================================================================
0d969553 185// calculate the bissectrice between two curves coming from a point. +
7fd59977 186// +
0d969553
Y
187// afirstcurve : \ curves the bissectrice between which will be calculated. +
188// asecondcurve : / +
189// apoint : point through which the bissectrice should pass. +
190// afirstvector : \ vectors to find the sector where +
191// asecondvector : / the bissectrice should be located. +
192// adirection : shows the side of the bissectrice to be preserved. +
193// tolerance : threshold starting from which the bisectrices are degenerated +
7fd59977 194//===========================================================================
195void Bisector_BisecAna::Perform(const Handle(Geom2d_Curve)& afirstcurve ,
196 const Handle(Geom2d_Curve)& asecondcurve ,
197 const gp_Pnt2d& apoint ,
198 const gp_Vec2d& afirstvector ,
199 const gp_Vec2d& asecondvector ,
200 const Standard_Real adirection ,
201 const Standard_Real tolerance ,
202 const Standard_Boolean oncurve )
203{
204
205 Standard_Boolean ok;
206 Standard_Real distanceptsol,parameter,firstparameter =0.;
96a95605 207 Standard_Boolean thesense = Standard_False,sense;
7fd59977 208 Standard_Real distancemini;
209 Standard_Integer nbsolution;
210 Standard_Real PreConf = Precision::Confusion();
211
212 Handle(Standard_Type) type1 = afirstcurve->DynamicType();
213 Handle(Standard_Type) type2 = asecondcurve->DynamicType();
214 Handle(Geom2d_Curve) CurveF;
215 Handle(Geom2d_Curve) CurveE;
216 Handle(GccInt_Bisec) TheSol;
217
218 gp_Vec2d tan1 = afirstcurve->DN(afirstcurve->LastParameter (),1);
219 gp_Vec2d tan2 = asecondcurve->DN(asecondcurve->FirstParameter(),1);
220 tan1.Reverse();
221
222 if (type1 == STANDARD_TYPE(Geom2d_TrimmedCurve))
223 CurveF = Handle(Geom2d_TrimmedCurve)::DownCast(afirstcurve)->BasisCurve();
224 else
225 CurveF = afirstcurve;
226
227 if (type2 == STANDARD_TYPE(Geom2d_TrimmedCurve))
228 CurveE = Handle(Geom2d_TrimmedCurve)::DownCast(asecondcurve)->BasisCurve();
229 else
230 CurveE = asecondcurve;
231
232 type1 = CurveF->DynamicType();
233 type2 = CurveE->DynamicType();
234 Standard_Integer cas =0;
235 gp_Circ2d circle1,circle2;
236 gp_Lin2d line1,line2;
237
238//=============================================================================
0d969553 239// Determination of the nature of arguments. +
7fd59977 240//=============================================================================
241
242 if (type1 == STANDARD_TYPE(Geom2d_Circle)) {
243 if (type2 == STANDARD_TYPE(Geom2d_Circle)) {
244 cas = 1;
245 Handle(Geom2d_Circle) C1 = Handle(Geom2d_Circle)::DownCast(CurveF);
246 circle1 = C1->Circ2d();
247 Handle(Geom2d_Circle) C2 = Handle(Geom2d_Circle)::DownCast(CurveE);
248 circle2 = C2->Circ2d();
249 }
250 else if (type2 == STANDARD_TYPE(Geom2d_Line)) {
251 cas = 2;
252 Handle(Geom2d_Circle) C1 = Handle(Geom2d_Circle)::DownCast(CurveF);
253 circle1 = C1->Circ2d();
254 Handle(Geom2d_Line) L2 = Handle(Geom2d_Line)::DownCast(CurveE);
255 line2 = L2->Lin2d();
256 }
257 else {
258 cout << "Not yet implemented" << endl;
259 }
260 }
261 else if (type1 == STANDARD_TYPE(Geom2d_Line)) {
262 if (type2 == STANDARD_TYPE(Geom2d_Circle)) {
263 cas = 2;
264 Handle(Geom2d_Circle) C1 = Handle(Geom2d_Circle)::DownCast(CurveE);
265 circle1 = C1->Circ2d();
266 Handle(Geom2d_Line) L2 = Handle(Geom2d_Line)::DownCast(CurveF);
267 line2 = L2->Lin2d();
268 }
269 else if (type2 == STANDARD_TYPE(Geom2d_Line)) {
270 cas = 3;
271 Handle(Geom2d_Line) L1 = Handle(Geom2d_Line)::DownCast(CurveF);
272 line1 = L1->Lin2d();
273 Handle(Geom2d_Line) L2 = Handle(Geom2d_Line)::DownCast(CurveE);
274 line2 = L2->Lin2d();
275 }
276 else {
277 cout << "Not yet implemented" << endl;
278 }
279 }
280 else {
281 cout << "Not yet implemented" << endl;
282 }
283
284 switch(cas) {
285
286//=============================================================================
0d969553 287// Bissectrice circle - circle. +
7fd59977 288//=============================================================================
289
290 case 1 : {
291 Standard_Real radius1 = circle1.Radius();
292 Standard_Real radius2 = circle2.Radius();
293
294 //-----------------------------------------------------
0d969553 295 // Particular case when two circles are mixed.
7fd59977 296 //-----------------------------------------------------
297 if (circle1.Location().IsEqual(circle2.Location(),PreConf)&&
298 (Abs(radius1 - radius2) <= PreConf)){
299 gp_Pnt2d P1 = afirstcurve ->Value(afirstcurve ->LastParameter());
300 gp_Pnt2d P2 = asecondcurve->Value(asecondcurve->FirstParameter());
301 gp_Pnt2d PMil;
302 gp_Lin2d line;
303 PMil = gp_Pnt2d((P1.X() + P2.X())/2.,
304 (P1.Y() + P2.Y())/2.);
305// Modified by skv - Fri Jul 1 16:23:32 2005 IDEM(Airbus) Begin
306// line = gp_Lin2d(PMil,
307// gp_Dir2d(circle1.Location().X() - PMil.X(),
308// circle1.Location().Y() - PMil.Y()));
309 if (!circle1.Location().IsEqual(PMil,PreConf)) {
310 // PMil doesn't coinside with the circle location.
311 line = gp_Lin2d(PMil,
312 gp_Dir2d(circle1.Location().X() - PMil.X(),
313 circle1.Location().Y() - PMil.Y()));
314 } else if (radius1 >= PreConf) {
315 // PMil coinsides with the circle location and radius is greater then 0.
316 line = gp_Lin2d(circle1.Location(),
317 gp_Dir2d(P1.Y() - circle1.Location().Y(),
318 circle1.Location().X() - P1.X()));
319 } else {
320 // radius is equal to 0. No matter what direction to chose.
321 line = gp_Lin2d(circle1.Location(), gp_Dir2d(1., 0.));
322 }
323// Modified by skv - Fri Jul 1 16:23:32 2005 IDEM(Airbus) End
324 Handle(GccInt_Bisec) solution = new GccInt_BLine(line);
325 sense = Standard_False;
326// Modified by skv - Tue Feb 15 17:51:29 2005 Integration Begin
327// distanceptsol = Distance(apoint,solution,
328// afirstvector,asecondvector,
329// adirection,parameter,sense,ok);
330 if (oncurve)
331 distanceptsol = Distance(apoint,solution,
332 tan2,tan1,
333 adirection,parameter,sense,ok);
334 else
335 distanceptsol = Distance(apoint,solution,
336 afirstvector,asecondvector,
337 adirection,parameter,sense,ok);
338// Modified by skv - Tue Feb 15 17:51:29 2005 Integration End
339 Handle(Geom2d_Curve) bisectorcurve = new Geom2d_Line(line);
340 if (!sense)
341 thebisector =new Geom2d_TrimmedCurve(bisectorcurve,
342 parameter,
343 - Precision::Infinite());
344 else {
345 Standard_Real parameter2;
346 parameter2 = ElCLib::Parameter(line,circle1.Location());
347 parameter2 += 1.e-8;
348 thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
349 parameter,
350 parameter2);
351 }
352 break;
0d969553 353 } //end of case mixed circles.
7fd59977 354
355 if (radius1 < radius2) {
356 gp_Circ2d circle = circle1;
357 circle1 = circle2;
358 circle2 = circle;
359
360 Standard_Real radius = radius1;
361 radius1 = radius2;
362 radius2 = radius;
363 }
364
0d969553
Y
365 // small reframing of circles. in the case when the circles
366 // are OnCurve , if they are almost tangent they become tangent.
7fd59977 367 Standard_Real EntreAxe = circle1.Location().Distance(circle2.Location());
368 Standard_Real D1 = 0.5*(radius1 - EntreAxe - radius2);
369 Standard_Boolean CirclesTangent = Standard_False;
370
371// Modified by Sergey KHROMOV - Thu Oct 31 12:42:21 2002 End
372// if ( oncurve && Abs(D1) < PreConf) {
373 if ( oncurve && Abs(D1) < PreConf && tan1.IsParallel(tan2, 1.e-8)) {
374// Modified by Sergey KHROMOV - Thu Oct 31 12:42:22 2002 Begin
0d969553 375 // C2 included in C1 and tangent.
7fd59977 376 circle1.SetRadius(radius1 - D1);
377 circle2.SetRadius(radius2 + D1);
378 CirclesTangent = Standard_True;
379 }
380 else {
381 D1 = 0.5*(radius1 - EntreAxe + radius2);
382// Modified by Sergey KHROMOV - Thu Oct 31 12:44:24 2002 Begin
383// if (oncurve && Abs(D1) < PreConf) {
384 if (oncurve && Abs(D1) < PreConf && tan1.IsParallel(tan2, 1.e-8)) {
385// Modified by Sergey KHROMOV - Thu Oct 31 12:44:25 2002 End
0d969553 386 // C2 and C1 tangent and disconnected.
7fd59977 387 circle1.SetRadius(radius1 - D1);
388 circle2.SetRadius(radius2 - D1);
389 CirclesTangent = Standard_True;
390 }
0d969553 391 } // end of reframing.
7fd59977 392
393 GccAna_Circ2dBisec Bisector(circle1,circle2);
394
395 distancemini = Precision::Infinite();
396
397 if (Bisector.IsDone()) {
398 nbsolution = Bisector.NbSolutions();
399 for (Standard_Integer i = 1; i <= nbsolution; i++) {
400 Handle(GccInt_Bisec) solution = Bisector.ThisSolution(i);
401 Degenerate(solution,tolerance);
402 sense = Standard_True;
403 if (oncurve) {
404 distanceptsol = Distance(apoint,solution,
405 tan1,tan2,
406 adirection,parameter,sense,ok);
407 }
408 else {ok = Standard_True;}
409
7fd59977 410 if (ok) {
411 sense = Standard_False;
412// Modified by skv - Tue Feb 15 17:51:29 2005 Integration Begin
413// distanceptsol = Distance(apoint,solution,
414// afirstvector,asecondvector,
415// adirection,parameter,sense,ok);
416 if (oncurve)
417 distanceptsol = Distance(apoint,solution,
418 tan2,tan1,
419 adirection,parameter,sense,ok);
420 else
421 distanceptsol = Distance(apoint,solution,
422 afirstvector,asecondvector,
423 adirection,parameter,sense,ok);
424// Modified by skv - Tue Feb 15 17:51:29 2005 Integration End
425 if (distanceptsol <= distancemini) {
426 TheSol = solution;
427 firstparameter = parameter;
428 thesense = sense;
429 distancemini = distanceptsol;
430 }
431 }
432 }
433 if (!TheSol.IsNull()) {
434 Handle(Geom2d_Curve) bisectorcurve;
435 GccInt_IType type = TheSol->ArcType();
436 if (type == GccInt_Lin) {
437 gp_Lin2d gpline = TheSol->Line();
438 bisectorcurve = new Geom2d_Line(gpline);
439
440 Standard_Real secondparameter = Precision::Infinite();
441 if (!thesense) secondparameter = - Precision::Infinite();
442
443 if (oncurve) {
0d969553
Y
444 // bisectrice right and oncurve
445 // is cut between two circle of the same radius if circles are tangent.
446
447 // if tangent flat and the bissectrice at the side of the concavity
448 // of one of the circles. the bissectrice is a segment of the point common to
449 // first of 2 centers of circle that it meets.
450 // in this case it is important to set a segmnent for
451 // intersection in Tool2d.
7fd59977 452
453 if (CirclesTangent) {
454 // Modified by skv - Tue Apr 13 17:23:31 2004 IDEM(Airbus) Begin
455 // Trying to correct the line if the distance between it
456 // and the reference point is too big.
457 if (distancemini > tolerance) {
458 gp_Pnt2d aPloc = gpline.Location();
459 gp_Dir2d aNewDir(apoint.XY() - aPloc.XY());
460 gp_Lin2d aNewLin(aPloc, aNewDir);
461 gp_Pnt2d aCC2 = circle2.Location();
462 Standard_Real aNewDMin = aNewLin.Distance(apoint);
463 Standard_Real aTolConf = 1.e-3;
464 // Hope, aNewDMin is equal to 0...
465
466 if (aNewLin.Distance(aCC2) <= aTolConf) {
467 distancemini = aNewDMin;
468 firstparameter = ElCLib::Parameter(aNewLin, apoint);
469 bisectorcurve = new Geom2d_Line(aNewLin);
470 }
471 }
472 // Modified by skv - Tue Apr 13 17:23:32 2004 IDEM(Airbus) End
473 if (tan1.Dot(tan2) < 0.) {
0d969553 474 // flat and not turn back.
7fd59977 475 Standard_Real Par1 = ElCLib::Parameter(gpline, circle1.Location());
476 Standard_Real Par2 = ElCLib::Parameter(gpline, circle2.Location());
477 Standard_Real MinPar = Min(Par1,Par2);
478 Standard_Real MaxPar = Max(Par1,Par2);
479
480 if (!thesense) {
481 if (MaxPar < firstparameter)
482 secondparameter = MaxPar - 1.E-8;
483 else if (MinPar < firstparameter)
484 secondparameter = MinPar - 1.E-8;
485 }
486 else {
487 if (MinPar > firstparameter)
488 secondparameter = MinPar + 1.E-8;
489 else if (MaxPar > firstparameter)
490 secondparameter = MaxPar + 1.E-8;
491 }
492 }
493 }
494 }
495
496 thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
497 firstparameter,
498 secondparameter);
499 }
500 else if (type == GccInt_Cir) {
501 bisectorcurve = new Geom2d_Circle(TheSol->Circle());
502 if (!thesense)
503 thebisector = new Geom2d_TrimmedCurve
c6541a0c 504 (bisectorcurve,firstparameter-2.0*M_PI,firstparameter,thesense);
7fd59977 505 else
506 thebisector = new Geom2d_TrimmedCurve
c6541a0c 507 (bisectorcurve,firstparameter,firstparameter+2.0*M_PI,thesense);
7fd59977 508 }
509 else if (type == GccInt_Hpr) {
510 bisectorcurve = new Geom2d_Hyperbola(TheSol->Hyperbola());
511 if (!thesense)
512 thebisector = new Geom2d_TrimmedCurve
513 (bisectorcurve,firstparameter, - Precision::Infinite());
514 else
515 thebisector = new Geom2d_TrimmedCurve
516 (bisectorcurve,firstparameter,Precision::Infinite());
517 }
518 else if (type == GccInt_Ell) {
519 bisectorcurve = new Geom2d_Ellipse(TheSol->Ellipse());
520 if (!thesense)
521 thebisector = new Geom2d_TrimmedCurve
c6541a0c 522 (bisectorcurve,firstparameter-2.0*M_PI,firstparameter,thesense);
7fd59977 523 else
524 thebisector = new Geom2d_TrimmedCurve
c6541a0c 525 (bisectorcurve,firstparameter,firstparameter+2.0*M_PI,thesense);
7fd59977 526 }
527 }
528 }
529 }
530 break;
531
532//=============================================================================
0d969553 533// Bissectrice circle - straight. +
7fd59977 534//=============================================================================
535
536 case 2 : {
0d969553
Y
537 // small reframing of circles. in case OnCurve.
538 // If the circle and the straight line are almost tangent they become tangent.
7fd59977 539 if (oncurve) {
540 Standard_Real radius1 = circle1.Radius();
541 Standard_Real D1 = (line2.Distance(circle1.Location()) - radius1);
542// Modified by Sergey KHROMOV - Wed Oct 30 14:48:43 2002 Begin
543// if (Abs(D1) < PreConf) {
544 if (Abs(D1) < PreConf && tan1.IsParallel(tan2, 1.e-8)) {
545// Modified by Sergey KHROMOV - Wed Oct 30 14:48:44 2002 End
546 circle1.SetRadius(radius1+D1);
547 }
548 }
549
550 GccAna_CircLin2dBisec Bisector(circle1,line2);
551
552 distancemini = Precision::Infinite();
553
554 if (Bisector.IsDone()) {
555 nbsolution = Bisector.NbSolutions();
556 for (Standard_Integer i = 1; i <= nbsolution; i++) {
557 Handle(GccInt_Bisec) solution = Bisector.ThisSolution(i);
558 Degenerate(solution,tolerance);
559 sense = Standard_True;
560 distanceptsol = Distance(apoint,solution,tan1,tan2,
561 adirection,parameter,sense,ok);
7fd59977 562 if (ok || !oncurve) {
563 sense = Standard_False;
564// Modified by skv - Tue Feb 15 17:51:29 2005 Integration Begin
565// distanceptsol = Distance(apoint,solution,
566// afirstvector,asecondvector,
567// adirection,parameter,sense,ok);
568 if (oncurve)
569 distanceptsol = Distance(apoint,solution,
570 tan2,tan1,
571 adirection,parameter,sense,ok);
572 else
573 distanceptsol = Distance(apoint,solution,
574 afirstvector,asecondvector,
575 adirection,parameter,sense,ok);
576// Modified by skv - Tue Feb 15 17:51:29 2005 Integration End
577 if (distanceptsol <= distancemini) {
578 TheSol = solution;
579 firstparameter = parameter;
580 thesense = sense;
581 distancemini = distanceptsol+1.e-8;
582 }
583 }
584 }
585 if (!TheSol.IsNull()) {
586 GccInt_IType type = TheSol->ArcType();
587 Handle(Geom2d_Curve) bisectorcurve;
588 if (type == GccInt_Lin) {
589 // -----------------------------------------------------------------
0d969553
Y
590 // If the bisectrice is a line
591 // => the straight line is tangent to the circle.
592 // It the part of bisectrice concerned is at the side of the center.
593 // => the bisectrice is limited by the point and the center of the circle.
594 // Note : In the latter case the bisectrice is a degenerated parabole.
7fd59977 595 // -----------------------------------------------------------------
596 gp_Pnt2d circlecenter;
597 gp_Lin2d gpline;
598 Standard_Real secondparameter;
599
600 circlecenter = circle1.Location();
601 gpline = TheSol->Line();
602 secondparameter = ElCLib::Parameter(gpline, circlecenter);
603 bisectorcurve = new Geom2d_Line(gpline);
604
605 if (!thesense) {
606 if (secondparameter > firstparameter) {
607 secondparameter = - Precision::Infinite();
608 }
609 else {
610 secondparameter = secondparameter - 1.E-8;
611 }
612 }
613 else {
614 if (secondparameter < firstparameter) {
615 secondparameter = Precision::Infinite();
616 }
617 else {
618 secondparameter = secondparameter + 1.E-8;
619 }
620 }
621
622 thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
623 firstparameter,
624 secondparameter);
625 }
626 else if (type == GccInt_Par) {
627 bisectorcurve = new Geom2d_Parabola(TheSol->Parabola());
628 if (!thesense)
629 thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
630 firstparameter,
631 - Precision::Infinite());
632 else
633 thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
634 firstparameter,
635 Precision::Infinite());
636 }
637 }
638 }
639 }
640 break;
641
642//=============================================================================
0d969553 643// Bissectrice straight - straight. +
7fd59977 644//=============================================================================
645 case 3 : {
646 gp_Dir2d Direc1(line1.Direction());
647 gp_Dir2d Direc2(line2.Direction());
648 gp_Lin2d line;
649 distancemini = Precision::Infinite();
650
651// Modified by Sergey KHROMOV - Tue Sep 10 15:58:43 2002 Begin
652// Change to the same criterion as in MAT2d_Circuit.cxx:
653// method MAT2d_Circuit::InitOpen(..)
654// if (Direc1.IsParallel(Direc2,RealEpsilon())) {
655 if (Direc1.IsParallel(Direc2,1.e-8)) {
656// Modified by Sergey KHROMOV - Tue Sep 10 15:58:45 2002 End
657 if (line1.Distance(line2.Location())/2. <= Precision::Confusion())
658 line = gp_Lin2d(apoint,gp_Dir2d(-line1.Direction().Y(),
659 line1.Direction().X()));
660 else
661 line = gp_Lin2d(apoint,line2.Direction());
662
663 Handle(GccInt_Bisec) solution = new GccInt_BLine(line);
664// Modified by skv - Wed Jul 7 17:21:09 2004 IDEM(Airbus) Begin
665// sense = Standard_True;
666// distanceptsol = Distance(apoint,solution,
667// tan1,tan2,
668// adirection,parameter,sense,ok);
669// theSense = sense;
670// if (ok || !oncurve) {
671 sense = Standard_False;
672// Modified by skv - Tue Feb 15 17:51:29 2005 Integration Begin
673// distanceptsol = Distance(apoint,solution,
674// afirstvector,asecondvector,
675// adirection,parameter,sense,ok);
676 if (oncurve)
677 distanceptsol = Distance(apoint,solution,
678 tan2,tan1,
679 adirection,parameter,sense,ok);
680 else
681 distanceptsol = Distance(apoint,solution,
682 afirstvector,asecondvector,
683 adirection,parameter,sense,ok);
684// Modified by skv - Tue Feb 15 17:51:29 2005 Integration End
685// if (distanceptsol <= distancemini) {
686 firstparameter = parameter;
687 Handle(Geom2d_Curve) bisectorcurve;
688 bisectorcurve = new Geom2d_Line(line);
689 if (!sense)
690 thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
691 firstparameter,
692 - Precision::Infinite());
693 else
694 thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
695 firstparameter,
696 Precision::Infinite());
697// }
698// }
699// Modified by skv - Wed Jul 7 17:21:09 2004 IDEM(Airbus) End
700 }
701 else {
702 gp_Lin2d l(apoint,gp_Dir2d(Direc2.XY()-Direc1.XY()));
703 Handle(GccInt_Bisec) solution = new GccInt_BLine(l);
704 Standard_Boolean ok;
705 sense = Standard_False;
706// Modified by skv - Tue Feb 15 17:51:29 2005 Integration Begin
707// distanceptsol = Distance(apoint,solution,
708// afirstvector,asecondvector,
709// adirection,parameter,sense,ok);
710 if (oncurve)
711 distanceptsol = Distance(apoint,solution,
712 tan2,tan1,
713 adirection,parameter,sense,ok);
714 else
715 distanceptsol = Distance(apoint,solution,
716 afirstvector,asecondvector,
717 adirection,parameter,sense,ok);
718// Modified by skv - Tue Feb 15 17:51:29 2005 Integration End
719 if (ok || !oncurve) {
720 thesense = sense;
721 distancemini = distanceptsol;
722 }
723 TheSol = new GccInt_BLine(l);
724 Handle(Geom2d_Curve) bisectorcurve;
725 bisectorcurve = new Geom2d_Line(TheSol->Line());
726 if (!thesense)
727 thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
728 0.,- Precision::Infinite());
729 else
730 thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
731 0., Precision::Infinite());
732 }
733 }
734 break;
735
736 default :
737 StdFail_NotDone::Raise();
738 break;
739 }
740}
741
742
743//===========================================================================
0d969553 744// calculate the bissectrice between a curve and a point and starting in a point. +
7fd59977 745// +
0d969553
Y
746// afirstcurve : \ curve and point the bissectrice between which is calculated +
747// asecondpoint : / +
748// apoint : point through which the bissectrice should pass. +
749// afirstvector : \ vectors to determine the sector in which +
750// asecondvector : / the bissectrice should be located. +
751// adirection : shows the side of the bissectrice to be preserved. +
752// tolerance : threshold starting from which the bisectrices are degenerated+
7fd59977 753//===========================================================================
754
755void Bisector_BisecAna::Perform(const Handle(Geom2d_Curve)& afirstcurve ,
756 const Handle(Geom2d_Point)& asecondpoint ,
757 const gp_Pnt2d& apoint ,
758 const gp_Vec2d& afirstvector ,
759 const gp_Vec2d& asecondvector,
760 const Standard_Real adirection ,
761 const Standard_Real tolerance ,
762 const Standard_Boolean oncurve )
763{
764 Standard_Boolean ok;
96a95605 765 Standard_Boolean thesense = Standard_False,sense;
7fd59977 766 Standard_Real distanceptsol,parameter,firstparameter =0.,secondparameter;
767 Handle(Geom2d_Curve) curve;
768 Handle(GccInt_Bisec) TheSol;
769
770 gp_Circ2d circle;
771 gp_Lin2d line;
772 gp_Pnt2d circlecenter;
773
774 Standard_Integer cas = 0;
775
776 Handle(Standard_Type) type = afirstcurve->DynamicType();
777
778 if (type == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
779 curve = (*(Handle_Geom2d_TrimmedCurve*)&afirstcurve)->BasisCurve();
780 }
781 else {
782 curve = afirstcurve;
783 }
784
785 type = curve->DynamicType();
786#ifdef DEB
787 gp_Pnt2d Point(asecondpoint->Pnt2d());
788#else
789 asecondpoint->Pnt2d();
790#endif
791 if (type == STANDARD_TYPE(Geom2d_Circle)) {
792 cas = 1;
793 Handle(Geom2d_Circle) C1 = Handle(Geom2d_Circle)::DownCast(curve);
794 circle = C1->Circ2d();
795 }
796 else if (type == STANDARD_TYPE(Geom2d_Line)) {
797 cas = 2;
798 Handle(Geom2d_Line) L1 = Handle(Geom2d_Line)::DownCast(curve);
799 line = L1->Lin2d();
800 }
801 else {
802 cout << "Not yet implemented" << endl;
803 }
804
805 switch(cas) {
806
807//=============================================================================
0d969553 808// Bissectrice point - circle. +
7fd59977 809//=============================================================================
810 case 1 : {
8a6db25a 811 GccAna_CircPnt2dBisec Bisector(circle, asecondpoint->Pnt2d(), tolerance);
7fd59977 812 Standard_Real distancemini = Precision::Infinite();
813 if (Bisector.IsDone()) {
814 Standard_Integer nbsolution = Bisector.NbSolutions();
815 for (Standard_Integer i = 1; i <= nbsolution; i++) {
816 Handle(GccInt_Bisec) solution = Bisector.ThisSolution(i);
817 Degenerate(solution,tolerance);
818 sense = Standard_False;
819 distanceptsol = Distance(apoint,solution,
820 afirstvector,asecondvector,
821 adirection,parameter,sense,ok);
822
823 if (distanceptsol <= distancemini) {
824 TheSol = solution;
825 firstparameter = parameter;
826 thesense = sense;
827 distancemini = distanceptsol;
828 }
829 }
830 if (!TheSol.IsNull()) {
831 GccInt_IType type = TheSol->ArcType();
832 Handle(Geom2d_Curve) bisectorcurve;
833 if (type == GccInt_Lin) {
834
835// ----------------------------------------------------------------------------
0d969553
Y
836// If the bisectrice is a line
837// => the point is on the circle.
838// If the part of bisectrice concerned is at the side of the center.
839// => the bisectrice is limited by the point and the center of the circle.
840// Note : In this latter case the bisectrice is actually an ellipse of small null axis.
7fd59977 841// ----------------------------------------------------------------------------
842
843 circlecenter = circle.Location();
844 line = TheSol->Line();
845 secondparameter = ElCLib::Parameter(line, circlecenter);
846 bisectorcurve = new Geom2d_Line(line);
847
848 if (!thesense) {
849 if (secondparameter > firstparameter) {
850 secondparameter = - Precision::Infinite();
851 }
852 else {
853 secondparameter = secondparameter - 1.E-8;
854 }
855 }
856 else {
857 if (secondparameter < firstparameter) {
858 secondparameter = Precision::Infinite();
859 }
860 else {
861 secondparameter = secondparameter + 1.E-8;
862 }
863 }
864
865 thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
866 firstparameter,
867 secondparameter);
868
869 }
870 else if (type == GccInt_Cir) {
871 bisectorcurve = new Geom2d_Circle(TheSol->Circle());
872 if (!thesense)
873 thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
c6541a0c 874 firstparameter-2.0*M_PI,
7fd59977 875 firstparameter,
876 thesense);
877 else
878 thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
879 firstparameter,
c6541a0c 880 firstparameter+2.0*M_PI,
7fd59977 881 thesense);
882 }
883 else if (type == GccInt_Hpr) {
884 bisectorcurve=new Geom2d_Hyperbola(TheSol->Hyperbola());
885 if (!thesense)
886 thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
887 firstparameter,
888 - Precision::Infinite());
889 else
890 thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
891 firstparameter,
892 Precision::Infinite());
893 }
894 else if (type == GccInt_Ell) {
895 bisectorcurve = new Geom2d_Ellipse(TheSol->Ellipse());
896 if (!thesense)
897 thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
c6541a0c 898 firstparameter-2.0*M_PI,
7fd59977 899 firstparameter,
900 thesense);
901 else
902 thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
903 firstparameter,
c6541a0c 904 firstparameter+2.0*M_PI,
7fd59977 905 thesense);
906 }
907 }
908 }
909 }
910 break;
911
912//=============================================================================
0d969553 913// Bissectrice point - straight. +
7fd59977 914//=============================================================================
915 case 2 : {
916 GccAna_LinPnt2dBisec Bisector(line,asecondpoint->Pnt2d());
917
7fd59977 918#ifdef DEB
919 gp_Vec2d V(line.Direction());
920#else
921 line.Direction();
922#endif
923 Handle(GccInt_Bisec) solution = Bisector.ThisSolution();
924 Degenerate(solution,tolerance);
925 GccInt_IType type = solution->ArcType();
926 Handle(Geom2d_Curve) bisectorcurve;
927
928 if (type == GccInt_Lin) {
929 bisectorcurve = new Geom2d_Line(solution->Line());
930 }
931 else if (type == GccInt_Par) {
932 bisectorcurve = new Geom2d_Parabola(solution->Parabola());
933 }
934 sense = Standard_False;
935 distanceptsol = Distance(apoint,solution,
936 afirstvector,asecondvector,
937 adirection,parameter,sense,ok);
938
939 if (ok || !oncurve) {
940 firstparameter = parameter;
941 thesense = sense;
942 }
943
944 if (!thesense)
945 thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
946 firstparameter,
947 - Precision::Infinite());
948 else
949 thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
950 firstparameter,
951 Precision::Infinite());
952 }
953 break;
954
955 default:
956 {
957 cout << "Not yet implemented" << endl;
958 break;
959 }
960 }
961}
962
963
964//===========================================================================
0d969553 965// calculate the bissectrice between a curve and a point starting at a point. +
7fd59977 966// +
0d969553
Y
967// afirstpoint : \ curves between which the +
968// asecondcurve : / bissectrice is calculated. +
969// apoint : point through which the bissectrice should pass. +
970// afirstvector : \ vectors to determine the secteur in which +
971// asecondvector : / the bissectrice should be located. +
972// adirection : shows the side of the bissectrice to be preserved. +
973// tolerance : threshold at which the bisectrices become degenerated+
7fd59977 974//===========================================================================
975
976void Bisector_BisecAna::Perform(const Handle(Geom2d_Point)& afirstpoint ,
977 const Handle(Geom2d_Curve)& asecondcurve ,
978 const gp_Pnt2d& apoint ,
979 const gp_Vec2d& afirstvector ,
980 const gp_Vec2d& asecondvector,
981 const Standard_Real adirection ,
982// const Standard_Real tolerance ,
983 const Standard_Real ,
984 const Standard_Boolean oncurve )
985
986{
987 Standard_Real adirectionreverse = - adirection;
988 Perform(asecondcurve ,
989 afirstpoint ,
990 apoint ,
991 asecondvector ,
992 afirstvector ,
993 adirectionreverse ,
994// Modified by skv - Tue Feb 15 17:51:29 2005 Integration Begin
995 0.,
996// Modified by skv - Tue Feb 15 17:51:29 2005 Integration End
997 oncurve );
998}
999
1000//===========================================================================
0d969553 1001// calculate the bissectrice between two points starting at a point. +
7fd59977 1002// +
0d969553
Y
1003// afirstpoint : \ curves between which the +
1004// asecondpoint : / bissectrice is calculated. +
1005// apoint : point through which the bissectrice should pass. +
1006// afirstvector : \ vectors to determine the sector in which the +
1007// asecondvector : / bissectrice should be located. +
1008// adirection : shows the side of the bissectrice to be preserved. +
7fd59977 1009//===========================================================================
1010
1011void Bisector_BisecAna::Perform(const Handle(Geom2d_Point)& afirstpoint ,
1012 const Handle(Geom2d_Point)& asecondpoint ,
1013 const gp_Pnt2d& apoint ,
1014 const gp_Vec2d& afirstvector ,
1015 const gp_Vec2d& asecondvector,
1016 const Standard_Real adirection ,
1017// const Standard_Real tolerance ,
1018 const Standard_Real ,
1019 const Standard_Boolean oncurve )
1020{
1021 Standard_Boolean sense,ok;
96a95605 1022 Standard_Real parameter;
7fd59977 1023
1024 GccAna_Pnt2dBisec bisector(afirstpoint->Pnt2d(),asecondpoint->Pnt2d());
1025 gp_Lin2d line = bisector.ThisSolution();
1026 Handle(GccInt_Bisec) solution = new GccInt_BLine(line);
1027
1028 sense = Standard_False;
96a95605 1029 Distance(apoint,solution,
7fd59977 1030 afirstvector,asecondvector,
1031 adirection,parameter,sense,ok);
1032 if (ok || !oncurve) {
1033 Handle(Geom2d_Curve) bisectorcurve = new Geom2d_Line(line);
1034 if (!sense)
1035 thebisector=new Geom2d_TrimmedCurve(bisectorcurve,
1036 parameter,- Precision::Infinite());
1037 else
1038 thebisector =new Geom2d_TrimmedCurve(bisectorcurve,
1039 parameter,Precision::Infinite());
1040 }
1041}
1042
1043//=============================================================================
1044//function : IsExtendAtStart
1045//purpose :
1046//=============================================================================
1047Standard_Boolean Bisector_BisecAna::IsExtendAtStart() const
1048{
1049 return Standard_False;
1050}
1051
1052//=============================================================================
1053//function : IsExtendAtEnd
1054//purpose :
1055//=============================================================================
1056Standard_Boolean Bisector_BisecAna::IsExtendAtEnd() const
1057{
1058 return Standard_False;
1059}
1060
1061//=============================================================================
1062//function : SetTrim
0d969553
Y
1063//purpose : Restriction of the bissectrice by the domain of the curve Cu.
1064// The domain of the curve is the set of points that are closer to the
1065// than to its extremities.
1066// For the calculation the domain is extended. Extension of Epsilon1 of the
1067// First and the Last parameter of the curve.
7fd59977 1068//=============================================================================
1069//void Bisector_BisecAna::SetTrim(const Handle(Geom2d_Curve)& Cu)
1070void Bisector_BisecAna::SetTrim(const Handle(Geom2d_Curve)& )
1071{
1072/*
1073 Handle(Standard_Type) Type;
1074 Handle(Geom2d_Curve) TheCurve;
1075 Handle(Geom2d_Circle) CircleCu;
1076 Handle(Geom2d_Line) LineCu;
1077 Handle(Geom2d_Curve) FirstLimit;
1078 Handle(Geom2d_Curve) LastLimit;
1079
1080 gp_Lin2d gpLine;
1081 gp_Pnt2d P, PFirst, PLast, FirstPointBisector, Center;
1082 gp_Vec2d TanFirst, TanLast;
1083
1084 IntRes2d_Domain FirstDomain;
1085 IntRes2d_Domain LastDomain ;
1086
1087 Standard_Real UFirst, ULast, UB1, UB2;
1088 Standard_Real UBisInt1, UBisInt2, Utrim;
1089 Standard_Real Distance;
1090 Standard_Real Radius;
1091
1092 Standard_Real Epsilon1 = 1.E-6; // Epsilon sur le parametre de la courbe.
1093 Standard_Real Tolerance = 1.E-8; // Tolerance pour les intersections.
1094
1095 Type = Cu->DynamicType();
1096
1097 if (Type == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
1098 TheCurve = Handle(Geom2d_TrimmedCurve)::DownCast(Cu)->BasisCurve();
1099 Type = TheCurve->DynamicType();
1100 }
1101 else {
1102 TheCurve = Cu;
1103 }
1104
1105 if (Type == STANDARD_TYPE(Geom2d_Circle)) {
1106 CircleCu = Handle(Geom2d_Circle)::DownCast(TheCurve);
1107 }
1108 else {
1109 LineCu = Handle(Geom2d_Line)::DownCast(TheCurve);
1110 }
1111
1112 // Recuperation de UFirst, ULast.
1113 // -------------------------------
1114 UFirst = Cu->FirstParameter();
1115 ULast = Cu->LastParameter();
1116
1117 // Creation des lignes Limites du domaine si elles existent.
1118 // et Determination de leur domaine d intersection.
1119 // ---------------------------------------------------------
1120 if (Type == STANDARD_TYPE(Geom2d_Circle)) {
1121 CircleCu->D1(UFirst,PFirst,TanFirst);
1122 CircleCu->D1(ULast ,PLast ,TanLast);
1123 Radius = CircleCu->Radius();
1124
1125 if (PFirst.Distance(PLast) > 2.*Epsilon1 && Radius > Epsilon1) {
1126 Center = CircleCu->Location();
1127 P = PFirst.Translated( - (Epsilon1/Radius)*TanFirst );
1128
1129 FirstLimit = new Geom2d_Line(P,
1130 gp_Dir2d(PFirst.X() - Center.X(),
1131 PFirst.Y() - Center.Y()));
1132 P = PLast .Translated( (Epsilon1/Radius)*TanLast );
1133
1134 LastLimit = new Geom2d_Line(P,
1135 gp_Dir2d(PLast.X() - Center.X(),
1136 PLast.Y() - Center.Y()));
1137
1138 Geom2dAdaptor_Curve AFirstLimit(FirstLimit);
1139 Geom2dAdaptor_Curve ALastLimit (LastLimit);
1140 Geom2dInt_GInter Intersect(AFirstLimit , FirstDomain,
1141 ALastLimit , LastDomain ,
1142 Tolerance , Tolerance );
1143
1144 if (Intersect.IsDone() && !Intersect.IsEmpty()) {
1145 if (Intersect.NbPoints() >= 1) {
1146 FirstDomain.SetValues(Intersect.Point(1).Value(),
1147 Intersect.Point(1).ParamOnFirst(),
1148 Tolerance,Standard_True);
1149 LastDomain. SetValues(Intersect.Point(1).Value(),
1150 Intersect.Point(1).ParamOnSecond(),
1151 Tolerance,Standard_True);
1152 }
1153 }
1154 }
1155 }
1156 else if (Type == STANDARD_TYPE(Geom2d_Line)) {
1157 gpLine = LineCu->Lin2d();
1158 if (UFirst > - Precision::Infinite()){
1159 P = LineCu->Value(UFirst - Epsilon1);
1160 FirstLimit = new Geom2d_Line(gpLine.Normal(P)) ;
1161 }
1162 if (ULast < Precision::Infinite()) {
1163 P = LineCu->Value(ULast + Epsilon1);
1164 LastLimit = new Geom2d_Line(gpLine.Normal(P));
1165 }
1166 }
1167 else {
1168 Standard_NotImplemented::Raise();
1169 }
1170
1171 // Determination domaine d intersection de la Bissectrice.
1172 // -------------------------------------------------------
1173 UB1 = thebisector->FirstParameter();
1174 UB2 = thebisector->LastParameter();
1175 if (UB2 > 10000.) {
1176 UB2 = 10000.;
1177 Handle(Geom2d_Curve) BasisCurve = thebisector->BasisCurve();
1178 Handle(Standard_Type) Type1 = BasisCurve->DynamicType();
1179 gp_Parab2d gpParabola;
1180 gp_Hypr2d gpHyperbola;
1181 Standard_Real Focus;
1182 Standard_Real Limit = 50000.;
1183 if (Type1 == STANDARD_TYPE(Geom2d_Parabola)) {
1184 gpParabola = Handle(Geom2d_Parabola)::DownCast(BasisCurve)->Parab2d();
1185 Focus = gpParabola.Focal();
1186 Standard_Real Val1 = Sqrt(Limit*Focus);
1187 Standard_Real Val2 = Sqrt(Limit*Limit);
1188 UB2 = (Val1 <= Val2 ? Val1:Val2);
1189 }
1190 else if (Type1 == STANDARD_TYPE(Geom2d_Hyperbola)) {
1191 gpHyperbola = Handle(Geom2d_Hyperbola)::DownCast(BasisCurve)->Hypr2d();
1192 Standard_Real Majr = gpHyperbola.MajorRadius();
1193 Standard_Real Minr = gpHyperbola.MinorRadius();
1194 Standard_Real Valu1 = Limit/Majr;
1195 Standard_Real Valu2 = Limit/Minr;
1196 Standard_Real Val1 = Log(Valu1+Sqrt(Valu1*Valu1-1));
1197 Standard_Real Val2 = Log(Valu2+Sqrt(Valu2*Valu2+1));
1198 UB2 = (Val1 <= Val2 ? Val1:Val2);
1199 }
1200 }
1201
1202 IntRes2d_Domain DomainBisector(thebisector->Value(UB1), UB1, Tolerance,
1203 thebisector->Value(UB2), UB2, Tolerance);
1204
1205 if (thebisector->BasisCurve()->IsPeriodic()) {
c6541a0c 1206 DomainBisector.SetEquivalentParameters(0.0,2.*M_PI);
7fd59977 1207 }
1208 FirstPointBisector = thebisector->Value(UB1);
1209
1210
1211 // Intersection Bisectrice avec FirstLimit => UBisInt1.
1212 // ----------------------------------------------------
1213 UBisInt1 = Precision::Infinite();
1214 if (!FirstLimit.IsNull()) {
1215 Geom2dAdaptor_Curve AdapBis (thebisector);
1216 Geom2dAdaptor_Curve AFirstLimit(FirstLimit);
1217 Geom2dInt_GInter Intersect(AFirstLimit , FirstDomain,
1218 AdapBis , DomainBisector,
1219 Tolerance , Tolerance );
1220
1221 if (Intersect.IsDone() && !Intersect.IsEmpty()) {
1222 for (Standard_Integer i=1; i<=Intersect.NbPoints(); i++) {
1223 Distance = FirstPointBisector.Distance(Intersect.Point(i).Value());
1224 if (Distance > 2.*Tolerance) {
1225 UBisInt1 = Intersect.Point(i).ParamOnSecond();
1226 break;
1227 }
1228 }
1229 }
1230 }
1231 // Intersection Bisectrice avec LastLimit => UBisInt2.
1232 // ---------------------------------------------------
1233 UBisInt2 = Precision::Infinite();
1234 if (!LastLimit.IsNull()) {
1235 Geom2dAdaptor_Curve AdapBis (thebisector);
1236 Geom2dAdaptor_Curve ALastLimit (LastLimit);
1237 Geom2dInt_GInter Intersect(ALastLimit , LastDomain ,
1238 AdapBis , DomainBisector,
1239 Tolerance , Tolerance );
1240
1241 if (Intersect.IsDone() && !Intersect.IsEmpty()) {
1242 for (Standard_Integer i=1; i<=Intersect.NbPoints(); i++) {
1243 Distance = FirstPointBisector.Distance(Intersect.Point(i).Value());
1244 if (Distance > 2.*Tolerance) {
1245 UBisInt2 = Intersect.Point(i).ParamOnSecond();
1246 break;
1247 }
1248 }
1249 }
1250 }
1251 // Restriction de la Bissectrice par le point d intersection de plus petit
1252 // parametre.
1253 //------------------------------------------------------------------------
1254 Utrim = (UBisInt1 < UBisInt2) ? UBisInt1 : UBisInt2;
1255
1256 if (Utrim < UB2 && Utrim > UB1) thebisector->SetTrim(UB1,Utrim);
1257*/
1258}
1259
1260void Bisector_BisecAna::SetTrim(const Standard_Real uf, const Standard_Real ul)
1261{
1262 thebisector->SetTrim(uf, ul);
1263}
1264//=============================================================================
1265//function : Reverse
1266//purpose :
1267//=============================================================================
1268void Bisector_BisecAna::Reverse()
1269{
1270 thebisector->Reverse();
1271}
1272
1273//=============================================================================
1274//function : ReversedParameter
1275//purpose :
1276//=============================================================================
1277Standard_Real Bisector_BisecAna::ReversedParameter(const Standard_Real U) const
1278{
1279 return thebisector->ReversedParameter(U);
1280}
1281
1282//=============================================================================
1283//function : IsCN
1284//purpose :
1285//=============================================================================
1286Standard_Boolean Bisector_BisecAna::IsCN(const Standard_Integer N) const
1287{
1288 return thebisector->IsCN(N);
1289}
1290
1291//=============================================================================
1292//function : Copy
1293//purpose :
1294//=============================================================================
1295Handle(Geom2d_Geometry) Bisector_BisecAna::Copy() const
1296{
1297 Handle(Bisector_BisecAna) C = new Bisector_BisecAna();
1298 C->Init (Handle(Geom2d_TrimmedCurve)::DownCast(thebisector->Copy()));
1299 return C;
1300}
1301
1302//=============================================================================
1303//function : Transform
1304//purpose :
1305//=============================================================================
1306void Bisector_BisecAna::Transform(const gp_Trsf2d& T)
1307{
1308 thebisector->Transform(T);
1309}
1310
1311//=============================================================================
1312//function : FirstParameter
1313//purpose :
1314//=============================================================================
1315Standard_Real Bisector_BisecAna::FirstParameter() const
1316{
1317// modified by NIZHNY-EAP Thu Feb 3 17:23:42 2000 ___BEGIN___
1318// return thebisector->BasisCurve()->FirstParameter();
1319 return thebisector->FirstParameter();
1320// modified by NIZHNY-EAP Thu Feb 3 17:23:48 2000 ___END___
1321}
1322
1323//=============================================================================
1324//function : LastParameter
1325//purpose :
1326//=============================================================================
1327Standard_Real Bisector_BisecAna::LastParameter() const
1328{
1329 return thebisector->LastParameter();
1330}
1331
1332//=============================================================================
1333//function : IsClosed
1334//purpose :
1335//=============================================================================
1336Standard_Boolean Bisector_BisecAna::IsClosed() const
1337{
1338 return thebisector->BasisCurve()->IsClosed();
1339}
1340
1341//=============================================================================
1342//function : IsPeriodic
1343//purpose :
1344//=============================================================================
1345Standard_Boolean Bisector_BisecAna::IsPeriodic() const
1346{
1347 return thebisector->BasisCurve()->IsPeriodic();
1348}
1349
1350//=============================================================================
1351//function : Continuity
1352//purpose :
1353//=============================================================================
1354GeomAbs_Shape Bisector_BisecAna::Continuity() const
1355{
1356 return thebisector->Continuity();
1357}
1358
1359//=============================================================================
1360//function : D0
1361//purpose :
1362//=============================================================================
1363void Bisector_BisecAna::D0(const Standard_Real U, gp_Pnt2d& P) const
1364{
1365 thebisector->BasisCurve()->D0(U,P);
1366}
1367
1368//=============================================================================
1369//function : D1
1370//purpose :
1371//=============================================================================
1372void Bisector_BisecAna::D1(const Standard_Real U, gp_Pnt2d& P, gp_Vec2d& V1) const
1373{
1374 thebisector->BasisCurve()->D1(U,P,V1);
1375}
1376//=============================================================================
1377//function : D2
1378//purpose :
1379//=============================================================================
1380void Bisector_BisecAna::D2(const Standard_Real U,
1381 gp_Pnt2d& P,
1382 gp_Vec2d& V1,
1383 gp_Vec2d& V2) const
1384{
1385 thebisector->BasisCurve()->D2(U,P,V1,V2);
1386}
1387//=============================================================================
1388//function : D3
1389//purpose :
1390//=============================================================================
1391void Bisector_BisecAna::D3(const Standard_Real U,
1392 gp_Pnt2d& P,
1393 gp_Vec2d& V1,
1394 gp_Vec2d& V2,
1395 gp_Vec2d& V3) const
1396{
1397 thebisector->BasisCurve()->D3(U,P,V1,V2,V3);
1398}
1399//=============================================================================
1400//function : DN
1401//purpose :
1402//=============================================================================
1403gp_Vec2d Bisector_BisecAna::DN(const Standard_Real U, const Standard_Integer N) const
1404{
1405 return thebisector->BasisCurve()->DN (U, N);
1406}
1407
1408//=============================================================================
1409//function : Geom2dCurve
1410//purpose :
1411//=============================================================================
1412Handle(Geom2d_Curve) Bisector_BisecAna::Geom2dCurve() const
1413{
1414 return thebisector->BasisCurve();
1415}
1416
1417//==========================================================================
1418//function : ParameterOfStartPoint
1419//purpose :
1420//==========================================================================
1421Standard_Real Bisector_BisecAna::ParameterOfStartPoint() const
1422{
1423 return thebisector->FirstParameter();
1424}
1425
1426//==========================================================================
1427//function : ParameterOfEndPoint
1428//purpose :
1429//==========================================================================
1430Standard_Real Bisector_BisecAna::ParameterOfEndPoint() const
1431{
1432 return thebisector->LastParameter();
1433}
1434
1435//==========================================================================
1436//function : Parameter
1437//purpose :
1438//==========================================================================
1439Standard_Real Bisector_BisecAna::Parameter(const gp_Pnt2d& P) const
1440{
1441 gp_Hypr2d gphyperbola;
1442 gp_Parab2d gpparabola ;
1443 gp_Elips2d gpellipse ;
1444 gp_Circ2d gpcircle ;
1445 gp_Lin2d gpline ;
1446
1447 Handle(Geom2d_Curve) BasisCurve = thebisector->BasisCurve();
1448 Handle(Standard_Type) Type = BasisCurve ->DynamicType();
1449
1450 if (Type == STANDARD_TYPE(Geom2d_Line)) {
1451 gpline = Handle(Geom2d_Line)::DownCast(BasisCurve)->Lin2d();
1452 return ElCLib::Parameter(gpline,P);
1453 }
1454 else if (Type == STANDARD_TYPE(Geom2d_Circle)) {
1455 gpcircle = Handle(Geom2d_Circle)::DownCast(BasisCurve)->Circ2d();
1456 return ElCLib::Parameter(gpcircle,P);
1457 }
1458 else if (Type == STANDARD_TYPE(Geom2d_Hyperbola)) {
1459 gphyperbola = Handle(Geom2d_Hyperbola)::DownCast(BasisCurve)->Hypr2d();
1460 return ElCLib::Parameter(gphyperbola,P);
1461 }
1462 else if (Type == STANDARD_TYPE(Geom2d_Parabola)) {
1463 gpparabola = Handle(Geom2d_Parabola)::DownCast(BasisCurve)->Parab2d();
1464 return ElCLib::Parameter(gpparabola,P);
1465 }
1466 else if (Type == STANDARD_TYPE(Geom2d_Ellipse)) {
1467 gpellipse = Handle(Geom2d_Ellipse)::DownCast(BasisCurve)->Elips2d();
1468 return ElCLib::Parameter(gpellipse,P);
1469 }
1470 return 0.;
1471}
1472
1473//=============================================================================
1474//function : NbIntervals
1475//purpose :
1476//=============================================================================
1477Standard_Integer Bisector_BisecAna::NbIntervals() const
1478{
1479 return 1;
1480}
1481
1482//=============================================================================
1483//function : IntervalFirst
1484//purpose :
1485//=============================================================================
1486Standard_Real Bisector_BisecAna::IntervalFirst(const Standard_Integer I) const
1487{
1488 if (I != 1) Standard_OutOfRange::Raise();
1489 return FirstParameter();
1490}
1491
1492//=============================================================================
1493//function : IntervalLast
1494//purpose :
1495//=============================================================================
1496Standard_Real Bisector_BisecAna::IntervalLast(const Standard_Integer I) const
1497{
1498 if (I != 1) Standard_OutOfRange::Raise();
1499 return LastParameter();
1500}
1501
1502//=============================================================================
1503//function :
1504//=============================================================================
1505void Bisector_BisecAna::Init(const Handle(Geom2d_TrimmedCurve)& Bis)
1506{
1507 thebisector = Bis;
1508}
1509
1510//=============================================================================
1511//function : Degenerate
0d969553
Y
1512//purpose : Replace the bisectrice by a straight line,
1513// if the bisectrice is an ellipse, a parabole or a degenerated ellipse.
7fd59977 1514//=============================================================================
1515Standard_Boolean Degenerate(Handle(GccInt_Bisec)& aBisector,
1516 const Standard_Real Tolerance)
1517{
1518 Standard_Boolean Degeneree = Standard_False;
1519
1520 gp_Hypr2d gphyperbola;
1521 gp_Parab2d gpparabola ;
1522 gp_Elips2d gpellipse ;
1523 //gp_Circ2d gpcircle ;
1524
1525 Handle(GccInt_Bisec) NewBisector;
1526
1527 GccInt_IType type = aBisector->ArcType();
1528
1529 if (type == GccInt_Hpr) {
1530 gphyperbola = aBisector->Hyperbola();
1531
0d969553
Y
1532 // If the Hyperbola is degenerated, it is replaced by the straight line
1533 // with direction to the axis if symmetry.
7fd59977 1534
1535 if (gphyperbola.MajorRadius() < Tolerance) {
1536 gp_Lin2d gpline(gphyperbola.YAxis());
1537 NewBisector = new GccInt_BLine(gpline);
1538 aBisector = NewBisector;
1539 Degeneree = Standard_True;
1540 }
1541 if (gphyperbola.MinorRadius() < Tolerance) {
1542 gp_Lin2d gpline(gphyperbola.XAxis());
1543 NewBisector = new GccInt_BLine(gpline);
1544 aBisector = NewBisector;
1545 Degeneree = Standard_True;
1546 }
1547 }
1548 else if (type == GccInt_Par) {
1549 gpparabola = aBisector->Parabola();
1550
0d969553
Y
1551 // If the parabole is degenerated, it is replaces by the straight
1552 // line starting at the Top and with direction of the axis of symmetry.
7fd59977 1553
1554 if (gpparabola.Focal() < Tolerance) {
1555 gp_Lin2d gpline(gpparabola.MirrorAxis());
1556 NewBisector = new GccInt_BLine(gpline);
1557 aBisector = NewBisector;
1558 Degeneree = Standard_True;
1559 }
1560 }
1561 else if (type == GccInt_Ell) {
1562 gpellipse = aBisector->Ellipse();
1563
0d969553
Y
1564 // If the ellipse is degenerated, it is replaced by the straight line
1565 // defined by the great axis.
7fd59977 1566
1567 if (gpellipse.MinorRadius() < Tolerance) {
1568 gp_Lin2d gpline(gpellipse.XAxis());
1569 NewBisector = new GccInt_BLine(gpline);
1570 aBisector = NewBisector;
1571 Degeneree = Standard_True;
1572 }
1573 }
1574 return Degeneree;
1575}
1576
1577static void Indent (const Standard_Integer Offset) {
1578 if (Offset > 0) {
1579 for (Standard_Integer i = 0; i < Offset; i++) { cout << " "; }
1580 }
1581}
1582
1583//=============================================================================
1584//function : Dump
1585// purpose :
1586//=============================================================================
1587//void Bisector_BisecAna::Dump(const Standard_Integer Deep,
1588void Bisector_BisecAna::Dump(const Standard_Integer ,
1589 const Standard_Integer Offset) const
1590{
1591 Indent (Offset);
1592 cout<<"Bisector_BisecAna"<<endl;
1593 Indent (Offset);
1594// thebisector->Dump();
1595}