0030480: Visualization - Clear of Select3D_SensitiveGroup does not update internal...
[occt.git] / src / Geom2dGcc / Geom2dGcc_FunctionTanCirCu.cxx
1 // Created on: 1992-01-20
2 // Created by: Remi GILET
3 // Copyright (c) 1992-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17
18 #include <Geom2dAdaptor_Curve.hxx>
19 #include <Geom2dGcc_CurveTool.hxx>
20 #include <Geom2dGcc_FunctionTanCirCu.hxx>
21 #include <gp_Circ2d.hxx>
22 #include <gp_Pnt.hxx>
23 #include <gp_Pnt2d.hxx>
24 #include <gp_Vec.hxx>
25 #include <gp_Vec2d.hxx>
26
27 //=========================================================================
28 //  soit P1 le point sur la courbe Geom2dAdaptor_Curve d abscisse u.      +
29 //  soit C  le centre du cercle TheCirc.                                  +
30 //  Nous recherchons un point P2 appartenant au cercle tel que :          +
31 //           --->   -->                                                   +
32 //        *  P1P2 . CP2 = 0                                               +
33 //                                                                        +
34 //        *    -->  2    2                                                +
35 //           ||CP2||  = R                                                 +
36 //  Nous cherchons donc les zeros de la fonction suivante:                +
37 //                         -->  --> 2                                     +
38 //             -->  2    ( CP1 . T )      2                               +
39 //           ||CP1||  -  -----------  -  R   =  F(u)                      +
40 //                          --> 2                                         +
41 //                         ||T||                                          +
42 //                                                                        +
43 //  La derivee de cette fonction est :                                    +
44 //                                                                        +
45 //             2*(CP1.T)(CP1.N)     2*(CP1.T)*(CP1.T)*T.N                 +
46 //  f(u) =  -  ----------------  +  ---------------------                 +
47 //                  T.T                  (T.T)*(T.T)                      +
48 //=========================================================================
49 //                                                                        +
50 // skv: Small addition: The function and the derivative are normalized    +
51 //                      by an average square distance between the circle  +
52 //                      and the curve.                                    +
53 //=========================================================================
54 Geom2dGcc_FunctionTanCirCu::
55 Geom2dGcc_FunctionTanCirCu(const gp_Circ2d& Circ   ,
56                            const Geom2dAdaptor_Curve&  Curv   ) {
57                              Curve = Curv;
58                              TheCirc = Circ;
59
60                              //  Modified by Sergey KHROMOV - Thu Apr  5 09:51:21 2001 Begin
61                              Standard_Integer aNbSamp = Geom2dGcc_CurveTool::NbSamples(Curve);
62                              Standard_Real    aFirst  = Geom2dGcc_CurveTool::FirstParameter(Curve);
63                              Standard_Real    aLast   = Geom2dGcc_CurveTool::LastParameter(Curve);
64                              Standard_Real    aStep   = (aLast - aFirst)/aNbSamp;
65                              Standard_Real    anX     = aFirst + aStep/2.;
66                              Standard_Integer aNbP    = 0;
67                              gp_XY            aLoc(0., 0.);
68
69                              while (anX <= aLast) {
70                                aLoc += (Geom2dGcc_CurveTool::Value(Curve, anX)).XY();
71                                anX  += aStep;
72                                aNbP++;
73                              }
74                              myWeight = Max((aLoc - TheCirc.Location().XY()).SquareModulus(), TheCirc.Radius());
75                              //  Modified by Sergey KHROMOV - Thu Apr  5 09:51:25 2001 End
76 }
77
78
79 Standard_Boolean Geom2dGcc_FunctionTanCirCu::
80 Value (const Standard_Real  X    ,
81        Standard_Real& Fval ) {
82          gp_Pnt2d Point;
83          gp_Vec2d Vect1;
84          Geom2dGcc_CurveTool::D1(Curve,X,Point,Vect1);
85          Standard_Real NormeD1 = Vect1.Magnitude();
86          gp_Vec2d TheDirection(TheCirc.Location(),Point);
87          Standard_Real squaredir = TheDirection.Dot(TheDirection);
88          Standard_Real R = TheCirc.Radius();
89          Fval = squaredir-R*R-
90            (TheDirection.Dot(Vect1))*(TheDirection.Dot(Vect1))/(NormeD1*NormeD1);
91          //  Modified by Sergey KHROMOV - Thu Apr  5 17:38:05 2001 Begin
92          Fval /= myWeight;
93          //  Modified by Sergey KHROMOV - Thu Apr  5 17:38:06 2001 End
94          return Standard_True;
95 }
96
97 Standard_Boolean Geom2dGcc_FunctionTanCirCu::
98 Derivative (const Standard_Real  X     ,
99             Standard_Real& Deriv ) {
100               gp_Pnt2d Point;
101               gp_Vec2d Vect1,Vect2;
102               Geom2dGcc_CurveTool::D2(Curve,X,Point,Vect1,Vect2);
103               Standard_Real NormeD1 = Vect1.SquareMagnitude();
104               gp_Vec2d TheDirection(TheCirc.Location(),Point);
105               Standard_Real cp1dott = TheDirection.Dot(Vect1);
106               Deriv = -2.*(cp1dott/NormeD1)*
107                 ((TheDirection.Dot(Vect2))-cp1dott*Vect1.Dot(Vect2)/NormeD1);
108               //  Modified by Sergey KHROMOV - Thu Apr  5 17:38:15 2001 Begin
109               Deriv /= myWeight;
110               //  Modified by Sergey KHROMOV - Thu Apr  5 17:38:15 2001 End
111               return Standard_True;
112 }
113
114 Standard_Boolean Geom2dGcc_FunctionTanCirCu::
115 Values (const Standard_Real  X     ,
116         Standard_Real& Fval  ,
117         Standard_Real& Deriv ) {
118           gp_Pnt2d Point;
119           gp_Vec2d Vect1,Vect2;
120           Geom2dGcc_CurveTool::D2(Curve,X,Point,Vect1,Vect2);
121           Standard_Real NormeD1 = Vect1.SquareMagnitude();
122           gp_Vec2d TheDirection(TheCirc.Location(),Point);
123           Standard_Real squaredir = TheDirection.SquareMagnitude();
124           Standard_Real cp1dott = TheDirection.Dot(Vect1);
125           Standard_Real R = TheCirc.Radius();
126
127           Fval = squaredir-R*R-cp1dott*cp1dott/NormeD1;
128           //  Modified by Sergey KHROMOV - Thu Apr  5 17:38:28 2001 Begin
129           Fval /= myWeight;
130           //  Modified by Sergey KHROMOV - Thu Apr  5 17:38:28 2001 End
131
132           Deriv = -2.*(cp1dott/NormeD1)*
133             ((TheDirection.Dot(Vect2))-cp1dott*Vect1.Dot(Vect2)/NormeD1);
134           //  Modified by Sergey KHROMOV - Thu Apr  5 17:37:36 2001 Begin
135           Deriv /= myWeight;
136           //  Modified by Sergey KHROMOV - Thu Apr  5 17:37:37 2001 End
137           return Standard_True;
138 }