Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 1996-02-05 |
2 | // Created by: Philippe MANGIN | |
3 | // Copyright (c) 1996-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 | |
0797d9d3 | 17 | #ifndef OCCT_DEBUG |
7fd59977 | 18 | #define No_Standard_RangeError |
19 | #define No_Standard_OutOfRange | |
20 | #endif | |
21 | ||
7fd59977 | 22 | |
23 | #include <BSplCLib.hxx> | |
42cf5bc1 | 24 | #include <FairCurve_Batten.hxx> |
7fd59977 | 25 | #include <FairCurve_BattenLaw.hxx> |
26 | #include <FairCurve_EnergyOfBatten.hxx> | |
27 | #include <FairCurve_Newton.hxx> | |
42cf5bc1 | 28 | #include <Geom2d_BSplineCurve.hxx> |
29 | #include <gp_Pnt2d.hxx> | |
30 | #include <gp_Vec2d.hxx> | |
7fd59977 | 31 | #include <math_Matrix.hxx> |
42cf5bc1 | 32 | #include <PLib.hxx> |
7fd59977 | 33 | #include <Precision.hxx> |
7fd59977 | 34 | #include <Standard_NegativeValue.hxx> |
35 | #include <Standard_NullValue.hxx> | |
36 | ||
37 | // ================================================================== | |
38 | FairCurve_Batten::FairCurve_Batten(const gp_Pnt2d& P1, | |
39 | const gp_Pnt2d& P2, | |
40 | const Standard_Real Height, | |
41 | const Standard_Real Slope) | |
42 | // ================================================================== | |
43 | : myCode(FairCurve_OK), | |
44 | OldP1(P1), | |
45 | OldP2(P2), | |
46 | OldAngle1(0), | |
47 | OldAngle2(0), | |
48 | OldHeight(Height), | |
49 | OldSlope(Slope), | |
50 | OldSlidingFactor(1), | |
51 | OldFreeSliding(0), | |
52 | OldConstraintOrder1(1), | |
53 | OldConstraintOrder2(1), | |
54 | NewP1(P1), | |
55 | NewP2(P2), | |
56 | NewAngle1(0), | |
57 | NewAngle2(0), | |
58 | NewHeight(Height), | |
59 | NewSlope(Slope), | |
60 | NewSlidingFactor(1), | |
61 | NewFreeSliding(0), | |
62 | NewConstraintOrder1(1), | |
63 | NewConstraintOrder2(1), | |
64 | Degree(9) | |
65 | { | |
66 | if (P1.IsEqual(P2, Precision::Confusion())) | |
9775fa61 | 67 | throw Standard_NullValue("FairCurve : P1 and P2 are confused"); |
7fd59977 | 68 | if (Height <= 0) |
9775fa61 | 69 | throw Standard_NegativeValue("FairCurve : Height is not positive"); |
7fd59977 | 70 | // |
0d969553 | 71 | // Initialize by a straight line (2 poles) |
7fd59977 | 72 | // |
73 | Handle(TColStd_HArray1OfReal) Iknots = new TColStd_HArray1OfReal(1,2); | |
74 | Handle(TColStd_HArray1OfInteger) Imults = new TColStd_HArray1OfInteger(1,2); | |
75 | Handle(TColgp_HArray1OfPnt2d) Ipoles = new TColgp_HArray1OfPnt2d(1,2); | |
76 | ||
77 | Iknots->SetValue(1, 0); | |
78 | Iknots->SetValue(2, 1); | |
79 | ||
80 | Imults->SetValue(1, 2); | |
81 | Imults->SetValue(2, 2); | |
82 | ||
83 | Ipoles->SetValue(1, P1); | |
84 | Ipoles->SetValue(2, P2); | |
85 | ||
0d969553 | 86 | // Increase the degree |
7fd59977 | 87 | |
88 | Handle(TColgp_HArray1OfPnt2d) Npoles = new TColgp_HArray1OfPnt2d(1, Degree+1); | |
89 | Handle(TColStd_HArray1OfReal) Nweight = new TColStd_HArray1OfReal(1, 2); | |
90 | Handle(TColStd_HArray1OfReal) Nknots = new TColStd_HArray1OfReal(1, 2); | |
91 | Handle(TColStd_HArray1OfInteger) Nmults = new TColStd_HArray1OfInteger(1, 2); | |
92 | ||
93 | BSplCLib::IncreaseDegree (1, Degree, Standard_False, | |
94 | Ipoles->Array1(), | |
95 | BSplCLib::NoWeights(), | |
96 | Iknots->Array1(), | |
97 | Imults->Array1(), | |
98 | Npoles->ChangeArray1(), | |
0e14656b | 99 | &Nweight->ChangeArray1(), |
7fd59977 | 100 | Nknots->ChangeArray1(), |
101 | Nmults->ChangeArray1() ); | |
102 | ||
0d969553 | 103 | // and impact the result in our fields |
7fd59977 | 104 | |
105 | Poles = Npoles; | |
106 | Knots = Nknots; | |
107 | Mults = Nmults; | |
108 | ||
0d969553 | 109 | // calculate "plane" nodes |
7fd59977 | 110 | |
111 | Flatknots = new TColStd_HArray1OfReal | |
112 | (1, BSplCLib::KnotSequenceLength(Mults->Array1(), Degree, Standard_False)); | |
113 | ||
114 | BSplCLib::KnotSequence (Knots->Array1(), | |
115 | Mults->Array1(), | |
116 | Degree, Standard_False, | |
117 | Flatknots->ChangeArray1()); | |
118 | } | |
119 | // ================================================================== | |
e6f550da | 120 | FairCurve_Batten::~FairCurve_Batten() |
7fd59977 | 121 | {} |
122 | // ================================================================== | |
123 | void FairCurve_Batten::Angles(const gp_Pnt2d& P1, | |
124 | const gp_Pnt2d& P2) | |
125 | // ================================================================== | |
126 | { | |
127 | gp_Vec2d VOld(NewP1, NewP2), VNew(P1, P2); | |
128 | Standard_Real Dangle = VOld.Angle(VNew); | |
129 | NewAngle1 -= Dangle; | |
130 | NewAngle2 += Dangle; | |
131 | } | |
132 | ||
133 | // ================================================================== | |
134 | void FairCurve_Batten::SetP1(const gp_Pnt2d& P1) | |
135 | // ================================================================== | |
136 | { | |
137 | if (P1.IsEqual(NewP2, Precision::Confusion())) | |
9775fa61 | 138 | throw Standard_NullValue("FairCurve : P1 and P2 are confused"); |
7fd59977 | 139 | Angles(P1, NewP2); |
140 | NewP1 = P1; | |
141 | } | |
142 | ||
143 | // ================================================================== | |
144 | void FairCurve_Batten::SetP2(const gp_Pnt2d& P2) | |
145 | // ================================================================== | |
146 | { | |
147 | if (NewP1.IsEqual(P2, Precision::Confusion())) | |
9775fa61 | 148 | throw Standard_NullValue("FairCurve : P1 and P2 are confused"); |
7fd59977 | 149 | Angles(NewP1, P2); |
150 | NewP2 = P2; | |
151 | } | |
152 | ||
153 | // ================================================================== | |
154 | Standard_Boolean FairCurve_Batten::Compute(FairCurve_AnalysisCode& ACode, | |
155 | const Standard_Integer NbIterations, | |
156 | const Standard_Real Tolerance) | |
157 | // ================================================================== | |
158 | { | |
159 | Standard_Boolean Ok=Standard_True, End=Standard_False; | |
0d969553 | 160 | Standard_Real AngleMax = 0.7; // parameter ruling the function of increment ( 40 degrees ) |
c6541a0c | 161 | Standard_Real AngleMin = 2*M_PI/100; // parameter ruling the function of increment |
0d969553 | 162 | // full passage should not cost more than 100 steps. |
7fd59977 | 163 | Standard_Real DAngle1, DAngle2, Ratio, Fraction, Toler; |
164 | Standard_Real OldDist, NewDist; | |
165 | ||
0d969553 | 166 | // Loop of Homotopy : calculation of the step and optimisation |
7fd59977 | 167 | |
168 | while (Ok && !End) { | |
169 | DAngle1 = NewAngle1-OldAngle1; | |
170 | DAngle2 = NewAngle2-OldAngle2; | |
171 | Ratio = 1; | |
172 | if (NewConstraintOrder1>0) { | |
173 | Fraction = Abs(DAngle1) / (AngleMax * Exp (-Abs(OldAngle1)/AngleMax) + AngleMin); | |
174 | if (Fraction > 1) Ratio = 1 / Fraction; | |
175 | } | |
176 | if (NewConstraintOrder2>0) { | |
177 | Fraction = Abs(DAngle2) / (AngleMax * Exp (-Abs(OldAngle2)/AngleMax) + AngleMin); | |
178 | if (Fraction > 1) Ratio = (Ratio < 1 / Fraction ? Ratio : 1 / Fraction); | |
179 | } | |
180 | ||
181 | OldDist = OldP1.Distance(OldP2); | |
182 | NewDist = NewP1.Distance(NewP2); | |
183 | Fraction = Abs(OldDist-NewDist) / (OldDist/3); | |
184 | if ( Fraction > 1) Ratio = (Ratio < 1 / Fraction ? Ratio : 1 / Fraction); | |
185 | ||
186 | gp_Vec2d DeltaP1(OldP1, NewP1) , DeltaP2(OldP2, NewP2); | |
187 | if ( Ratio == 1) { | |
188 | End = Standard_True; | |
189 | Toler = Tolerance; | |
190 | } | |
191 | else { | |
192 | DeltaP1 *= Ratio; | |
193 | DeltaP2 *= Ratio; | |
194 | DAngle1 *= Ratio; | |
195 | DAngle2 *= Ratio; | |
196 | Toler = 10 * Tolerance; | |
197 | } | |
198 | ||
199 | Ok = Compute( DeltaP1, DeltaP2, | |
200 | DAngle1, DAngle2, | |
201 | ACode, | |
202 | NbIterations, | |
203 | Toler); | |
204 | ||
205 | if (ACode != FairCurve_OK) End = Standard_True; | |
206 | if (NewFreeSliding) NewSlidingFactor = OldSlidingFactor; | |
207 | if (NewConstraintOrder1 == 0) NewAngle1 = OldAngle1; | |
208 | if (NewConstraintOrder2 == 0) NewAngle2 = OldAngle2; | |
209 | } | |
210 | myCode = ACode; | |
211 | return Ok; | |
212 | } | |
213 | // ============================================================================= | |
214 | Standard_Boolean FairCurve_Batten::Compute(const gp_Vec2d& DeltaP1, | |
215 | const gp_Vec2d& DeltaP2, | |
216 | const Standard_Real DeltaAngle1, | |
217 | const Standard_Real DeltaAngle2, | |
218 | FairCurve_AnalysisCode& ACode, | |
219 | const Standard_Integer NbIterations, | |
220 | const Standard_Real Tolerance) | |
221 | // ============================================================================= | |
222 | { | |
223 | Standard_Boolean Ok, OkCompute=Standard_True; | |
224 | ACode = FairCurve_OK; | |
225 | ||
0d969553 | 226 | // Deformation of the curve by adding a polynom of interpolation |
7fd59977 | 227 | Standard_Integer L = 2 + NewConstraintOrder1 + NewConstraintOrder2, kk, ii; |
228 | TColStd_Array1OfReal knots (1,2); | |
229 | knots(1) = 0; | |
230 | knots(2) = 1; | |
231 | TColStd_Array1OfInteger mults (1,2); | |
232 | TColgp_Array1OfPnt2d HermitePoles(1,L); | |
233 | TColgp_Array1OfPnt2d Interpolation(1,L); | |
234 | Handle(TColgp_HArray1OfPnt2d) NPoles = new TColgp_HArray1OfPnt2d(1, Poles->Length()); | |
235 | ||
0d969553 | 236 | // Polynoms of Hermite |
7fd59977 | 237 | math_Matrix HermiteCoef(1, L, 1, L); |
238 | Ok = PLib::HermiteCoefficients(0,1, NewConstraintOrder1, NewConstraintOrder2, | |
239 | HermiteCoef); | |
240 | if (!Ok) return Standard_False; | |
241 | ||
0d969553 | 242 | // Definition of constraints of interpolation |
7fd59977 | 243 | TColgp_Array1OfXY ADelta(1,L); |
244 | gp_Vec2d VOld(OldP1, OldP2), VNew( -(OldP1.XY()+DeltaP1.XY()) + (OldP2.XY()+DeltaP2.XY()) ); | |
245 | Standard_Real DAngleRef = VNew.Angle(VOld); | |
246 | ||
247 | ADelta(1) = DeltaP1.XY(); | |
248 | kk = 2; | |
249 | if (NewConstraintOrder1>0) { | |
250 | gp_Vec2d OldDerive( Poles->Value(Poles->Lower()), | |
251 | Poles->Value(Poles->Lower()+1) ); | |
252 | OldDerive *= Degree / (Knots->Value(2) - Knots->Value(1)); | |
253 | ADelta(kk) = (OldDerive.Rotated(DeltaAngle1-DAngleRef) - OldDerive).XY(); | |
254 | kk += 1; | |
255 | } | |
256 | ADelta(kk) = DeltaP2.XY(); | |
257 | kk += 1; | |
258 | if (NewConstraintOrder2>0) { | |
259 | gp_Vec2d OldDerive( Poles->Value(Poles->Upper()-1), | |
260 | Poles->Value(Poles->Upper()) ); | |
261 | OldDerive *= Degree / (Knots->Value(Knots->Upper()) - Knots->Value(Knots->Upper()-1) ); | |
262 | ADelta(kk) = (OldDerive.Rotated(DAngleRef-DeltaAngle2) - OldDerive).XY(); | |
263 | } | |
264 | ||
265 | // Interpolation | |
266 | gp_XY AuxXY (0,0); | |
267 | for (ii=1; ii<=L; ii++) { | |
268 | AuxXY.SetCoord(0.0, 0); | |
269 | for (kk=1; kk<=L; kk++) { | |
270 | AuxXY += HermiteCoef(kk, ii) * ADelta(kk); | |
271 | } | |
272 | Interpolation(ii).SetXY(AuxXY); | |
273 | } | |
0d969553 | 274 | // Conversion into BSpline of the same structure as the current batten. |
7fd59977 | 275 | PLib::CoefficientsPoles( Interpolation, PLib::NoWeights(), |
276 | HermitePoles, PLib::NoWeights() ); | |
277 | ||
278 | mults.Init(L); | |
279 | ||
280 | Handle(Geom2d_BSplineCurve) DeltaCurve = | |
281 | new Geom2d_BSplineCurve( HermitePoles, | |
282 | knots, mults, L-1); | |
283 | ||
284 | DeltaCurve->IncreaseDegree(Degree); | |
285 | if (Mults->Length()>2) { | |
286 | DeltaCurve->InsertKnots(Knots->Array1(), Mults->Array1(), 1.e-10); | |
287 | } | |
288 | ||
0d969553 | 289 | // Summing |
7fd59977 | 290 | DeltaCurve->Poles( NPoles->ChangeArray1() ); |
291 | for (kk= NPoles->Lower(); kk<=NPoles->Upper(); kk++) { | |
292 | NPoles->ChangeValue(kk).ChangeCoord() += Poles->Value(kk).Coord(); | |
293 | } | |
294 | ||
0d969553 | 295 | // Intermediary data |
7fd59977 | 296 | |
297 | Standard_Real Angle1, Angle2, SlidingLength, | |
298 | Alph1 = OldAngle1 + DeltaAngle1, | |
299 | Alph2 = OldAngle2 + DeltaAngle2, | |
300 | Dist = NPoles->Value(NPoles->Upper()) | |
301 | . Distance( NPoles->Value( NPoles->Lower() ) ), | |
302 | LReference = SlidingOfReference(Dist, Alph1, Alph2); | |
303 | gp_Vec2d Ox(1, 0), | |
304 | P1P2 ( NPoles->Value(NPoles->Upper()).Coord() | |
305 | - NPoles->Value(NPoles->Lower()).Coord() ); | |
306 | ||
0d969553 | 307 | // Angles corresponding to axis ox |
7fd59977 | 308 | |
309 | Angle1 = Ox.Angle(P1P2) + Alph1; | |
310 | Angle2 = -Ox.Angle(P1P2) + Alph2; | |
311 | ||
0d969553 | 312 | // Calculation of the length of sliding (imposed or intial); |
7fd59977 | 313 | |
314 | if (!NewFreeSliding) { | |
315 | SlidingLength = NewSlidingFactor * LReference; | |
316 | } | |
317 | else { | |
318 | if (OldFreeSliding) { | |
319 | SlidingLength = OldSlidingFactor * LReference; | |
320 | } | |
321 | else { | |
322 | SlidingLength = SlidingOfReference(Dist, Alph1, Alph2); | |
323 | } | |
324 | } | |
325 | ||
326 | ||
327 | ||
0d969553 | 328 | // Energy and vectors of initialisation |
7fd59977 | 329 | FairCurve_BattenLaw LBatten (NewHeight, NewSlope, SlidingLength ); |
330 | FairCurve_EnergyOfBatten EBatten (Degree+1, Flatknots, NPoles, | |
331 | NewConstraintOrder1, NewConstraintOrder2, | |
332 | LBatten, SlidingLength, NewFreeSliding, | |
333 | Angle1, Angle2); | |
334 | math_Vector VInit (1, EBatten.NbVariables()); | |
335 | ||
0d969553 | 336 | // The valeur below is the smallest value of the criterion of flexion. |
7fd59977 | 337 | Standard_Real VConvex = 0.01 * pow(NewHeight / SlidingLength, 3); |
338 | if (VConvex < 1.e-12) {VConvex = 1.e-12;} | |
339 | ||
340 | Ok = EBatten.Variable(VInit); | |
341 | ||
342 | // Minimisation | |
343 | FairCurve_Newton Newton(EBatten, | |
344 | Tolerance*P1P2.Magnitude()/10, | |
345 | Tolerance, | |
346 | NbIterations, | |
347 | VConvex); | |
348 | Newton.Perform(EBatten, VInit); | |
349 | Ok = Newton.IsDone(); | |
350 | ||
351 | if (Ok) { | |
352 | Poles = NPoles; | |
353 | Newton.Location(VInit); | |
354 | if (NewFreeSliding) { OldSlidingFactor = VInit(VInit.Upper()) / LReference;} | |
355 | else { OldSlidingFactor = NewSlidingFactor; } | |
356 | ||
357 | if (NewConstraintOrder1 == 0) { | |
358 | gp_Vec2d Tangente ( Poles->Value(Poles->Lower()+1).Coord() | |
359 | - Poles->Value(Poles->Lower()).Coord() ); | |
360 | OldAngle1 = P1P2.Angle(Tangente); | |
361 | } | |
362 | else {OldAngle1 = Alph1;} | |
363 | ||
364 | if (NewConstraintOrder2 == 0) { | |
365 | gp_Vec2d Tangente ( Poles->Value(Poles->Upper()).Coord() | |
366 | - Poles->Value(Poles->Upper()-1).Coord() ); | |
367 | OldAngle2 = (-Tangente).Angle(-P1P2); | |
368 | } | |
369 | else {OldAngle2 = Alph2;} | |
370 | ||
371 | OldP1 = Poles->Value(Poles->Lower()); | |
372 | OldP2 = Poles->Value(Poles->Upper()); | |
373 | OldConstraintOrder1 = NewConstraintOrder1; | |
374 | OldConstraintOrder2 = NewConstraintOrder2; | |
375 | OldFreeSliding = NewFreeSliding; | |
376 | OldSlope = NewSlope; | |
377 | OldHeight = NewHeight; | |
378 | } | |
379 | else { | |
380 | Standard_Real V; | |
381 | ACode = EBatten.Status(); | |
382 | if (!LBatten.Value(0, V) || !LBatten.Value(1, V)) { | |
383 | ACode = FairCurve_NullHeight; | |
384 | } | |
385 | else { OkCompute = Standard_False;} | |
386 | return OkCompute; | |
387 | } | |
388 | ||
389 | Ok = EBatten.Variable(VInit); | |
390 | ||
0d969553 | 391 | // Processing of non-convergence |
7fd59977 | 392 | if (!Newton.IsConverged()) { |
393 | ACode = FairCurve_NotConverged; | |
394 | } | |
395 | ||
396 | ||
0d969553 | 397 | // Prevention of infinite sliding |
7fd59977 | 398 | if (NewFreeSliding && VInit(VInit.Upper()) > 2*LReference) |
399 | ACode = FairCurve_InfiniteSliding; | |
400 | ||
401 | ||
0d969553 | 402 | // Eventual insertion of Nodes |
7fd59977 | 403 | Standard_Boolean NewKnots = Standard_False; |
404 | Standard_Integer NbKnots = Knots->Length(); | |
405 | Standard_Real ValAngles = (Abs(OldAngle1) + Abs(OldAngle2) | |
406 | + 2 * Abs(OldAngle2 - OldAngle1) ) ; | |
407 | while ( ValAngles > (2*(NbKnots-2) + 1)*(1+2*NbKnots) ) { | |
408 | NewKnots = Standard_True; | |
409 | NbKnots += NbKnots-1; | |
410 | } | |
411 | ||
412 | if (NewKnots) { | |
413 | Handle(Geom2d_BSplineCurve) NewBS = | |
414 | new Geom2d_BSplineCurve( NPoles->Array1(), Knots->Array1(), | |
415 | Mults->Array1(), Degree); | |
416 | ||
417 | Handle(TColStd_HArray1OfInteger) NMults = | |
418 | new TColStd_HArray1OfInteger (1,NbKnots); | |
419 | NMults->Init(Degree-3); | |
420 | ||
421 | Handle(TColStd_HArray1OfReal) NKnots = | |
422 | new TColStd_HArray1OfReal (1,NbKnots); | |
423 | for (ii=1; ii<=NbKnots; ii++) { | |
424 | NKnots->ChangeValue(ii) = (double) (ii-1) / (NbKnots-1); | |
425 | } | |
426 | ||
427 | NewBS -> InsertKnots(NKnots->Array1(), NMults->Array1(), 1.e-10); | |
51740958 | 428 | Handle(TColgp_HArray1OfPnt2d) NewNPoles = |
7fd59977 | 429 | new TColgp_HArray1OfPnt2d(1, NewBS->NbPoles()); |
51740958 | 430 | NewBS -> Poles(NewNPoles->ChangeArray1() ); |
7fd59977 | 431 | NewBS -> Multiplicities( NMults->ChangeArray1() ); |
432 | NewBS -> Knots( NKnots->ChangeArray1() ); | |
433 | Handle(TColStd_HArray1OfReal) FKnots = | |
434 | new TColStd_HArray1OfReal (1, NewBS->NbPoles() + Degree+1); | |
435 | NewBS -> KnotSequence( FKnots->ChangeArray1()); | |
436 | ||
51740958 | 437 | Poles = NewNPoles; |
7fd59977 | 438 | Mults = NMults; |
439 | Knots = NKnots; | |
440 | Flatknots = FKnots; | |
441 | } | |
442 | ||
0d969553 | 443 | // For eventual debug |
7fd59977 | 444 | // Newton.Dump(cout); |
445 | ||
446 | return OkCompute; | |
447 | } | |
448 | ||
449 | ||
450 | // ================================================================== | |
451 | Standard_Real FairCurve_Batten::SlidingOfReference() const | |
452 | // ================================================================== | |
453 | { | |
454 | return SlidingOfReference(NewP1.Distance(NewP2), NewAngle1, NewAngle2 ); | |
455 | } | |
456 | // ================================================================== | |
457 | Standard_Real FairCurve_Batten::SlidingOfReference(const Standard_Real Dist, | |
458 | const Standard_Real Angle1, | |
459 | const Standard_Real Angle2) const | |
460 | // ================================================================== | |
461 | { | |
462 | Standard_Real a1, a2; | |
463 | ||
0d969553 | 464 | // case of angle without constraints |
7fd59977 | 465 | if ( (NewConstraintOrder1 == 0) && (NewConstraintOrder2 == 0)) return Dist; |
466 | ||
c6541a0c | 467 | if (NewConstraintOrder1 == 0) a1 = Abs( Abs(NewAngle2)<M_PI ? Angle2/2 : M_PI/2); |
7fd59977 | 468 | else a1 = Abs(Angle1); |
469 | ||
c6541a0c | 470 | if (NewConstraintOrder2 == 0) a2 = Abs( Abs(NewAngle1)<M_PI ? Angle1/2 : M_PI/2); |
7fd59977 | 471 | else a2 = Abs(Angle2); |
472 | ||
0d969553 | 473 | // case of angle of the same sign |
7fd59977 | 474 | if (Angle1 * Angle2 >= 0 ) { |
475 | return Compute(Dist, a1, a2); | |
476 | } | |
477 | ||
0d969553 | 478 | // case of angle of opposite sign |
7fd59977 | 479 | else { |
480 | Standard_Real Ratio = a1 / ( a1 + a2 ); | |
481 | Standard_Real AngleMilieu = pow(1-Ratio,2) * a1 + pow(Ratio,2) * a2; | |
c6541a0c | 482 | if (AngleMilieu > M_PI/2) AngleMilieu = M_PI/2; |
7fd59977 | 483 | |
484 | return Ratio * Compute(Dist, a1, AngleMilieu ) | |
485 | + (1-Ratio) * Compute(Dist, a2, AngleMilieu ); | |
486 | } | |
487 | } | |
488 | ||
489 | ||
490 | // ================================================================== | |
491 | Standard_Real FairCurve_Batten::Compute(const Standard_Real Dist, | |
492 | const Standard_Real Angle1, | |
493 | const Standard_Real Angle2) const | |
494 | // ================================================================== | |
495 | { | |
496 | Standard_Real L1 = Compute(Dist, Angle1); | |
497 | Standard_Real L2 = Compute(Dist, Angle2), Aux; | |
498 | if (L1 < L2) { | |
499 | Aux = L2; | |
500 | L2 = L1; | |
501 | L1 = Aux; | |
502 | } | |
503 | return 0.3 * L1 + 0.7 * L2; | |
504 | } | |
505 | ||
506 | // ================================================================== | |
507 | Standard_Real FairCurve_Batten::Compute(const Standard_Real Dist, | |
508 | const Standard_Real Angle) const | |
509 | // ================================================================== | |
510 | { | |
0d969553 | 511 | if (Angle < Precision::Angular() ) { return Dist; } // length of segment P1P2 |
c6541a0c D |
512 | if (Angle < M_PI/2) { return Angle*Dist / sin(Angle); } // length of circle P1P2 respecting ANGLE |
513 | if (Angle > M_PI) { return Sqrt(Angle*M_PI) * Dist;} | |
0d969553 | 514 | else { return Angle * Dist; } // linear interpolation |
7fd59977 | 515 | } |
516 | ||
517 | // ================================================================== | |
518 | Handle(Geom2d_BSplineCurve) FairCurve_Batten::Curve() const | |
519 | // ================================================================== | |
520 | { | |
521 | Handle(Geom2d_BSplineCurve) TheCurve = new | |
522 | Geom2d_BSplineCurve ( Poles->Array1(), | |
523 | Knots->Array1(), | |
524 | Mults->Array1(), | |
525 | Degree); | |
526 | return TheCurve; | |
527 | } | |
528 | ||
529 | // ================================================================== | |
530 | void FairCurve_Batten::Dump(Standard_OStream& o) const | |
531 | // ================================================================== | |
532 | { | |
533 | ||
586db386 | 534 | o << " Batten |"; o.width(7); o<< "Old | New" << endl; |
7fd59977 | 535 | o << " P1 X |"; o.width(7); o<< OldP1.X() << " | " << NewP1.X() << endl; |
536 | o << " Y |"; o.width(7); o<< OldP1.Y() << " | " << NewP1.Y() << endl; | |
537 | o << " P2 X |"; o.width(7); o<< OldP2.X() << " | " << NewP2.X() << endl; | |
538 | o << " Y |"; o.width(7); o<< OldP2.Y() << " | " << NewP2.Y() << endl; | |
539 | o << " Angle1 |"; o.width(7); o<< OldAngle1 << " | " << NewAngle1 << endl; | |
540 | o << " Angle2 |"; o.width(7); o<< OldAngle2 << " | " << NewAngle2 << endl; | |
541 | o << " Height |"; o.width(7); o<< OldHeight << " | " << NewHeight << endl; | |
542 | o << " Slope |"; o.width(7); o<< OldSlope << " | " << NewSlope << endl; | |
543 | o << " SlidingFactor |"; o.width(7); o<< OldSlidingFactor << " | " << NewSlidingFactor << endl; | |
544 | o << " FreeSliding |"; o.width(7); o<< OldFreeSliding << " | " << NewFreeSliding << endl; | |
545 | o << " ConstrOrder1 |"; o.width(7); o<< OldConstraintOrder1 << " | " << NewConstraintOrder1 << endl; | |
546 | o << " ConstrOrder2 |" ; o.width(7); o<< OldConstraintOrder2 << " | " << NewConstraintOrder2 << endl; | |
547 | switch (myCode) { | |
548 | case FairCurve_OK : | |
549 | o << "AnalysisCode : Ok" << endl; | |
550 | break; | |
551 | case FairCurve_NotConverged : | |
552 | o << "AnalysisCode : NotConverged" << endl; | |
553 | break; | |
554 | case FairCurve_InfiniteSliding : | |
555 | o << "AnalysisCode : InfiniteSliding" << endl; | |
556 | break; | |
557 | case FairCurve_NullHeight : | |
558 | o << "AnalysisCode : NullHeight" << endl; | |
559 | break; | |
560 | } | |
561 | } | |
562 |