1 // Created on: 1994-07-04
2 // Created by: Yves FRICAUD
3 // Copyright (c) 1994-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
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
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 #include <Bisector_Bisec.ixx>
18 #include <Bisector.hxx>
19 #include <Geom2d_Circle.hxx>
20 #include <Geom2d_Line.hxx>
21 #include <Geom2d_Point.hxx>
22 #include <Geom2d_CartesianPoint.hxx>
23 #include <Geom2d_TrimmedCurve.hxx>
25 #include <gp_Pnt2d.hxx>
26 #include <gp_Vec2d.hxx>
27 #include <StdFail_NotDone.hxx>
28 #include <Standard_NotImplemented.hxx>
29 #include <Precision.hxx>
30 #include <Bisector_Curve.hxx>
31 #include <Bisector_BisecAna.hxx>
32 #include <Bisector_BisecPC.hxx>
33 #include <Bisector_BisecCC.hxx>
36 #include <DrawTrSurf.hxx>
37 static char tname[100];
38 static Standard_CString name = tname ;
39 static Standard_Integer nbb = 0;
42 static Standard_Boolean IsMaxRC (const Handle(Geom2d_Curve)& C,
46 static void ReplaceByLineIfIsToSmall (Handle(Geom2d_Curve)& Bis,
47 Standard_Real& UFirst,
48 Standard_Real& ULast);
49 //=============================================================================
50 //function : Empty Constructor
51 //=============================================================================
52 Bisector_Bisec::Bisector_Bisec()
56 //===========================================================================
57 // calculate the bissectrice between two curves coming from a point.
59 // afirstcurve : \ curves between which the
60 // asecondcurve : / bissectrice is calculated.
61 // apoint : point through which the bissectrice should pass.
62 // afirstvector : \ vectors to determine the sector where
63 // asecondvector : / the bissectrice should be located.
64 // adirection : shows the the side of the bissectrice to be preserved.
65 // tolerance : threshold starting from which the bisectrices are degenerated
66 //===========================================================================
68 void Bisector_Bisec::Perform(const Handle(Geom2d_Curve)& afirstcurve ,
69 const Handle(Geom2d_Curve)& asecondcurve ,
70 const gp_Pnt2d& apoint ,
71 const gp_Vec2d& afirstvector ,
72 const gp_Vec2d& asecondvector ,
73 const Standard_Real adirection ,
74 const Standard_Real tolerance ,
75 const Standard_Boolean oncurve )
77 Handle(Standard_Type) Type1 = afirstcurve ->DynamicType();
78 Handle(Standard_Type) Type2 = asecondcurve->DynamicType();
79 Handle(Bisector_Curve) Bis;
80 Standard_Real UFirst,ULast;
82 if (Type1 == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
83 Type1 = Handle(Geom2d_TrimmedCurve)::DownCast(afirstcurve)
84 ->BasisCurve()->DynamicType();
86 if (Type2 == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
87 Type2 = Handle(Geom2d_TrimmedCurve)::DownCast(asecondcurve)
88 ->BasisCurve()->DynamicType();
91 if ( (Type1 == STANDARD_TYPE(Geom2d_Circle) || Type1 == STANDARD_TYPE(Geom2d_Line)) &&
92 (Type2 == STANDARD_TYPE(Geom2d_Circle) || Type2 == STANDARD_TYPE(Geom2d_Line)) ) {
93 //------------------------------------------------------------------
94 // Analytic Bissectrice.
95 //------------------------------------------------------------------
96 Handle(Bisector_BisecAna) BisAna = new Bisector_BisecAna();
97 BisAna->Perform(afirstcurve ,
105 UFirst = BisAna->ParameterOfStartPoint();
106 ULast = BisAna->ParameterOfEndPoint();
110 Standard_Boolean IsLine = Standard_False;
113 gp_Dir2d Fd(afirstvector);
114 gp_Dir2d Sd(asecondvector);
115 //if (Fd.Dot(Sd) < Precision::Angular() - 1.) {
116 //if (Fd.Dot(Sd) < 10*Precision::Angular() - 1.) //patch
117 if (Fd.Dot(Sd) < Sqrt(2.*Precision::Angular()) - 1.)
118 IsLine = Standard_True;
121 //------------------------------------------------------------------
123 //------------------------------------------------------------------
124 gp_Dir2d N ( - adirection*afirstvector.Y(), adirection*afirstvector.X());
125 Handle (Geom2d_CartesianPoint) PG = new Geom2d_CartesianPoint(apoint);
126 Handle (Geom2d_Line) L = new Geom2d_Line (apoint,N);
127 Handle (Geom2d_TrimmedCurve)
128 BisL = new Geom2d_TrimmedCurve (L,0,Precision::Infinite());
129 Handle(Bisector_BisecAna) BisAna = new Bisector_BisecAna ();
131 UFirst = BisAna->ParameterOfStartPoint();
132 ULast = BisAna->ParameterOfEndPoint();
136 //-------------------------------------------------------------------
138 //-------------------------------------------------------------------
139 Handle(Bisector_BisecCC) BisCC = new Bisector_BisecCC();
140 BisCC -> Perform(asecondcurve,
146 if (BisCC -> IsEmpty()) {
147 // bissectrice is empty. a point is projected at the end of the guide curve.
148 // Construction of a false bissectrice.
149 // modified by NIZHNY-EAP Mon Feb 21 12:00:13 2000 ___BEGIN___
150 gp_Dir2d dir1(afirstvector), dir2(asecondvector);
152 Nx = - dir1.X() - dir2.X(),
153 Ny = - dir1.Y() - dir2.Y();
154 if (Abs(Nx) <= gp::Resolution() && Abs(Ny) <= gp::Resolution()) {
155 Nx = - afirstvector.Y();
156 Ny = afirstvector.X();
158 //gp_Dir2d N ( - adirection*afirstvector.Y(), adirection*afirstvector.X());
159 gp_Dir2d N ( adirection*Nx, adirection*Ny);
160 // modified by NIZHNY-EAP Mon Feb 21 12:00:19 2000 ___END___
162 Handle (Geom2d_CartesianPoint) PG = new Geom2d_CartesianPoint(apoint);
163 Handle (Geom2d_Line) L = new Geom2d_Line (apoint,N);
164 Handle (Geom2d_TrimmedCurve)
165 BisL = new Geom2d_TrimmedCurve (L,0,Precision::Infinite());
166 Handle(Bisector_BisecAna) BisAna = new Bisector_BisecAna ();
168 UFirst = BisAna->ParameterOfStartPoint();
169 ULast = BisAna->ParameterOfEndPoint();
173 UFirst = BisCC->FirstParameter();
174 ULast = BisCC->LastParameter ();
176 ReplaceByLineIfIsToSmall(Bis,UFirst,ULast);
180 thebisector = new Geom2d_TrimmedCurve(Bis,UFirst,ULast);
183 sprintf( name, "c1_%d", ++nbb );
184 DrawTrSurf::Set( name, afirstcurve );
185 sprintf( name, "c2_%d", nbb );
186 DrawTrSurf::Set( name, asecondcurve );
187 sprintf( name, "p%d", nbb );
188 DrawTrSurf::Set( name, apoint );
189 sprintf( name, "b%d", nbb );
190 DrawTrSurf::Set( name, thebisector );
194 //===========================================================================
195 // calculate the bissectrice between a curve and a point starting in a point.
197 // afirstcurve : \ curve and point the bissectrice between which is calculated.
199 // apoint : point through which the bissectrice should pass.
200 // afirstvector : \ vectors to find the sector where
201 // asecondvector : / the bissectrice should be located.
202 // adirection : shows the side of the bissectrice to be preserved.
203 // tolerance : threshold starting from which the bisectrices are degenerated
204 //===========================================================================
206 void Bisector_Bisec::Perform(const Handle(Geom2d_Curve)& afirstcurve ,
207 const Handle(Geom2d_Point)& asecondpoint ,
208 const gp_Pnt2d& apoint ,
209 const gp_Vec2d& afirstvector ,
210 const gp_Vec2d& asecondvector,
211 const Standard_Real adirection ,
212 const Standard_Real tolerance ,
213 const Standard_Boolean oncurve )
215 //gp_Pnt2d SecondPnt = asecondpoint->Pnt2d();
217 Handle(Bisector_Curve) Bis;
218 Handle(Standard_Type) Type1 = afirstcurve ->DynamicType();
219 Standard_Real UFirst,ULast;
221 if (Type1 == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
222 Type1 = Handle(Geom2d_TrimmedCurve)::DownCast(afirstcurve)
223 ->BasisCurve()->DynamicType();
226 if ( Type1 == STANDARD_TYPE(Geom2d_Circle) || Type1 == STANDARD_TYPE(Geom2d_Line)) {
227 //------------------------------------------------------------------
228 // Analytic Bissectrice.
229 //------------------------------------------------------------------
230 Handle(Bisector_BisecAna) BisAna = new Bisector_BisecAna();
231 BisAna -> Perform (afirstcurve ,
239 UFirst = BisAna->ParameterOfStartPoint();
240 ULast = BisAna->ParameterOfEndPoint();
244 Standard_Boolean IsLine = Standard_False;
245 Standard_Real RC = Precision::Infinite();
248 if (Bisector::IsConvex(afirstcurve,adirection) ||
249 IsMaxRC(afirstcurve,afirstcurve->LastParameter(),RC)) {
250 IsLine = Standard_True;
254 //------------------------------------------------------------------
256 //------------------------------------------------------------------
257 gp_Dir2d N ( -adirection*afirstvector.Y(), adirection*afirstvector.X());
258 Handle (Geom2d_Line) L = new Geom2d_Line (apoint,N);
259 Handle (Geom2d_TrimmedCurve) BisL = new Geom2d_TrimmedCurve(L,0,RC);
260 Handle(Bisector_BisecAna) BisAna = new Bisector_BisecAna ();
262 UFirst = BisAna->ParameterOfStartPoint();
263 ULast = BisAna->ParameterOfEndPoint();
267 //-------------------------------------------------------------------
269 //-------------------------------------------------------------------
270 Handle(Bisector_BisecPC) BisPC = new Bisector_BisecPC();
271 Handle(Geom2d_Curve) afirstcurvereverse = afirstcurve->Reversed();
273 BisPC -> Perform(afirstcurvereverse ,
274 asecondpoint->Pnt2d(),
276 // Modified by Sergey KHROMOV - Thu Feb 21 16:49:54 2002 Begin
277 if (BisPC -> IsEmpty()) {
278 gp_Dir2d dir1(afirstvector), dir2(asecondvector);
280 Nx = - dir1.X() - dir2.X(),
281 Ny = - dir1.Y() - dir2.Y();
282 if (Abs(Nx) <= gp::Resolution() && Abs(Ny) <= gp::Resolution()) {
283 Nx = - afirstvector.Y();
284 Ny = afirstvector.X();
286 // gp_Dir2d N ( -adirection*afirstvector.Y(), adirection*afirstvector.X());
287 gp_Dir2d N ( adirection*Nx, adirection*Ny);
288 Handle (Geom2d_Line) L = new Geom2d_Line (apoint,N);
289 Handle (Geom2d_TrimmedCurve) BisL = new Geom2d_TrimmedCurve(L,0,RC);
290 Handle(Bisector_BisecAna) BisAna = new Bisector_BisecAna ();
292 UFirst = BisAna->ParameterOfStartPoint();
293 ULast = BisAna->ParameterOfEndPoint();
296 // Modified by Sergey KHROMOV - Wed Mar 6 17:01:08 2002 End
297 UFirst = BisPC->Parameter(apoint);
298 ULast = BisPC->LastParameter();
301 //Standard_Real t = .9;
302 //UFirst = (1. - t) * BisPC->FirstParameter() + t * ULast;
303 //Extrapolate by line
304 //gp_Dir2d N ( -adirection*afirstvector.Y(), adirection*afirstvector.X());
305 gp_Vec2d V( BisPC->Value(BisPC->FirstParameter()), BisPC->Value(ULast) );
307 Handle (Geom2d_Line) L = new Geom2d_Line (apoint,N);
308 Handle (Geom2d_TrimmedCurve) BisL = new Geom2d_TrimmedCurve (L,0,RC);
309 Handle(Bisector_BisecAna) BisAna = new Bisector_BisecAna ();
311 UFirst = BisAna->ParameterOfStartPoint();
312 ULast = BisAna->ParameterOfEndPoint();
320 thebisector = new Geom2d_TrimmedCurve(Bis,UFirst,ULast);
323 sprintf( name, "c1_%d", ++nbb );
324 DrawTrSurf::Set( name, afirstcurve );
325 sprintf( name, "c2_%d", nbb );
326 DrawTrSurf::Set( name, SecondPnt );
327 sprintf( name, "p%d", nbb );
328 DrawTrSurf::Set( name, apoint );
329 sprintf( name, "b%d", nbb );
330 DrawTrSurf::Set( name, thebisector );
334 //===========================================================================
335 // calculate the bissectrice between a curve and a point starting in a point.
337 // afirstpoint : \ curve and point the bissectrice between which is calculated.
339 // apoint : point through which the bissectrice should pass.
340 // afirstvector : \ vectors to find the sector where
341 // asecondvector : / the bissectrice should be located.
342 // adirection : shows the side of the bissectrice to be preserved.
343 // tolerance : threshold starting from which the bisectrices are degenerated
344 //===========================================================================
346 void Bisector_Bisec::Perform(const Handle(Geom2d_Point)& afirstpoint ,
347 const Handle(Geom2d_Curve)& asecondcurve ,
348 const gp_Pnt2d& apoint ,
349 const gp_Vec2d& afirstvector ,
350 const gp_Vec2d& asecondvector,
351 const Standard_Real adirection ,
352 const Standard_Real tolerance ,
353 const Standard_Boolean oncurve )
356 //gp_Pnt2d FirstPnt = afirstpoint->Pnt2d();
358 Handle(Bisector_Curve) Bis;
359 Handle(Standard_Type) Type1 = asecondcurve ->DynamicType();
360 Standard_Real UFirst,ULast;
362 if (Type1 == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
363 Type1 = Handle(Geom2d_TrimmedCurve)::DownCast(asecondcurve)
364 ->BasisCurve()->DynamicType();
367 if ( Type1 == STANDARD_TYPE(Geom2d_Circle) || Type1 == STANDARD_TYPE(Geom2d_Line)) {
368 //------------------------------------------------------------------
369 // Analytic Bissectrice.
370 //------------------------------------------------------------------
371 Handle(Bisector_BisecAna) BisAna = new Bisector_BisecAna();
372 BisAna -> Perform (afirstpoint ,
380 UFirst = BisAna->ParameterOfStartPoint();
381 ULast = BisAna->ParameterOfEndPoint();
385 // Standard_Real UPoint = 0.;
386 Standard_Boolean IsLine = Standard_False;
387 Standard_Real RC = Precision::Infinite();
390 if (Bisector::IsConvex(asecondcurve, adirection) ||
391 IsMaxRC(asecondcurve,asecondcurve->FirstParameter(),RC)) {
392 IsLine = Standard_True;
396 //------------------------------------------------------------------
398 //------------------------------------------------------------------
399 gp_Dir2d N ( -adirection*afirstvector.Y(), adirection*afirstvector.X());
400 Handle (Geom2d_Line) L = new Geom2d_Line (apoint,N);
401 Handle (Geom2d_TrimmedCurve) BisL = new Geom2d_TrimmedCurve (L,0,RC);
402 Handle(Bisector_BisecAna) BisAna = new Bisector_BisecAna ();
404 UFirst = BisAna->ParameterOfStartPoint();
405 ULast = BisAna->ParameterOfEndPoint();
409 //-------------------------------------------------------------------
411 //-------------------------------------------------------------------
412 Handle(Bisector_BisecPC) BisPC = new Bisector_BisecPC();
413 BisPC -> Perform(asecondcurve ,
414 afirstpoint->Pnt2d(),
416 // Modified by Sergey KHROMOV - Thu Feb 21 16:49:54 2002 Begin
417 if (BisPC -> IsEmpty()) {
418 gp_Dir2d dir1(afirstvector), dir2(asecondvector);
420 Nx = - dir1.X() - dir2.X(),
421 Ny = - dir1.Y() - dir2.Y();
422 if (Abs(Nx) <= gp::Resolution() && Abs(Ny) <= gp::Resolution()) {
423 Nx = - afirstvector.Y();
424 Ny = afirstvector.X();
426 // gp_Dir2d N ( -adirection*afirstvector.Y(), adirection*afirstvector.X());
427 gp_Dir2d N ( adirection*Nx, adirection*Ny);
428 Handle (Geom2d_Line) L = new Geom2d_Line (apoint,N);
429 Handle (Geom2d_TrimmedCurve) BisL = new Geom2d_TrimmedCurve(L,0,RC);
430 Handle(Bisector_BisecAna) BisAna = new Bisector_BisecAna ();
432 UFirst = BisAna->ParameterOfStartPoint();
433 ULast = BisAna->ParameterOfEndPoint();
436 // Modified by Sergey KHROMOV - Thu Feb 21 16:49:58 2002 End
437 UFirst = BisPC->Parameter(apoint);
438 ULast = BisPC->LastParameter();
441 //Extrapolate by line
442 //gp_Dir2d N ( -adirection*afirstvector.Y(), adirection*afirstvector.X());
443 gp_Vec2d V( BisPC->Value(BisPC->FirstParameter()), BisPC->Value(ULast) );
445 Handle (Geom2d_Line) L = new Geom2d_Line (apoint,N);
446 Handle (Geom2d_TrimmedCurve) BisL = new Geom2d_TrimmedCurve (L,0,RC);
447 Handle(Bisector_BisecAna) BisAna = new Bisector_BisecAna ();
449 UFirst = BisAna->ParameterOfStartPoint();
450 ULast = BisAna->ParameterOfEndPoint();
458 thebisector = new Geom2d_TrimmedCurve(Bis,UFirst,ULast);
461 sprintf( name, "c1_%d", ++nbb );
462 DrawTrSurf::Set( name, FirstPnt );
463 sprintf( name, "c2_%d", nbb );
464 DrawTrSurf::Set( name, asecondcurve );
465 sprintf( name, "p%d", nbb );
466 DrawTrSurf::Set( name, apoint );
467 sprintf( name, "b%d", nbb );
468 DrawTrSurf::Set( name, thebisector );
472 //===========================================================================
473 // calculate the bissectrice between two points starting in a point.
475 // afirstpoint : \ curves the bissectrice between which should be
476 // asecondpoint : / calculated.
477 // apoint : point through which the bissectrice should pass.
478 // afirstvector : \ vectors to find the sector where
479 // asecondvector : / the bissectrice should be located.
480 // adirection : shows the side of the bissectrice to be preserved.
481 //===========================================================================
483 void Bisector_Bisec::Perform(const Handle(Geom2d_Point)& afirstpoint ,
484 const Handle(Geom2d_Point)& asecondpoint ,
485 const gp_Pnt2d& apoint ,
486 const gp_Vec2d& afirstvector ,
487 const gp_Vec2d& asecondvector,
488 const Standard_Real adirection ,
489 const Standard_Real tolerance ,
490 const Standard_Boolean oncurve )
492 Handle(Bisector_BisecAna) Bis = new Bisector_BisecAna();
494 Bis -> Perform (afirstpoint ,
502 thebisector = new Geom2d_TrimmedCurve(Bis,
503 Bis->ParameterOfStartPoint(),
504 Bis->ParameterOfEndPoint());
507 sprintf( name, "c1_%d", ++nbb );
508 DrawTrSurf::Set( name, afirstpoint->Pnt2d() );
509 sprintf( name, "c2_%d", nbb );
510 DrawTrSurf::Set( name, asecondpoint->Pnt2d() );
511 sprintf( name, "p%d", nbb );
512 DrawTrSurf::Set( name, apoint );
513 sprintf( name, "b%d", nbb );
514 DrawTrSurf::Set( name, thebisector );
518 //=============================================================================
521 //=============================================================================
522 const Handle(Geom2d_TrimmedCurve)& Bisector_Bisec::Value() const
527 //=============================================================================
528 //function : ChangeValue
530 //=============================================================================
531 const Handle(Geom2d_TrimmedCurve)& Bisector_Bisec::ChangeValue()
536 //=============================================================================
537 //function : ReplaceByLineIfIsToSmall
538 //purpose : If the size of an algorithmic bissectrice is negligeable it is
539 // replaced by a half-straight.
540 //=============================================================================
541 static void ReplaceByLineIfIsToSmall (Handle(Geom2d_Curve)& Bis,
542 Standard_Real& UFirst,
543 Standard_Real& ULast )
546 if (Abs(ULast - UFirst) > 2.*Precision::PConfusion()*10.) return; //patch
548 gp_Pnt2d PF = Bis->Value(UFirst);
549 gp_Pnt2d PL = Bis->Value(ULast);
551 if (PF.Distance(PL) > Precision::Confusion()*10.) return;
553 gp_Vec2d T1 = Bis->DN(UFirst,1);
555 Handle (Geom2d_CartesianPoint) PG = new Geom2d_CartesianPoint(PF);
556 Handle (Geom2d_Line) L = new Geom2d_Line (PF,T1);
557 Handle (Geom2d_TrimmedCurve)
558 BisL = new Geom2d_TrimmedCurve (L,0,Precision::Infinite());
559 Handle(Bisector_BisecAna) BisAna = new Bisector_BisecAna ();
561 UFirst = BisAna->ParameterOfStartPoint();
562 ULast = BisAna->ParameterOfEndPoint();
566 //=============================================================================
569 //=============================================================================
570 static Standard_Boolean IsMaxRC (const Handle(Geom2d_Curve)& C,
575 Standard_Real US = C->FirstParameter();
576 Standard_Real UL = C->LastParameter();
583 Norm2 = D1.SquareMagnitude();;
584 if (Norm2 < gp::Resolution()) { KF = 0.0;}
585 else { KF = Abs(D1^D2)/(Norm2*sqrt(Norm2));}
588 Norm2 = D1.SquareMagnitude();;
589 if (Norm2 < gp::Resolution()) { KL = 0.0;}
590 else { KL = Abs(D1^D2)/(Norm2*sqrt(Norm2));}
592 Standard_Boolean IsMax = Standard_False;
596 if (KL == 0.0) R = Precision::Infinite(); else R = 1/KL;
597 IsMax = Standard_True;
602 if (KF == 0.0) R = Precision::Infinite(); else R = 1/KF;
603 IsMax = Standard_True;