0024255: Regressions in test cases on OCCT vc9 win64 Release
[occt.git] / src / Bisector / Bisector_Bisec.cxx
CommitLineData
b311480e 1// Created on: 1994-07-04
2// Created by: Yves FRICAUD
3// Copyright (c) 1994-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#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>
873c119f 24#include <Geom2d_BSplineCurve.hxx>
7fd59977 25#include <gp.hxx>
26#include <gp_Pnt2d.hxx>
27#include <gp_Vec2d.hxx>
28#include <StdFail_NotDone.hxx>
29#include <Standard_NotImplemented.hxx>
30#include <Precision.hxx>
31#include <Bisector_Curve.hxx>
32#include <Bisector_BisecAna.hxx>
33#include <Bisector_BisecPC.hxx>
34#include <Bisector_BisecCC.hxx>
873c119f 35#include <GCE2d_MakeSegment.hxx>
7fd59977 36
873c119f 37#ifdef OCCT_DEBUG
38//#define DRAW
39#ifdef DRAW
7fd59977 40#include <DrawTrSurf.hxx>
873c119f 41#pragma comment(lib, "TKDraw.lib")
42static char name[100];
7fd59977 43static Standard_Integer nbb = 0;
873c119f 44static Standard_Boolean Affich = Standard_False;
45#endif
46#endif
47
7fd59977 48
7fd59977 49static Standard_Boolean IsMaxRC (const Handle(Geom2d_Curve)& C,
873c119f 50 Standard_Real U,
51 Standard_Real& R);
7fd59977 52
53static void ReplaceByLineIfIsToSmall (Handle(Geom2d_Curve)& Bis,
873c119f 54 Standard_Real& UFirst,
55 Standard_Real& ULast);
7fd59977 56//=============================================================================
0d969553 57//function : Empty Constructor
7fd59977 58//=============================================================================
59Bisector_Bisec::Bisector_Bisec()
60{
61}
62
63//===========================================================================
0d969553 64// calculate the bissectrice between two curves coming from a point.
7fd59977 65//
0d969553
Y
66// afirstcurve : \ curves between which the
67// asecondcurve : / bissectrice is calculated.
68// apoint : point through which the bissectrice should pass.
69// afirstvector : \ vectors to determine the sector where
70// asecondvector : / the bissectrice should be located.
71// adirection : shows the the side of the bissectrice to be preserved.
72// tolerance : threshold starting from which the bisectrices are degenerated
7fd59977 73//===========================================================================
74
75void Bisector_Bisec::Perform(const Handle(Geom2d_Curve)& afirstcurve ,
873c119f 76 const Handle(Geom2d_Curve)& asecondcurve ,
77 const gp_Pnt2d& apoint ,
78 const gp_Vec2d& afirstvector ,
79 const gp_Vec2d& asecondvector ,
80 const Standard_Real adirection ,
81 const Standard_Real tolerance ,
82 const Standard_Boolean oncurve )
7fd59977 83{
84 Handle(Standard_Type) Type1 = afirstcurve ->DynamicType();
85 Handle(Standard_Type) Type2 = asecondcurve->DynamicType();
86 Handle(Bisector_Curve) Bis;
87 Standard_Real UFirst,ULast;
873c119f 88
7fd59977 89 if (Type1 == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
90 Type1 = Handle(Geom2d_TrimmedCurve)::DownCast(afirstcurve)
873c119f 91 ->BasisCurve()->DynamicType();
7fd59977 92 }
93 if (Type2 == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
94 Type2 = Handle(Geom2d_TrimmedCurve)::DownCast(asecondcurve)
873c119f 95 ->BasisCurve()->DynamicType();
96 }
97
98 Handle(Geom2d_Curve) afirstcurve1 = afirstcurve;
99 Handle(Geom2d_Curve) asecondcurve1 = asecondcurve;
100
101 if(Type1 == STANDARD_TYPE(Geom2d_BSplineCurve))
102 {
103 Handle(Geom2d_BSplineCurve) aBS;
104 if(afirstcurve->DynamicType() == STANDARD_TYPE(Geom2d_TrimmedCurve))
105 {
106 aBS = Handle(Geom2d_BSplineCurve)::DownCast(Handle(Geom2d_TrimmedCurve)::DownCast(afirstcurve)
107 ->BasisCurve());
108 }
109 else
110 {
111 aBS = Handle(Geom2d_BSplineCurve)::DownCast(afirstcurve);
112 }
113 if(aBS->Degree() == 1 && aBS->NbPoles() == 2)
114 {
115 if(aBS->Pole(1).Distance(aBS->Pole(2)) < 1.e-4)
116 {
117 afirstcurve1 = GCE2d_MakeSegment(aBS->Pole(1), aBS->Pole(2));
118 Type1 = STANDARD_TYPE(Geom2d_Line);
119 }
120 }
121 }
122
123
124 if(Type2 == STANDARD_TYPE(Geom2d_BSplineCurve))
125 {
126 Handle(Geom2d_BSplineCurve) aBS;
127 if(asecondcurve->DynamicType() == STANDARD_TYPE(Geom2d_TrimmedCurve))
128 {
129 aBS = Handle(Geom2d_BSplineCurve)::DownCast(Handle(Geom2d_TrimmedCurve)::DownCast(asecondcurve)
130 ->BasisCurve());
131 }
132 else
133 {
134 aBS = Handle(Geom2d_BSplineCurve)::DownCast(asecondcurve);
135 }
136 if(aBS->Degree() == 1 && aBS->NbPoles() == 2)
137 {
138 if(aBS->Pole(1).Distance(aBS->Pole(2)) < 1.e-4)
139 {
140 asecondcurve1 = GCE2d_MakeSegment(aBS->Pole(1), aBS->Pole(2));
141 Type2 = STANDARD_TYPE(Geom2d_Line);
142 }
143 }
7fd59977 144 }
145
146 if ( (Type1 == STANDARD_TYPE(Geom2d_Circle) || Type1 == STANDARD_TYPE(Geom2d_Line)) &&
873c119f 147 (Type2 == STANDARD_TYPE(Geom2d_Circle) || Type2 == STANDARD_TYPE(Geom2d_Line)) )
148 {
7fd59977 149 //------------------------------------------------------------------
0d969553 150 // Analytic Bissectrice.
7fd59977 151 //------------------------------------------------------------------
873c119f 152 Handle(Bisector_BisecAna) BisAna = new Bisector_BisecAna();
153 BisAna->Perform(afirstcurve1 ,
154 asecondcurve1 ,
155 apoint ,
156 afirstvector ,
157 asecondvector ,
158 adirection ,
159 tolerance ,
160 oncurve );
161 UFirst = BisAna->ParameterOfStartPoint();
162 ULast = BisAna->ParameterOfEndPoint();
163 Bis = BisAna;
7fd59977 164 }
165 else {
873c119f 166 Standard_Boolean IsLine = Standard_False;
7fd59977 167
168 if (oncurve) {
169 gp_Dir2d Fd(afirstvector);
170 gp_Dir2d Sd(asecondvector);
171 //if (Fd.Dot(Sd) < Precision::Angular() - 1.) {
172 //if (Fd.Dot(Sd) < 10*Precision::Angular() - 1.) //patch
173 if (Fd.Dot(Sd) < Sqrt(2.*Precision::Angular()) - 1.)
873c119f 174 IsLine = Standard_True;
7fd59977 175 }
176 if (IsLine) {
177 //------------------------------------------------------------------
0d969553 178 // Half-Staight.
7fd59977 179 //------------------------------------------------------------------
180 gp_Dir2d N ( - adirection*afirstvector.Y(), adirection*afirstvector.X());
181 Handle (Geom2d_CartesianPoint) PG = new Geom2d_CartesianPoint(apoint);
182 Handle (Geom2d_Line) L = new Geom2d_Line (apoint,N);
183 Handle (Geom2d_TrimmedCurve)
873c119f 184 BisL = new Geom2d_TrimmedCurve (L,0,Precision::Infinite());
7fd59977 185 Handle(Bisector_BisecAna) BisAna = new Bisector_BisecAna ();
186 BisAna->Init(BisL);
187 UFirst = BisAna->ParameterOfStartPoint();
188 ULast = BisAna->ParameterOfEndPoint();
189 Bis = BisAna;
190 }
191 else {
192 //-------------------------------------------------------------------
193 // Bissectrice algo
194 //-------------------------------------------------------------------
195 Handle(Bisector_BisecCC) BisCC = new Bisector_BisecCC();
873c119f 196 BisCC -> Perform(asecondcurve1,
197 afirstcurve1 ,
198 adirection ,
199 adirection ,
200 apoint);
7fd59977 201
202 if (BisCC -> IsEmpty()) {
873c119f 203 // bissectrice is empty. a point is projected at the end of the guide curve.
204 // Construction of a false bissectrice.
205 // modified by NIZHNY-EAP Mon Feb 21 12:00:13 2000 ___BEGIN___
206 gp_Pnt2d aP1 = afirstcurve1->Value(afirstcurve1->LastParameter());
207 gp_Pnt2d aP2 = asecondcurve1->Value(asecondcurve1->FirstParameter());
208 gp_Pnt2d aPm(.5*(aP1.XY()+aP2.XY()));
209 Standard_Real Nx, Ny;
210 if(aPm.Distance(apoint) > 10.*Precision::Confusion())
211 {
212 Nx = apoint.X() - aPm.X();
213 Ny = apoint.Y() - aPm.Y();
214 if(adirection < 0)
215 {
216 Nx = -Nx;
217 Ny = -Ny;
218 }
219 }
220 else
221 {
222 gp_Dir2d dir1(afirstvector), dir2(asecondvector);
223 Nx = - dir1.X() - dir2.X(),
224 Ny = - dir1.Y() - dir2.Y();
225 if (Abs(Nx) <= gp::Resolution() && Abs(Ny) <= gp::Resolution()) {
226 Nx = -afirstvector.Y();
227 Ny = afirstvector.X();
228 }
229 }
230 gp_Dir2d N ( adirection*Nx, adirection*Ny);
231 // modified by NIZHNY-EAP Mon Feb 21 12:00:19 2000 ___END___
232
233 Handle (Geom2d_CartesianPoint) PG = new Geom2d_CartesianPoint(apoint);
234 Handle (Geom2d_Line) L = new Geom2d_Line (apoint,N);
235 Handle (Geom2d_TrimmedCurve)
236 BisL = new Geom2d_TrimmedCurve (L,0,Precision::Infinite());
237 Handle(Bisector_BisecAna) BisAna = new Bisector_BisecAna ();
238 BisAna->Init(BisL);
239 UFirst = BisAna->ParameterOfStartPoint();
240 ULast = BisAna->ParameterOfEndPoint();
241 Bis = BisAna;
7fd59977 242 }
243 else {
873c119f 244 UFirst = BisCC->FirstParameter();
245 ULast = BisCC->LastParameter ();
246 Bis = BisCC;
247 ReplaceByLineIfIsToSmall(Bis,UFirst,ULast);
7fd59977 248 }
249 }
250 }
873c119f 251 UFirst = Max(UFirst, Bis->FirstParameter());
252 ULast = Min(ULast, Bis->LastParameter());
7fd59977 253 thebisector = new Geom2d_TrimmedCurve(Bis,UFirst,ULast);
873c119f 254#ifdef DRAW
255 if(Affich)
256 {
257 sprintf( name, "c1_%d", ++nbb );
258 DrawTrSurf::Set( name, afirstcurve );
259 sprintf( name, "c2_%d", nbb );
260 DrawTrSurf::Set( name, asecondcurve );
261 sprintf( name, "p%d", nbb );
262 DrawTrSurf::Set( name, apoint );
263 sprintf( name, "b%d", nbb );
264 DrawTrSurf::Set( name, thebisector );
265 }
266#endif
267
7fd59977 268}
269
270//===========================================================================
0d969553 271// calculate the bissectrice between a curve and a point starting in a point.
7fd59977 272//
0d969553
Y
273// afirstcurve : \ curve and point the bissectrice between which is calculated.
274// asecondpoint : /
275// apoint : point through which the bissectrice should pass.
276// afirstvector : \ vectors to find the sector where
277// asecondvector : / the bissectrice should be located.
278// adirection : shows the side of the bissectrice to be preserved.
279// tolerance : threshold starting from which the bisectrices are degenerated
7fd59977 280//===========================================================================
281
282void Bisector_Bisec::Perform(const Handle(Geom2d_Curve)& afirstcurve ,
873c119f 283 const Handle(Geom2d_Point)& asecondpoint ,
284 const gp_Pnt2d& apoint ,
285 const gp_Vec2d& afirstvector ,
286 const gp_Vec2d& asecondvector,
287 const Standard_Real adirection ,
288 const Standard_Real tolerance ,
289 const Standard_Boolean oncurve )
7fd59977 290{
291 //gp_Pnt2d SecondPnt = asecondpoint->Pnt2d();
292
293 Handle(Bisector_Curve) Bis;
294 Handle(Standard_Type) Type1 = afirstcurve ->DynamicType();
295 Standard_Real UFirst,ULast;
296
297 if (Type1 == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
298 Type1 = Handle(Geom2d_TrimmedCurve)::DownCast(afirstcurve)
873c119f 299 ->BasisCurve()->DynamicType();
7fd59977 300 }
301
302 if ( Type1 == STANDARD_TYPE(Geom2d_Circle) || Type1 == STANDARD_TYPE(Geom2d_Line)) {
303 //------------------------------------------------------------------
0d969553 304 // Analytic Bissectrice.
7fd59977 305 //------------------------------------------------------------------
306 Handle(Bisector_BisecAna) BisAna = new Bisector_BisecAna();
307 BisAna -> Perform (afirstcurve ,
873c119f 308 asecondpoint ,
309 apoint ,
310 afirstvector ,
311 asecondvector ,
312 adirection ,
313 tolerance ,
314 oncurve );
7fd59977 315 UFirst = BisAna->ParameterOfStartPoint();
316 ULast = BisAna->ParameterOfEndPoint();
317 Bis = BisAna;
318 }
319 else {
320 Standard_Boolean IsLine = Standard_False;
321 Standard_Real RC = Precision::Infinite();
873c119f 322
7fd59977 323 if (oncurve) {
324 if (Bisector::IsConvex(afirstcurve,adirection) ||
873c119f 325 IsMaxRC(afirstcurve,afirstcurve->LastParameter(),RC)) {
326 IsLine = Standard_True;
7fd59977 327 }
328 }
329 if (IsLine) {
330 //------------------------------------------------------------------
0d969553 331 // Half-Right.
7fd59977 332 //------------------------------------------------------------------
333 gp_Dir2d N ( -adirection*afirstvector.Y(), adirection*afirstvector.X());
334 Handle (Geom2d_Line) L = new Geom2d_Line (apoint,N);
335 Handle (Geom2d_TrimmedCurve) BisL = new Geom2d_TrimmedCurve(L,0,RC);
336 Handle(Bisector_BisecAna) BisAna = new Bisector_BisecAna ();
337 BisAna->Init(BisL);
338 UFirst = BisAna->ParameterOfStartPoint();
339 ULast = BisAna->ParameterOfEndPoint();
340 Bis = BisAna;
341 }
342 else {
343 //-------------------------------------------------------------------
344 // Bissectrice algo
345 //-------------------------------------------------------------------
346 Handle(Bisector_BisecPC) BisPC = new Bisector_BisecPC();
347 Handle(Geom2d_Curve) afirstcurvereverse = afirstcurve->Reversed();
873c119f 348
7fd59977 349 BisPC -> Perform(afirstcurvereverse ,
873c119f 350 asecondpoint->Pnt2d(),
351 - adirection );
352 // Modified by Sergey KHROMOV - Thu Feb 21 16:49:54 2002 Begin
7fd59977 353 if (BisPC -> IsEmpty()) {
873c119f 354 gp_Dir2d dir1(afirstvector), dir2(asecondvector);
355 Standard_Real
356 Nx = - dir1.X() - dir2.X(),
357 Ny = - dir1.Y() - dir2.Y();
358 if (Abs(Nx) <= gp::Resolution() && Abs(Ny) <= gp::Resolution()) {
359 Nx = - afirstvector.Y();
360 Ny = afirstvector.X();
361 }
362 // gp_Dir2d N ( -adirection*afirstvector.Y(), adirection*afirstvector.X());
363 gp_Dir2d N ( adirection*Nx, adirection*Ny);
364 Handle (Geom2d_Line) L = new Geom2d_Line (apoint,N);
365 Handle (Geom2d_TrimmedCurve) BisL = new Geom2d_TrimmedCurve(L,0,RC);
366 Handle(Bisector_BisecAna) BisAna = new Bisector_BisecAna ();
367 BisAna->Init(BisL);
368 UFirst = BisAna->ParameterOfStartPoint();
369 ULast = BisAna->ParameterOfEndPoint();
370 Bis = BisAna;
7fd59977 371 } else {
873c119f 372 // Modified by Sergey KHROMOV - Wed Mar 6 17:01:08 2002 End
373 UFirst = BisPC->Parameter(apoint);
374 ULast = BisPC->LastParameter();
375 if(UFirst >= ULast)
376 {
377 //Standard_Real t = .9;
378 //UFirst = (1. - t) * BisPC->FirstParameter() + t * ULast;
379 //Extrapolate by line
380 //gp_Dir2d N ( -adirection*afirstvector.Y(), adirection*afirstvector.X());
381 gp_Vec2d V( BisPC->Value(BisPC->FirstParameter()), BisPC->Value(ULast) );
382 gp_Dir2d N( V );
383 Handle (Geom2d_Line) L = new Geom2d_Line (apoint,N);
384 Handle (Geom2d_TrimmedCurve) BisL = new Geom2d_TrimmedCurve (L,0,RC);
385 Handle(Bisector_BisecAna) BisAna = new Bisector_BisecAna ();
386 BisAna->Init(BisL);
387 UFirst = BisAna->ParameterOfStartPoint();
388 ULast = BisAna->ParameterOfEndPoint();
389 Bis = BisAna;
390 }
391 else
392 Bis = BisPC;
7fd59977 393 }
394 }
395 }
873c119f 396 if(UFirst < Bis->FirstParameter())
397 UFirst = Bis->FirstParameter();
398 if(ULast > Bis->LastParameter())
399 ULast = Bis->LastParameter();
7fd59977 400 thebisector = new Geom2d_TrimmedCurve(Bis,UFirst,ULast);
401
873c119f 402#ifdef DRAW
403 if(Affich)
404 {
7fd59977 405 sprintf( name, "c1_%d", ++nbb );
406 DrawTrSurf::Set( name, afirstcurve );
407 sprintf( name, "c2_%d", nbb );
873c119f 408 DrawTrSurf::Set( name, asecondpoint->Pnt2d() );
7fd59977 409 sprintf( name, "p%d", nbb );
410 DrawTrSurf::Set( name, apoint );
411 sprintf( name, "b%d", nbb );
412 DrawTrSurf::Set( name, thebisector );
873c119f 413 }
414#endif
7fd59977 415}
416
417//===========================================================================
0d969553 418// calculate the bissectrice between a curve and a point starting in a point.
7fd59977 419//
0d969553
Y
420// afirstpoint : \ curve and point the bissectrice between which is calculated.
421// asecondcurve : /
422// apoint : point through which the bissectrice should pass.
423// afirstvector : \ vectors to find the sector where
424// asecondvector : / the bissectrice should be located.
425// adirection : shows the side of the bissectrice to be preserved.
426// tolerance : threshold starting from which the bisectrices are degenerated
7fd59977 427//===========================================================================
428
429void Bisector_Bisec::Perform(const Handle(Geom2d_Point)& afirstpoint ,
873c119f 430 const Handle(Geom2d_Curve)& asecondcurve ,
431 const gp_Pnt2d& apoint ,
432 const gp_Vec2d& afirstvector ,
433 const gp_Vec2d& asecondvector,
434 const Standard_Real adirection ,
435 const Standard_Real tolerance ,
436 const Standard_Boolean oncurve )
7fd59977 437
438{
439 //gp_Pnt2d FirstPnt = afirstpoint->Pnt2d();
440
441 Handle(Bisector_Curve) Bis;
442 Handle(Standard_Type) Type1 = asecondcurve ->DynamicType();
443 Standard_Real UFirst,ULast;
873c119f 444
7fd59977 445 if (Type1 == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
446 Type1 = Handle(Geom2d_TrimmedCurve)::DownCast(asecondcurve)
873c119f 447 ->BasisCurve()->DynamicType();
7fd59977 448 }
873c119f 449
7fd59977 450 if ( Type1 == STANDARD_TYPE(Geom2d_Circle) || Type1 == STANDARD_TYPE(Geom2d_Line)) {
451 //------------------------------------------------------------------
0d969553 452 // Analytic Bissectrice.
7fd59977 453 //------------------------------------------------------------------
454 Handle(Bisector_BisecAna) BisAna = new Bisector_BisecAna();
455 BisAna -> Perform (afirstpoint ,
873c119f 456 asecondcurve ,
457 apoint ,
458 afirstvector ,
459 asecondvector ,
460 adirection ,
461 tolerance ,
462 oncurve );
7fd59977 463 UFirst = BisAna->ParameterOfStartPoint();
464 ULast = BisAna->ParameterOfEndPoint();
465 Bis = BisAna;
466 }
467 else {
873c119f 468 // Standard_Real UPoint = 0.;
7fd59977 469 Standard_Boolean IsLine = Standard_False;
470 Standard_Real RC = Precision::Infinite();
873c119f 471
7fd59977 472 if (oncurve) {
473 if (Bisector::IsConvex(asecondcurve, adirection) ||
873c119f 474 IsMaxRC(asecondcurve,asecondcurve->FirstParameter(),RC)) {
475 IsLine = Standard_True;
7fd59977 476 }
477 }
478 if (IsLine) {
479 //------------------------------------------------------------------
0d969553 480 // Half-Staight.
7fd59977 481 //------------------------------------------------------------------
482 gp_Dir2d N ( -adirection*afirstvector.Y(), adirection*afirstvector.X());
483 Handle (Geom2d_Line) L = new Geom2d_Line (apoint,N);
484 Handle (Geom2d_TrimmedCurve) BisL = new Geom2d_TrimmedCurve (L,0,RC);
485 Handle(Bisector_BisecAna) BisAna = new Bisector_BisecAna ();
486 BisAna->Init(BisL);
487 UFirst = BisAna->ParameterOfStartPoint();
488 ULast = BisAna->ParameterOfEndPoint();
489 Bis = BisAna;
490 }
491 else {
492 //-------------------------------------------------------------------
493 // Bissectrice algo
494 //-------------------------------------------------------------------
495 Handle(Bisector_BisecPC) BisPC = new Bisector_BisecPC();
496 BisPC -> Perform(asecondcurve ,
873c119f 497 afirstpoint->Pnt2d(),
498 adirection );
499 // Modified by Sergey KHROMOV - Thu Feb 21 16:49:54 2002 Begin
7fd59977 500 if (BisPC -> IsEmpty()) {
873c119f 501 gp_Dir2d dir1(afirstvector), dir2(asecondvector);
502 Standard_Real
503 Nx = - dir1.X() - dir2.X(),
504 Ny = - dir1.Y() - dir2.Y();
505 if (Abs(Nx) <= gp::Resolution() && Abs(Ny) <= gp::Resolution()) {
506 Nx = - afirstvector.Y();
507 Ny = afirstvector.X();
508 }
509 // gp_Dir2d N ( -adirection*afirstvector.Y(), adirection*afirstvector.X());
510 gp_Dir2d N ( adirection*Nx, adirection*Ny);
511 Handle (Geom2d_Line) L = new Geom2d_Line (apoint,N);
512 Handle (Geom2d_TrimmedCurve) BisL = new Geom2d_TrimmedCurve(L,0,RC);
513 Handle(Bisector_BisecAna) BisAna = new Bisector_BisecAna ();
514 BisAna->Init(BisL);
515 UFirst = BisAna->ParameterOfStartPoint();
516 ULast = BisAna->ParameterOfEndPoint();
517 Bis = BisAna;
7fd59977 518 } else {
873c119f 519 // Modified by Sergey KHROMOV - Thu Feb 21 16:49:58 2002 End
520 UFirst = BisPC->Parameter(apoint);
521 ULast = BisPC->LastParameter();
522 if(UFirst >= ULast)
523 {
524 //Extrapolate by line
525 //gp_Dir2d N ( -adirection*afirstvector.Y(), adirection*afirstvector.X());
526 gp_Vec2d V( BisPC->Value(BisPC->FirstParameter()), BisPC->Value(ULast) );
527 gp_Dir2d N( V );
528 Handle (Geom2d_Line) L = new Geom2d_Line (apoint,N);
529 Handle (Geom2d_TrimmedCurve) BisL = new Geom2d_TrimmedCurve (L,0,RC);
530 Handle(Bisector_BisecAna) BisAna = new Bisector_BisecAna ();
531 BisAna->Init(BisL);
532 UFirst = BisAna->ParameterOfStartPoint();
533 ULast = BisAna->ParameterOfEndPoint();
534 Bis = BisAna;
535 }
536 else
537 Bis = BisPC;
7fd59977 538 }
539 }
540 }
873c119f 541
542 UFirst = Max(UFirst, Bis->FirstParameter());
543 ULast = Min(ULast, Bis->LastParameter());
7fd59977 544 thebisector = new Geom2d_TrimmedCurve(Bis,UFirst,ULast);
545
873c119f 546#ifdef DRAW
547 if(Affich)
548 {
7fd59977 549 sprintf( name, "c1_%d", ++nbb );
873c119f 550 DrawTrSurf::Set( name, afirstpoint->Pnt2d() );
7fd59977 551 sprintf( name, "c2_%d", nbb );
552 DrawTrSurf::Set( name, asecondcurve );
553 sprintf( name, "p%d", nbb );
554 DrawTrSurf::Set( name, apoint );
555 sprintf( name, "b%d", nbb );
556 DrawTrSurf::Set( name, thebisector );
873c119f 557 }
558#endif
559
7fd59977 560}
561
562//===========================================================================
0d969553 563// calculate the bissectrice between two points starting in a point.
7fd59977 564//
0d969553
Y
565// afirstpoint : \ curves the bissectrice between which should be
566// asecondpoint : / calculated.
567// apoint : point through which the bissectrice should pass.
568// afirstvector : \ vectors to find the sector where
569// asecondvector : / the bissectrice should be located.
570// adirection : shows the side of the bissectrice to be preserved.
7fd59977 571//===========================================================================
572
573void Bisector_Bisec::Perform(const Handle(Geom2d_Point)& afirstpoint ,
873c119f 574 const Handle(Geom2d_Point)& asecondpoint ,
575 const gp_Pnt2d& apoint ,
576 const gp_Vec2d& afirstvector ,
577 const gp_Vec2d& asecondvector,
578 const Standard_Real adirection ,
579 const Standard_Real tolerance ,
580 const Standard_Boolean oncurve )
7fd59977 581{
582 Handle(Bisector_BisecAna) Bis = new Bisector_BisecAna();
583
584 Bis -> Perform (afirstpoint ,
873c119f 585 asecondpoint ,
586 apoint ,
587 afirstvector ,
588 asecondvector ,
589 adirection ,
590 tolerance ,
591 oncurve );
7fd59977 592 thebisector = new Geom2d_TrimmedCurve(Bis,
873c119f 593 Bis->ParameterOfStartPoint(),
594 Bis->ParameterOfEndPoint());
7fd59977 595
873c119f 596#ifdef DRAW
597 if(Affich)
598 {
7fd59977 599 sprintf( name, "c1_%d", ++nbb );
600 DrawTrSurf::Set( name, afirstpoint->Pnt2d() );
601 sprintf( name, "c2_%d", nbb );
602 DrawTrSurf::Set( name, asecondpoint->Pnt2d() );
603 sprintf( name, "p%d", nbb );
604 DrawTrSurf::Set( name, apoint );
605 sprintf( name, "b%d", nbb );
606 DrawTrSurf::Set( name, thebisector );
873c119f 607 }
608#endif
7fd59977 609}
610
611//=============================================================================
612//function : Value
613//purpose :
614//=============================================================================
615const Handle(Geom2d_TrimmedCurve)& Bisector_Bisec::Value() const
616{
617 return thebisector;
618}
619
620//=============================================================================
621//function : ChangeValue
622//purpose :
623//=============================================================================
624const Handle(Geom2d_TrimmedCurve)& Bisector_Bisec::ChangeValue()
625{
626 return thebisector;
627}
628
7fd59977 629//=============================================================================
630//function : ReplaceByLineIfIsToSmall
0d969553
Y
631//purpose : If the size of an algorithmic bissectrice is negligeable it is
632// replaced by a half-straight.
7fd59977 633//=============================================================================
634static void ReplaceByLineIfIsToSmall (Handle(Geom2d_Curve)& Bis,
873c119f 635 Standard_Real& UFirst,
636 Standard_Real& ULast )
7fd59977 637
638{
639 if (Abs(ULast - UFirst) > 2.*Precision::PConfusion()*10.) return; //patch
640
641 gp_Pnt2d PF = Bis->Value(UFirst);
642 gp_Pnt2d PL = Bis->Value(ULast);
643
644 if (PF.Distance(PL) > Precision::Confusion()*10.) return;
645
646 gp_Vec2d T1 = Bis->DN(UFirst,1);
647
648 Handle (Geom2d_CartesianPoint) PG = new Geom2d_CartesianPoint(PF);
649 Handle (Geom2d_Line) L = new Geom2d_Line (PF,T1);
650 Handle (Geom2d_TrimmedCurve)
651 BisL = new Geom2d_TrimmedCurve (L,0,Precision::Infinite());
652 Handle(Bisector_BisecAna) BisAna = new Bisector_BisecAna ();
653 BisAna->Init(BisL);
654 UFirst = BisAna->ParameterOfStartPoint();
655 ULast = BisAna->ParameterOfEndPoint();
656 Bis = BisAna;
657}
658
659//=============================================================================
660//function : IsMaxRC
661//purpose :
662//=============================================================================
663static Standard_Boolean IsMaxRC (const Handle(Geom2d_Curve)& C,
873c119f 664 Standard_Real U,
665 Standard_Real& R)
7fd59977 666{
667 Standard_Real KF,KL;
668 Standard_Real US = C->FirstParameter();
669 Standard_Real UL = C->LastParameter();
670
671 gp_Vec2d D1,D2;
672 gp_Pnt2d P;
673 Standard_Real Norm2;
674
675 C->D2(US,P,D1,D2);
676 Norm2 = D1.SquareMagnitude();;
677 if (Norm2 < gp::Resolution()) { KF = 0.0;}
678 else { KF = Abs(D1^D2)/(Norm2*sqrt(Norm2));}
873c119f 679
7fd59977 680 C->D2(UL,P,D1,D2);
681 Norm2 = D1.SquareMagnitude();;
682 if (Norm2 < gp::Resolution()) { KL = 0.0;}
683 else { KL = Abs(D1^D2)/(Norm2*sqrt(Norm2));}
684
685 Standard_Boolean IsMax = Standard_False;
686
687 if (U == UL) {
688 if (KL < KF) {
689 if (KL == 0.0) R = Precision::Infinite(); else R = 1/KL;
690 IsMax = Standard_True;
691 }
692 }
693 else {
694 if (KF < KL) {
695 if (KF == 0.0) R = Precision::Infinite(); else R = 1/KF;
696 IsMax = Standard_True;
697 }
698 }
699 return IsMax;
700}