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