1 // File:        GccIter_FunctionTanCirCu.gxx
2 // Created:     Mon Jan 20 16:35:40 1992
3 // Author:      Remi GILET
4 //              <reg@phobox>
6 #include <gp_Vec2d.hxx>
7 #include <gp_Pnt2d.hxx>
8 #include <gp_Vec.hxx>
9 #include <gp_Pnt.hxx>
11 //=========================================================================
12 //  soit P1 le point sur la courbe TheCurve d abscisse u.                 +
13 //  soit C  le centre du cercle TheCirc.                                  +
14 //  Nous recherchons un point P2 appartenant au cercle tel que :          +
15 //           --->   -->                                                   +
16 //        *  P1P2 . CP2 = 0                                               +
17 //                                                                        +
18 //        *    -->  2    2                                                +
19 //           ||CP2||  = R                                                 +
20 //  Nous cherchons donc les zeros de la fonction suivante:                +
21 //                         -->  --> 2                                     +
22 //             -->  2    ( CP1 . T )      2                               +
23 //           ||CP1||  -  -----------  -  R   =  F(u)                      +
24 //                          --> 2                                         +
25 //                         ||T||                                          +
26 //                                                                        +
27 //  La derivee de cette fonction est :                                    +
28 //                                                                        +
29 //             2*(CP1.T)(CP1.N)     2*(CP1.T)*(CP1.T)*T.N                 +
30 //  f(u) =  -  ----------------  +  ---------------------                 +
31 //                  T.T                  (T.T)*(T.T)                      +
32 //=========================================================================
33 //                                                                        +
34 // skv: Small addition: The function and the derivative are normalized    +
35 //                      by an average square distance between the circle  +
36 //                      and the curve.                                    +
37 //=========================================================================
39 GccIter_FunctionTanCirCu::
40   GccIter_FunctionTanCirCu(const gp_Circ2d& Circ   ,
41                           const TheCurve&  Curv   ) {
42   Curve = Curv;
43   TheCirc = Circ;
45 //  Modified by Sergey KHROMOV - Thu Apr  5 09:51:21 2001 Begin
46   Standard_Integer aNbSamp = TheCurveTool::NbSamples(Curve);
47   Standard_Real    aFirst  = TheCurveTool::FirstParameter(Curve);
48   Standard_Real    aLast   = TheCurveTool::LastParameter(Curve);
49   Standard_Real    aStep   = (aLast - aFirst)/aNbSamp;
50   Standard_Real    anX     = aFirst + aStep/2.;
51   Standard_Integer aNbP    = 0;
52   gp_XY            aLoc(0., 0.);
54   while (anX <= aLast) {
55     aLoc += (TheCurveTool::Value(Curve, anX)).XY();
56     anX  += aStep;
57     aNbP++;
58   }
59   myWeight = Max((aLoc - TheCirc.Location().XY()).SquareModulus(), TheCirc.Radius());
60 //  Modified by Sergey KHROMOV - Thu Apr  5 09:51:25 2001 End
61  }
64 Standard_Boolean GccIter_FunctionTanCirCu::
65   Value (const Standard_Real  X    ,
66                Standard_Real& Fval ) {
67   gp_Pnt2d Point;
68   gp_Vec2d Vect1;
69   TheCurveTool::D1(Curve,X,Point,Vect1);
70   Standard_Real NormeD1 = Vect1.Magnitude();
71   gp_Vec2d TheDirection(TheCirc.Location(),Point);
72   Standard_Real squaredir = TheDirection.Dot(TheDirection);
74   Fval = squaredir-R*R-
75     (TheDirection.Dot(Vect1))*(TheDirection.Dot(Vect1))/(NormeD1*NormeD1);
76 //  Modified by Sergey KHROMOV - Thu Apr  5 17:38:05 2001 Begin
77   Fval /= myWeight;
78 //  Modified by Sergey KHROMOV - Thu Apr  5 17:38:06 2001 End
79   return Standard_True;
80 }
82 Standard_Boolean GccIter_FunctionTanCirCu::
83   Derivative (const Standard_Real  X     ,
84                     Standard_Real& Deriv ) {
85   gp_Pnt2d Point;
86   gp_Vec2d Vect1,Vect2;
87   TheCurveTool::D2(Curve,X,Point,Vect1,Vect2);
88   Standard_Real NormeD1 = Vect1.SquareMagnitude();
89   gp_Vec2d TheDirection(TheCirc.Location(),Point);
90   Standard_Real cp1dott = TheDirection.Dot(Vect1);
91   Deriv = -2.*(cp1dott/NormeD1)*
92     ((TheDirection.Dot(Vect2))-cp1dott*Vect1.Dot(Vect2)/NormeD1);
93 //  Modified by Sergey KHROMOV - Thu Apr  5 17:38:15 2001 Begin
94   Deriv /= myWeight;
95 //  Modified by Sergey KHROMOV - Thu Apr  5 17:38:15 2001 End
96   return Standard_True;
97 }
99 Standard_Boolean GccIter_FunctionTanCirCu::
100   Values (const Standard_Real  X     ,
101                 Standard_Real& Fval  ,
102                 Standard_Real& Deriv ) {
103   gp_Pnt2d Point;
104   gp_Vec2d Vect1,Vect2;
105   TheCurveTool::D2(Curve,X,Point,Vect1,Vect2);
106   Standard_Real NormeD1 = Vect1.SquareMagnitude();
107   gp_Vec2d TheDirection(TheCirc.Location(),Point);
108   Standard_Real squaredir = TheDirection.SquareMagnitude();
109   Standard_Real cp1dott = TheDirection.Dot(Vect1);