0024750: Replace instantiations of TCollection generic classes by NCollection templat...
[occt.git] / src / LProp / LProp_CLProps.gxx
CommitLineData
b311480e 1// Copyright (c) 1995-1999 Matra Datavision
973c2be1 2// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 3//
973c2be1 4// This file is part of Open CASCADE Technology software library.
b311480e 5//
d5f74e42 6// This library is free software; you can redistribute it and/or modify it under
7// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 8// by the Free Software Foundation, with special exception defined in the file
9// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10// distribution for complete text of the license and disclaimer of any warranty.
b311480e 11//
973c2be1 12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
b311480e 14
7fd59977 15#include <LProp_Status.hxx>
16#include <LProp_NotDefined.hxx>
17#include <Standard_OutOfRange.hxx>
18
32ca7a51 19static const Standard_Real MinStep = 1.0e-7;
7fd59977 20
b311480e 21
32ca7a51 22
23LProp_CLProps::LProp_CLProps (const Curve& C,
7fd59977 24 const Standard_Real U,
32ca7a51 25 const Standard_Integer N,
7fd59977 26 const Standard_Real Resolution)
32ca7a51 27 : myCurve(C), myDerOrder(N), myCN(4),
28 myLinTol(Resolution), myTangentStatus (LProp_Undecided)
7fd59977 29{
7fd59977 30 Standard_OutOfRange_Raise_if (N < 0 || N > 3,
32ca7a51 31 "LProp_CLProps::LProp_CLProps()");
32
7fd59977 33 SetParameter(U);
34}
35
32ca7a51 36LProp_CLProps::LProp_CLProps (const Curve& C, const Standard_Integer N,
37 const Standard_Real Resolution)
38 : myCurve(C), myU(RealLast()), myDerOrder(N), myCN(4),
39 myLinTol(Resolution), myTangentStatus (LProp_Undecided)
7fd59977 40{
32ca7a51 41 Standard_OutOfRange_Raise_if (N < 0 || N > 3,
42 "LProp_CLProps::LProp_CLProps()");
7fd59977 43}
44
45LProp_CLProps::LProp_CLProps (const Standard_Integer N,
46 const Standard_Real Resolution)
32ca7a51 47 : myU(RealLast()), myDerOrder(N), myCN(0), myLinTol(Resolution),
48 myTangentStatus (LProp_Undecided)
7fd59977 49{
7fd59977 50 Standard_OutOfRange_Raise_if (N < 0 || N > 3, "");
51}
52
53void LProp_CLProps::SetParameter(const Standard_Real U)
32ca7a51 54{
55 myU = U;
56 switch (myDerOrder)
57 {
7fd59977 58 case 0:
32ca7a51 59 Tool::Value(myCurve, myU, myPnt);
7fd59977 60 break;
61 case 1:
32ca7a51 62 Tool::D1(myCurve, myU, myPnt, myDerivArr[0]);
7fd59977 63 break;
64 case 2:
32ca7a51 65 Tool::D2(myCurve, myU, myPnt, myDerivArr[0], myDerivArr[1]);
7fd59977 66 break;
67 case 3:
32ca7a51 68 Tool::D3(myCurve, myU, myPnt, myDerivArr[0], myDerivArr[1], myDerivArr[2]);
7fd59977 69 break;
70 }
32ca7a51 71
72 myTangentStatus = LProp_Undecided;
7fd59977 73}
74
32ca7a51 75void LProp_CLProps::SetCurve(const Curve& C)
76{
77 myCurve = C ;
78 myCN = 4; // Tool::Continuity(C); RLE
7fd59977 79}
80
81const Pnt& LProp_CLProps::Value () const
32ca7a51 82{
83 return myPnt;
7fd59977 84}
85
86const Vec& LProp_CLProps::D1 ()
87{
32ca7a51 88 if (myDerOrder < 1)
89 {
90 myDerOrder = 1;
91 Tool::D1(myCurve, myU, myPnt, myDerivArr[0]);
7fd59977 92 }
32ca7a51 93
94 return myDerivArr[0];
7fd59977 95}
96
97const Vec& LProp_CLProps::D2 ()
98{
32ca7a51 99 if (myDerOrder < 2)
100 {
101 myDerOrder = 2;
102 Tool::D2(myCurve, myU, myPnt, myDerivArr[0], myDerivArr[1]);
7fd59977 103 }
32ca7a51 104
105 return myDerivArr[1];
7fd59977 106}
107
108const Vec& LProp_CLProps::D3 ()
109{
32ca7a51 110 if (myDerOrder < 3)
111 {
112 myDerOrder = 3;
113 Tool::D3(myCurve, myU, myPnt, myDerivArr[0], myDerivArr[1], myDerivArr[2]);
7fd59977 114 }
32ca7a51 115
116 return myDerivArr[2];
7fd59977 117}
118
119Standard_Boolean LProp_CLProps::IsTangentDefined ()
120{
32ca7a51 121 if (myTangentStatus == LProp_Undefined)
7fd59977 122 return Standard_False;
32ca7a51 123 else if (myTangentStatus >= LProp_Defined)
7fd59977 124 return Standard_True;
7fd59977 125
126 // tangentStatus == Lprop_Undecided
127 // we have to calculate the first non null derivative
32ca7a51 128 const Standard_Real Tol = myLinTol * myLinTol;
129
7fd59977 130 Vec V;
32ca7a51 131
7fd59977 132 Standard_Integer Order = 0;
32ca7a51 133 while (Order++ < 4)
134 {
135 if(myCN >= Order)
136 {
137 switch(Order)
138 {
139 case 1:
140 V = D1();
141 break;
142 case 2:
143 V = D2();
144 break;
145 case 3:
146 V = D3();
147 break;
148 }//switch(Order)
149
150 if(V.SquareMagnitude() > Tol)
151 {
152 mySignificantFirstDerivativeOrder = Order;
153 myTangentStatus = LProp_Defined;
154 return Standard_True;
155 }//if(V.SquareMagnitude() > Tol)
156 }//if(cn >= Order)
157 else
158 {
159 myTangentStatus = LProp_Undefined;
7fd59977 160 return Standard_False;
32ca7a51 161 }// else of "if(cn >= Order)" condition
162 }//while (Order < 4)
163
7fd59977 164 return Standard_False;
165}
166
7fd59977 167void LProp_CLProps::Tangent (Dir& D)
168{
32ca7a51 169 if(!IsTangentDefined())
170 LProp_NotDefined::Raise();
171
172 if(mySignificantFirstDerivativeOrder == 1)
173 D = Dir(myDerivArr[0]);
174 else if (mySignificantFirstDerivativeOrder > 1)
175 {
176 const Standard_Real DivisionFactor = 1.e-3;
177 const Standard_Real anUsupremum = Tool::LastParameter(myCurve),
178 anUinfium = Tool::FirstParameter(myCurve);
179
180 Standard_Real du;
181 if((anUsupremum >= RealLast()) || (anUinfium <= RealFirst()))
182 du = 0.0;
183 else
184 du = anUsupremum-anUinfium;
185
186 const Standard_Real aDelta = Max(du*DivisionFactor,MinStep);
187
188 Vec V = myDerivArr[mySignificantFirstDerivativeOrder - 1];
189
190 Standard_Real u;
191
192 if(myU-anUinfium < aDelta)
193 u = myU+aDelta;
194 else
195 u = myU-aDelta;
196
197 Pnt P1, P2;
198 Tool::Value(myCurve, Min(myU, u),P1);
199 Tool::Value(myCurve, Max(myU, u),P2);
200
201 Vec V1(P1,P2);
202 Standard_Real aDirFactor = V.Dot(V1);
203
204 if(aDirFactor < 0.0)
205 V = -V;
206
207 D = Dir(V);
208 }//else if (mySignificantFirstDerivativeOrder > 1)
7fd59977 209}
210
211Standard_Real LProp_CLProps::Curvature ()
212{
213 Standard_Boolean isDefined = IsTangentDefined();
105aae76 214 (void)isDefined; // trick to avoid compiler warning on variable unised in Release mode; note that IsTangentDefined() must be called always
7fd59977 215 LProp_NotDefined_Raise_if(!isDefined,
32ca7a51 216 "LProp_CLProps::CurvatureNotDefined()");
7fd59977 217
218 // if the first derivative is null the curvature is infinite.
32ca7a51 219 if(mySignificantFirstDerivativeOrder > 1)
220 return RealLast();
7fd59977 221
32ca7a51 222 Standard_Real Tol = myLinTol * myLinTol;
223 Standard_Real DD1 = myDerivArr[0].SquareMagnitude();
224 Standard_Real DD2 = myDerivArr[1].SquareMagnitude();
225
7fd59977 226 // if the second derivative is null the curvature is null.
32ca7a51 227 if (DD2 <= Tol)
228 {
229 myCurvature = 0.0;
7fd59977 230 }
32ca7a51 231 else
232 {
233 Standard_Real N = myDerivArr[0].CrossSquareMagnitude(myDerivArr[1]);
7fd59977 234 // if d[0] and d[1] are colinear the curvature is null.
235 Standard_Real t = N/(DD1*DD2);
32ca7a51 236 if (t<=Tol)
237 {
238 myCurvature = 0.0;
7fd59977 239 }
32ca7a51 240 else
241 {
242 myCurvature = sqrt(N) / (DD1*sqrt(DD1));
7fd59977 243 }
244 }
7fd59977 245
32ca7a51 246 return myCurvature;
247}
7fd59977 248
249void LProp_CLProps::Normal (Dir& D)
250{
251 Standard_Real c = Curvature();
32ca7a51 252 if(c==RealLast() || Abs(c) <= myLinTol)
253 {
254 LProp_NotDefined::Raise("LProp_CLProps::Normal(...):"
255 "Curvature is null or infinity");
256 }
7fd59977 257
258 // we used here the following vector relation
259 // a ^ (b ^ c) = b(ac) - c(ab)
260 // Norm = d[0] ^ (d[1] ^ d[0])
32ca7a51 261
262 Vec Norm = myDerivArr[1] * (myDerivArr[0] * myDerivArr[0]) - myDerivArr[0] * (myDerivArr[0] * myDerivArr[1]);
7fd59977 263 D = Dir(Norm);
264}
265
7fd59977 266void LProp_CLProps::CentreOfCurvature (Pnt& P)
267{
32ca7a51 268 if(Abs(Curvature()) <= myLinTol)
269 {
270 LProp_NotDefined::Raise();
271 }
7fd59977 272
273 // we used here the following vector relation
274 // a ^ (b ^ c) = b(ac) - c(ab)
275 // Norm = d[0] ^ (d[1] ^ d[0])
276
32ca7a51 277 Vec Norm = myDerivArr[1] * (myDerivArr[0] * myDerivArr[0]) - myDerivArr[0] * (myDerivArr[0] * myDerivArr[1]);
7fd59977 278 Norm.Normalize();
32ca7a51 279 Norm.Divide(myCurvature);
280 P= myPnt.Translated(Norm);
7fd59977 281}