Commit | Line | Data |
---|---|---|
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") |
42 | static char name[100]; | |
7fd59977 | 43 | static Standard_Integer nbb = 0; |
873c119f | 44 | static Standard_Boolean Affich = Standard_False; |
45 | #endif | |
46 | #endif | |
47 | ||
7fd59977 | 48 | |
7fd59977 | 49 | static Standard_Boolean IsMaxRC (const Handle(Geom2d_Curve)& C, |
873c119f | 50 | Standard_Real U, |
51 | Standard_Real& R); | |
7fd59977 | 52 | |
53 | static void ReplaceByLineIfIsToSmall (Handle(Geom2d_Curve)& Bis, | |
873c119f | 54 | Standard_Real& UFirst, |
55 | Standard_Real& ULast); | |
7fd59977 | 56 | //============================================================================= |
0d969553 | 57 | //function : Empty Constructor |
7fd59977 | 58 | //============================================================================= |
59 | Bisector_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 | ||
75 | void 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 | ||
282 | void 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 | ||
429 | void 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 | ||
573 | void 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 | //============================================================================= | |
615 | const Handle(Geom2d_TrimmedCurve)& Bisector_Bisec::Value() const | |
616 | { | |
617 | return thebisector; | |
618 | } | |
619 | ||
620 | //============================================================================= | |
621 | //function : ChangeValue | |
622 | //purpose : | |
623 | //============================================================================= | |
624 | const 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 | //============================================================================= |
634 | static 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 | //============================================================================= | |
663 | static 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 | } |