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