diff --git a/./GCPnts_TangentialDeflection.cxx b/./GCPnts_TangentialDeflection.cxx
index 7019e58..6597191 100644
@@ -67,11 +67,11 @@ static void D2 (const Adaptor2d_Curve2d& C, const Standard_Real U,
 static Standard_Real EstimAngl(const gp_Pnt& P1, const gp_Pnt& Pm, const gp_Pnt& P2)
 {
   gp_Vec V1(P1, Pm), V2(Pm, P2);
-  Standard_Real L = V1.Magnitude() * V2.Magnitude();
+  Standard_Real L = Sqrt(V1.SquareMagnitude() * V2.SquareMagnitude());
   //
   if(L > gp::Resolution())
   {
-    return V1.CrossMagnitude(V2)/L;
+    return V1.Dot(V2)/L;
   }
   else
   {
diff --git a/./GCPnts_TangentialDeflection.pxx b/./GCPnts_TangentialDeflection.pxx
index b4838d3..84f30c1 100644
@@ -195,9 +195,9 @@ void GCPnts_TangentialDeflection::PerformLinear (const TheCurve& C) {
   parameters.Append (firstu);
   points    .Append (P);
   if (minNbPnts > 2) {
-    Standard_Real Du = (lastu - firstu) / minNbPnts;
+    Standard_Real Du = (lastu - firstu) / (minNbPnts - 1);
     Standard_Real U = firstu + Du;
-    for (Standard_Integer i = 2; i <= minNbPnts; i++) {
+    for (Standard_Integer i = 2; i < minNbPnts; i++) {
       D0 (C, U, P);
       parameters.Append (U);
       points    .Append (P);
@@ -287,18 +287,19 @@ void GCPnts_TangentialDeflection::PerformCurve (const TheCurve& C)
     {
       //Si c'est une droite on verifie en calculant minNbPoints :
       Standard_Boolean IsLine   = Standard_True;
+      Standard_Boolean IsSequential = Standard_True;
       Standard_Integer NbPoints = (minNbPnts > 3) ? minNbPnts : 3;
       switch (C.GetType()) {
       case GeomAbs_BSplineCurve:
         {
           Handle_TheBSplineCurve BS = C.BSpline() ;
-          NbPoints = Max(BS->Degree() + 1, NbPoints);
+          NbPoints = Max(BS->NbPoles(), Max(BS->Degree() + 1, NbPoints));
           break;
         }
       case GeomAbs_BezierCurve:
         {
           Handle_TheBezierCurve  BZ = C.Bezier();
-          NbPoints = Max(BZ->Degree() + 1, NbPoints);
+          NbPoints = Max(BZ->NbPoles(), Max(BZ->Degree() + 1, NbPoints));
           break;
         }
       default:
@@ -325,8 +326,9 @@ void GCPnts_TangentialDeflection::PerformCurve (const TheCurve& C)
           Intervs(i + 1) = lastu;
         }
 
-        Standard_Real delta = (Intervs(i+1) - Intervs(i))/NbPoints;
-        for (j = 1; j <= NbPoints && IsLine; ++j)
+        Standard_Real delta = (Intervs(i+1) - Intervs(i))/(NbPoints-1);
+
+        for (j = 1; j < NbPoints && IsLine; ++j)
         {
           param = Intervs(i) + j*delta;
           D0 (C, param, MiddlePoint);
@@ -336,6 +338,12 @@ void GCPnts_TangentialDeflection::PerformCurve (const TheCurve& C)
           {
             const Standard_Real aAngle = V2.CrossMagnitude(V1)/(L1*L2);
             IsLine = (aAngle < ATol);
+
+            if(IsLine && IsSequential)
+            {
+                gp_XYZ V3 = LastPoint.XYZ() - MiddlePoint.XYZ();
+                IsSequential = (V3.Dot(V2) >= 0.0);
+            }
           }
         }
       }
@@ -345,7 +353,18 @@ void GCPnts_TangentialDeflection::PerformCurve (const TheCurve& C)
         parameters.Clear();
         points    .Clear();
 
+        const Standard_Integer oldMinNbPoints = minNbPnts;
+        if(!IsSequential)
+        {
+            minNbPnts = NbPoints;
+        }
+
         PerformLinear(C);
+
+        if(!IsSequential)
+        {
+            minNbPnts = oldMinNbPoints;
+        }
         return;
       }
       else
@@ -389,6 +408,7 @@ void GCPnts_TangentialDeflection::PerformCurve (const TheCurve& C)
   Standard_Boolean MorePoints = Standard_True;
   Standard_Real U2            = firstu;   
   Standard_Real AngleMax      = angularDeflection * 0.5;  //car on prend le point milieu
+  Standard_Real MinLen2       = myMinLen * myMinLen;
   Standard_Integer aIdx[2] = {Intervs.Lower(), Intervs.Lower()}; // Indexes of intervals of U1 and U2, used to handle non-uniform case.
   Standard_Boolean isNeedToCheck = Standard_False;
   gp_Pnt aPrevPoint = points.Last();
@@ -432,17 +452,17 @@ void GCPnts_TangentialDeflection::PerformCurve (const TheCurve& C)
 
       V1 = (CurrentPoint.XYZ() - aPrevPoint.XYZ()); //Critere de fleche
       V2 = (MiddlePoint.XYZ()  - aPrevPoint.XYZ());
-      L1 = V1.Modulus ();
+      L1 = V1.SquareModulus ();
 
-      FCoef = (L1 > myMinLen) ? 
-        V1.CrossMagnitude(V2)/(L1*curvatureDeflection) : 0.0;
+      FCoef = (L1 > MinLen2) ?
+        V1.CrossMagnitude(V2)/(Sqrt(L1)*curvatureDeflection) : 0.0;
 
       V1 = (CurrentPoint.XYZ() - MiddlePoint.XYZ()); //Critere d'angle
-      L1 = V1.Modulus ();
-      L2 = V2.Modulus ();
-      if (L1 > myMinLen && L2 > myMinLen)
+      L1 = V1.SquareModulus ();
+      L2 = V2.SquareModulus ();
+      if (L1 > MinLen2 && L2 > MinLen2)
       {
-        Standard_Real angg = V1.CrossMagnitude(V2) / (L1 * L2);
+        Standard_Real angg = V1.CrossMagnitude(V2) / (Sqrt(L1 * L2));
         ACoef = angg / AngleMax;
       }
       else
@@ -585,8 +605,10 @@ void GCPnts_TangentialDeflection::PerformCurve (const TheCurve& C)
     }
   }
   //Additional check for intervals
-  Standard_Real MinLen2 = myMinLen * myMinLen;
   Standard_Integer MaxNbp = 10 * Nbp;
+
+  Standard_Real CosAngleMax = Sqrt(1.0 - AngleMax * AngleMax);
+
   for(i = 1; i < Nbp; ++i)
   {
     U1 = parameters(i);
@@ -600,7 +622,7 @@ void GCPnts_TangentialDeflection::PerformCurve (const TheCurve& C)
     const gp_Pnt& P2 = points(i+1);
     D0(C, umax, MiddlePoint);
     amax = EstimAngl(P1, MiddlePoint, P2);
-    if(dmax > curvatureDeflection || amax > AngleMax)
+    if(dmax > curvatureDeflection || amax < CosAngleMax)
     {
       if(umax - U1 > uTol && U2 - umax > uTol)
       {
