1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2012 OPEN CASCADE SAS
4 // The content of this file is subject to the Open CASCADE Technology Public
5 // License Version 6.5 (the "License"). You may not use the content of this file
6 // except in compliance with the License. Please obtain a copy of the License
7 // at http://www.opencascade.org and read it completely before using this file.
9 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
10 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12 // The Original Code and all software distributed under the License is
13 // distributed on an "AS IS" basis, without warranty of any kind, and the
14 // Initial Developer hereby disclaims all such warranties, including without
15 // limitation, any warranties of merchantability, fitness for a particular
16 // purpose or non-infringement. Please see the License for the specific terms
17 // and conditions governing the rights and limitations under the License.
19 #include <LProp_Status.hxx>
20 #include <LProp_NotDefined.hxx>
21 #include <Standard_OutOfRange.hxx>
23 static const Standard_Real MinStep = 1.0e-7;
27 LProp_CLProps::LProp_CLProps (const Curve& C,
28 const Standard_Real U,
29 const Standard_Integer N,
30 const Standard_Real Resolution)
31 : myCurve(C), myDerOrder(N), myCN(4),
32 myLinTol(Resolution), myTangentStatus (LProp_Undecided)
34 Standard_OutOfRange_Raise_if (N < 0 || N > 3,
35 "LProp_CLProps::LProp_CLProps()");
40 LProp_CLProps::LProp_CLProps (const Curve& C, const Standard_Integer N,
41 const Standard_Real Resolution)
42 : myCurve(C), myU(RealLast()), myDerOrder(N), myCN(4),
43 myLinTol(Resolution), myTangentStatus (LProp_Undecided)
45 Standard_OutOfRange_Raise_if (N < 0 || N > 3,
46 "LProp_CLProps::LProp_CLProps()");
49 LProp_CLProps::LProp_CLProps (const Standard_Integer N,
50 const Standard_Real Resolution)
51 : myU(RealLast()), myDerOrder(N), myCN(0), myLinTol(Resolution),
52 myTangentStatus (LProp_Undecided)
54 Standard_OutOfRange_Raise_if (N < 0 || N > 3, "");
57 void LProp_CLProps::SetParameter(const Standard_Real U)
63 Tool::Value(myCurve, myU, myPnt);
66 Tool::D1(myCurve, myU, myPnt, myDerivArr[0]);
69 Tool::D2(myCurve, myU, myPnt, myDerivArr[0], myDerivArr[1]);
72 Tool::D3(myCurve, myU, myPnt, myDerivArr[0], myDerivArr[1], myDerivArr[2]);
76 myTangentStatus = LProp_Undecided;
79 void LProp_CLProps::SetCurve(const Curve& C)
82 myCN = 4; // Tool::Continuity(C); RLE
85 const Pnt& LProp_CLProps::Value () const
90 const Vec& LProp_CLProps::D1 ()
95 Tool::D1(myCurve, myU, myPnt, myDerivArr[0]);
101 const Vec& LProp_CLProps::D2 ()
106 Tool::D2(myCurve, myU, myPnt, myDerivArr[0], myDerivArr[1]);
109 return myDerivArr[1];
112 const Vec& LProp_CLProps::D3 ()
117 Tool::D3(myCurve, myU, myPnt, myDerivArr[0], myDerivArr[1], myDerivArr[2]);
120 return myDerivArr[2];
123 Standard_Boolean LProp_CLProps::IsTangentDefined ()
125 if (myTangentStatus == LProp_Undefined)
126 return Standard_False;
127 else if (myTangentStatus >= LProp_Defined)
128 return Standard_True;
130 // tangentStatus == Lprop_Undecided
131 // we have to calculate the first non null derivative
132 const Standard_Real Tol = myLinTol * myLinTol;
136 Standard_Integer Order = 0;
154 if(V.SquareMagnitude() > Tol)
156 mySignificantFirstDerivativeOrder = Order;
157 myTangentStatus = LProp_Defined;
158 return Standard_True;
159 }//if(V.SquareMagnitude() > Tol)
163 myTangentStatus = LProp_Undefined;
164 return Standard_False;
165 }// else of "if(cn >= Order)" condition
168 return Standard_False;
171 void LProp_CLProps::Tangent (Dir& D)
173 if(!IsTangentDefined())
174 LProp_NotDefined::Raise();
176 if(mySignificantFirstDerivativeOrder == 1)
177 D = Dir(myDerivArr[0]);
178 else if (mySignificantFirstDerivativeOrder > 1)
180 const Standard_Real DivisionFactor = 1.e-3;
181 const Standard_Real anUsupremum = Tool::LastParameter(myCurve),
182 anUinfium = Tool::FirstParameter(myCurve);
185 if((anUsupremum >= RealLast()) || (anUinfium <= RealFirst()))
188 du = anUsupremum-anUinfium;
190 const Standard_Real aDelta = Max(du*DivisionFactor,MinStep);
192 Vec V = myDerivArr[mySignificantFirstDerivativeOrder - 1];
196 if(myU-anUinfium < aDelta)
202 Tool::Value(myCurve, Min(myU, u),P1);
203 Tool::Value(myCurve, Max(myU, u),P2);
206 Standard_Real aDirFactor = V.Dot(V1);
212 }//else if (mySignificantFirstDerivativeOrder > 1)
215 Standard_Real LProp_CLProps::Curvature ()
217 Standard_Boolean isDefined = IsTangentDefined();
218 LProp_NotDefined_Raise_if(!isDefined,
219 "LProp_CLProps::CurvatureNotDefined()");
221 // if the first derivative is null the curvature is infinite.
222 if(mySignificantFirstDerivativeOrder > 1)
225 Standard_Real Tol = myLinTol * myLinTol;
226 Standard_Real DD1 = myDerivArr[0].SquareMagnitude();
227 Standard_Real DD2 = myDerivArr[1].SquareMagnitude();
229 // if the second derivative is null the curvature is null.
236 Standard_Real N = myDerivArr[0].CrossSquareMagnitude(myDerivArr[1]);
237 // if d[0] and d[1] are colinear the curvature is null.
238 Standard_Real t = N/(DD1*DD2);
245 myCurvature = sqrt(N) / (DD1*sqrt(DD1));
252 void LProp_CLProps::Normal (Dir& D)
254 Standard_Real c = Curvature();
255 if(c==RealLast() || Abs(c) <= myLinTol)
257 LProp_NotDefined::Raise("LProp_CLProps::Normal(...):"
258 "Curvature is null or infinity");
261 // we used here the following vector relation
262 // a ^ (b ^ c) = b(ac) - c(ab)
263 // Norm = d[0] ^ (d[1] ^ d[0])
265 Vec Norm = myDerivArr[1] * (myDerivArr[0] * myDerivArr[0]) - myDerivArr[0] * (myDerivArr[0] * myDerivArr[1]);
269 void LProp_CLProps::CentreOfCurvature (Pnt& P)
271 if(Abs(Curvature()) <= myLinTol)
273 LProp_NotDefined::Raise();
276 // we used here the following vector relation
277 // a ^ (b ^ c) = b(ac) - c(ab)
278 // Norm = d[0] ^ (d[1] ^ d[0])
280 Vec Norm = myDerivArr[1] * (myDerivArr[0] * myDerivArr[0]) - myDerivArr[0] * (myDerivArr[0] * myDerivArr[1]);
282 Norm.Divide(myCurvature);
283 P= myPnt.Translated(Norm);