summaryrefslogtreecommitdiff
path: root/inc/GccIter_FunctionTanCirCu.gxx
blob: 9d380e5ba038edb6d3cdaa22ef452f0da09b68fd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
// File:	GccIter_FunctionTanCirCu.gxx
// Created:	Mon Jan 20 16:35:40 1992
// Author:	Remi GILET
//		<reg@phobox>

#include <gp_Vec2d.hxx>
#include <gp_Pnt2d.hxx>
#include <gp_Vec.hxx>
#include <gp_Pnt.hxx>

//=========================================================================
//  soit P1 le point sur la courbe TheCurve d abscisse u.                 +
//  soit C  le centre du cercle TheCirc.                                  +
//  Nous recherchons un point P2 appartenant au cercle tel que :          +
//           --->   -->                                                   +
//        *  P1P2 . CP2 = 0                                               +
//                                                                        +
//        *    -->  2    2                                                +
//           ||CP2||  = R                                                 +
//  Nous cherchons donc les zeros de la fonction suivante:                +
//                         -->  --> 2                                     +
//             -->  2    ( CP1 . T )      2                               +
//           ||CP1||  -  -----------  -  R   =  F(u)                      +
//                          --> 2                                         +
//                         ||T||                                          +
//                                                                        +
//  La derivee de cette fonction est :                                    +
//                                                                        +
//             2*(CP1.T)(CP1.N)     2*(CP1.T)*(CP1.T)*T.N                 +
//  f(u) =  -  ----------------  +  ---------------------                 +
//                  T.T                  (T.T)*(T.T)                      +
//=========================================================================
//                                                                        +
// skv: Small addition: The function and the derivative are normalized    +
//                      by an average square distance between the circle  +
//                      and the curve.                                    +
//=========================================================================

GccIter_FunctionTanCirCu::
  GccIter_FunctionTanCirCu(const gp_Circ2d& Circ   ,
			  const TheCurve&  Curv   ) {
  Curve = Curv;
  TheCirc = Circ;

//  Modified by Sergey KHROMOV - Thu Apr  5 09:51:21 2001 Begin
  Standard_Integer aNbSamp = TheCurveTool::NbSamples(Curve);
  Standard_Real    aFirst  = TheCurveTool::FirstParameter(Curve);
  Standard_Real    aLast   = TheCurveTool::LastParameter(Curve);
  Standard_Real    aStep   = (aLast - aFirst)/aNbSamp;
  Standard_Real    anX     = aFirst + aStep/2.;
  Standard_Integer aNbP    = 0;
  gp_XY            aLoc(0., 0.);

  while (anX <= aLast) {
    aLoc += (TheCurveTool::Value(Curve, anX)).XY();
    anX  += aStep;
    aNbP++;
  }
  myWeight = Max((aLoc - TheCirc.Location().XY()).SquareModulus(), TheCirc.Radius());
//  Modified by Sergey KHROMOV - Thu Apr  5 09:51:25 2001 End
 }


Standard_Boolean GccIter_FunctionTanCirCu::
  Value (const Standard_Real  X    ,
	       Standard_Real& Fval ) {
  gp_Pnt2d Point;
  gp_Vec2d Vect1;
  TheCurveTool::D1(Curve,X,Point,Vect1);
  Standard_Real NormeD1 = Vect1.Magnitude();
  gp_Vec2d TheDirection(TheCirc.Location(),Point);
  Standard_Real squaredir = TheDirection.Dot(TheDirection);
  Standard_Real R = TheCirc.Radius();
  Fval = squaredir-R*R-
    (TheDirection.Dot(Vect1))*(TheDirection.Dot(Vect1))/(NormeD1*NormeD1);
//  Modified by Sergey KHROMOV - Thu Apr  5 17:38:05 2001 Begin
  Fval /= myWeight;
//  Modified by Sergey KHROMOV - Thu Apr  5 17:38:06 2001 End
  return Standard_True;
}

Standard_Boolean GccIter_FunctionTanCirCu::
  Derivative (const Standard_Real  X     ,
	            Standard_Real& Deriv ) {
  gp_Pnt2d Point;
  gp_Vec2d Vect1,Vect2;
  TheCurveTool::D2(Curve,X,Point,Vect1,Vect2);
  Standard_Real NormeD1 = Vect1.SquareMagnitude();
  gp_Vec2d TheDirection(TheCirc.Location(),Point);
  Standard_Real cp1dott = TheDirection.Dot(Vect1);
  Deriv = -2.*(cp1dott/NormeD1)*
    ((TheDirection.Dot(Vect2))-cp1dott*Vect1.Dot(Vect2)/NormeD1);
//  Modified by Sergey KHROMOV - Thu Apr  5 17:38:15 2001 Begin
  Deriv /= myWeight;
//  Modified by Sergey KHROMOV - Thu Apr  5 17:38:15 2001 End
  return Standard_True;
}

Standard_Boolean GccIter_FunctionTanCirCu::
  Values (const Standard_Real  X     ,
	        Standard_Real& Fval  ,
	        Standard_Real& Deriv ) {
  gp_Pnt2d Point;
  gp_Vec2d Vect1,Vect2;
  TheCurveTool::D2(Curve,X,Point,Vect1,Vect2);
  Standard_Real NormeD1 = Vect1.SquareMagnitude();
  gp_Vec2d TheDirection(TheCirc.Location(),Point);
  Standard_Real squaredir = TheDirection.SquareMagnitude();
  Standard_Real cp1dott = TheDirection.Dot(Vect1);
  Standard_Real R = TheCirc.Radius();

  Fval = squaredir-R*R-cp1dott*cp1dott/NormeD1;
//  Modified by Sergey KHROMOV - Thu Apr  5 17:38:28 2001 Begin
  Fval /= myWeight;
//  Modified by Sergey KHROMOV - Thu Apr  5 17:38:28 2001 End

  Deriv = -2.*(cp1dott/NormeD1)*
    ((TheDirection.Dot(Vect2))-cp1dott*Vect1.Dot(Vect2)/NormeD1);
//  Modified by Sergey KHROMOV - Thu Apr  5 17:37:36 2001 Begin
  Deriv /= myWeight;
//  Modified by Sergey KHROMOV - Thu Apr  5 17:37:37 2001 End
  return Standard_True;
}