Warning, /include/opencascade/LProp_CLProps.gxx is written in an unsupported language. File is not indexed.
0001 // Copyright (c) 1995-1999 Matra Datavision
0002 // Copyright (c) 1999-2014 OPEN CASCADE SAS
0003 //
0004 // This file is part of Open CASCADE Technology software library.
0005 //
0006 // This library is free software; you can redistribute it and/or modify it under
0007 // the terms of the GNU Lesser General Public License version 2.1 as published
0008 // by the Free Software Foundation, with special exception defined in the file
0009 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0010 // distribution for complete text of the license and disclaimer of any warranty.
0011 //
0012 // Alternatively, this file may be used under the terms of Open CASCADE
0013 // commercial license or contractual agreement.
0014
0015 #include <LProp_Status.hxx>
0016 #include <LProp_NotDefined.hxx>
0017 #include <Standard_OutOfRange.hxx>
0018
0019 static const Standard_Real MinStep = 1.0e-7;
0020
0021
0022
0023 LProp_CLProps::LProp_CLProps (const Curve& C,
0024 const Standard_Real U,
0025 const Standard_Integer N,
0026 const Standard_Real Resolution)
0027 : myCurve(C), myDerOrder(N), myCN(4),
0028 myLinTol(Resolution), myTangentStatus (LProp_Undecided)
0029 {
0030 Standard_OutOfRange_Raise_if (N < 0 || N > 3,
0031 "LProp_CLProps::LProp_CLProps()");
0032
0033 SetParameter(U);
0034 }
0035
0036 LProp_CLProps::LProp_CLProps (const Curve& C, const Standard_Integer N,
0037 const Standard_Real Resolution)
0038 : myCurve(C), myU(RealLast()), myDerOrder(N), myCN(4),
0039 myLinTol(Resolution), myTangentStatus (LProp_Undecided)
0040 {
0041 Standard_OutOfRange_Raise_if (N < 0 || N > 3,
0042 "LProp_CLProps::LProp_CLProps()");
0043 }
0044
0045 LProp_CLProps::LProp_CLProps (const Standard_Integer N,
0046 const Standard_Real Resolution)
0047 : myU(RealLast()), myDerOrder(N), myCN(0), myLinTol(Resolution),
0048 myTangentStatus (LProp_Undecided)
0049 {
0050 Standard_OutOfRange_Raise_if (N < 0 || N > 3, "LProp_CLProps() - invalid input");
0051 }
0052
0053 void LProp_CLProps::SetParameter(const Standard_Real U)
0054 {
0055 myU = U;
0056 switch (myDerOrder)
0057 {
0058 case 0:
0059 Tool::Value(myCurve, myU, myPnt);
0060 break;
0061 case 1:
0062 Tool::D1(myCurve, myU, myPnt, myDerivArr[0]);
0063 break;
0064 case 2:
0065 Tool::D2(myCurve, myU, myPnt, myDerivArr[0], myDerivArr[1]);
0066 break;
0067 case 3:
0068 Tool::D3(myCurve, myU, myPnt, myDerivArr[0], myDerivArr[1], myDerivArr[2]);
0069 break;
0070 }
0071
0072 myTangentStatus = LProp_Undecided;
0073 }
0074
0075 void LProp_CLProps::SetCurve(const Curve& C)
0076 {
0077 myCurve = C ;
0078 myCN = 4; // Tool::Continuity(C); RLE
0079 }
0080
0081 const Pnt& LProp_CLProps::Value () const
0082 {
0083 return myPnt;
0084 }
0085
0086 const Vec& LProp_CLProps::D1 ()
0087 {
0088 if (myDerOrder < 1)
0089 {
0090 myDerOrder = 1;
0091 Tool::D1(myCurve, myU, myPnt, myDerivArr[0]);
0092 }
0093
0094 return myDerivArr[0];
0095 }
0096
0097 const Vec& LProp_CLProps::D2 ()
0098 {
0099 if (myDerOrder < 2)
0100 {
0101 myDerOrder = 2;
0102 Tool::D2(myCurve, myU, myPnt, myDerivArr[0], myDerivArr[1]);
0103 }
0104
0105 return myDerivArr[1];
0106 }
0107
0108 const Vec& LProp_CLProps::D3 ()
0109 {
0110 if (myDerOrder < 3)
0111 {
0112 myDerOrder = 3;
0113 Tool::D3(myCurve, myU, myPnt, myDerivArr[0], myDerivArr[1], myDerivArr[2]);
0114 }
0115
0116 return myDerivArr[2];
0117 }
0118
0119 Standard_Boolean LProp_CLProps::IsTangentDefined ()
0120 {
0121 if (myTangentStatus == LProp_Undefined)
0122 return Standard_False;
0123 else if (myTangentStatus >= LProp_Defined)
0124 return Standard_True;
0125
0126 // tangentStatus == Lprop_Undecided
0127 // we have to calculate the first non null derivative
0128 const Standard_Real Tol = myLinTol * myLinTol;
0129
0130 Vec V;
0131
0132 Standard_Integer Order = 0;
0133 while (Order++ < 4)
0134 {
0135 if(myCN >= Order)
0136 {
0137 switch(Order)
0138 {
0139 case 1:
0140 V = D1();
0141 break;
0142 case 2:
0143 V = D2();
0144 break;
0145 case 3:
0146 V = D3();
0147 break;
0148 }//switch(Order)
0149
0150 if(V.SquareMagnitude() > Tol)
0151 {
0152 mySignificantFirstDerivativeOrder = Order;
0153 myTangentStatus = LProp_Defined;
0154 return Standard_True;
0155 }//if(V.SquareMagnitude() > Tol)
0156 }//if(cn >= Order)
0157 else
0158 {
0159 myTangentStatus = LProp_Undefined;
0160 return Standard_False;
0161 }// else of "if(cn >= Order)" condition
0162 }//while (Order < 4)
0163
0164 return Standard_False;
0165 }
0166
0167 void LProp_CLProps::Tangent (Dir& D)
0168 {
0169 if(!IsTangentDefined())
0170 throw LProp_NotDefined();
0171
0172 if(mySignificantFirstDerivativeOrder == 1)
0173 D = Dir(myDerivArr[0]);
0174 else if (mySignificantFirstDerivativeOrder > 1)
0175 {
0176 const Standard_Real DivisionFactor = 1.e-3;
0177 const Standard_Real anUsupremum = Tool::LastParameter(myCurve),
0178 anUinfium = Tool::FirstParameter(myCurve);
0179
0180 Standard_Real du;
0181 if((anUsupremum >= RealLast()) || (anUinfium <= RealFirst()))
0182 du = 0.0;
0183 else
0184 du = anUsupremum-anUinfium;
0185
0186 const Standard_Real aDelta = Max(du*DivisionFactor,MinStep);
0187
0188 Vec V = myDerivArr[mySignificantFirstDerivativeOrder - 1];
0189
0190 Standard_Real u;
0191
0192 if(myU-anUinfium < aDelta)
0193 u = myU+aDelta;
0194 else
0195 u = myU-aDelta;
0196
0197 Pnt P1, P2;
0198 Tool::Value(myCurve, Min(myU, u),P1);
0199 Tool::Value(myCurve, Max(myU, u),P2);
0200
0201 Vec V1(P1,P2);
0202 Standard_Real aDirFactor = V.Dot(V1);
0203
0204 if(aDirFactor < 0.0)
0205 V = -V;
0206
0207 D = Dir(V);
0208 }//else if (mySignificantFirstDerivativeOrder > 1)
0209 }
0210
0211 Standard_Real LProp_CLProps::Curvature ()
0212 {
0213 Standard_Boolean isDefined = IsTangentDefined();
0214 (void)isDefined; // trick to avoid compiler warning on variable unised in Release mode; note that IsTangentDefined() must be called always
0215 LProp_NotDefined_Raise_if(!isDefined,
0216 "LProp_CLProps::CurvatureNotDefined()");
0217
0218 // if the first derivative is null the curvature is infinite.
0219 if(mySignificantFirstDerivativeOrder > 1)
0220 return RealLast();
0221
0222 Standard_Real Tol = myLinTol * myLinTol;
0223 Standard_Real DD1 = myDerivArr[0].SquareMagnitude();
0224 Standard_Real DD2 = myDerivArr[1].SquareMagnitude();
0225
0226 // if the second derivative is null the curvature is null.
0227 if (DD2 <= Tol)
0228 {
0229 myCurvature = 0.0;
0230 }
0231 else
0232 {
0233 Standard_Real N = myDerivArr[0].CrossSquareMagnitude(myDerivArr[1]);
0234 // if d[0] and d[1] are colinear the curvature is null.
0235 //Standard_Real t = N/(DD1*DD2);
0236 Standard_Real t = N / DD1 / DD2;
0237 if (t<=Tol)
0238 {
0239 myCurvature = 0.0;
0240 }
0241 else
0242 {
0243 myCurvature = sqrt(N) / DD1 / sqrt(DD1);
0244 }
0245 }
0246
0247 return myCurvature;
0248 }
0249
0250 void LProp_CLProps::Normal (Dir& D)
0251 {
0252 Standard_Real c = Curvature();
0253 if(c==RealLast() || Abs(c) <= myLinTol)
0254 {
0255 throw LProp_NotDefined("LProp_CLProps::Normal(...):"
0256 "Curvature is null or infinity");
0257 }
0258
0259 // we used here the following vector relation
0260 // a ^ (b ^ c) = b(ac) - c(ab)
0261 // Norm = d[0] ^ (d[1] ^ d[0])
0262
0263 Vec Norm = myDerivArr[1] * (myDerivArr[0] * myDerivArr[0]) - myDerivArr[0] * (myDerivArr[0] * myDerivArr[1]);
0264 D = Dir(Norm);
0265 }
0266
0267 void LProp_CLProps::CentreOfCurvature (Pnt& P)
0268 {
0269 if(Abs(Curvature()) <= myLinTol)
0270 {
0271 throw LProp_NotDefined();
0272 }
0273
0274 // we used here the following vector relation
0275 // a ^ (b ^ c) = b(ac) - c(ab)
0276 // Norm = d[0] ^ (d[1] ^ d[0])
0277
0278 Vec Norm = myDerivArr[1] * (myDerivArr[0] * myDerivArr[0]) - myDerivArr[0] * (myDerivArr[0] * myDerivArr[1]);
0279 Norm.Normalize();
0280 Norm.Divide(myCurvature);
0281 P= myPnt.Translated(Norm);
0282 }