0022792: Globally defined symbol PI conflicts with VTK definition (Intel compiler)
[occt.git] / src / GccIter / GccIter_Lin2dTanObl.gxx
1 // File:        GccIter_Lin2dTanObl.cxx
2 // Created:     Fri Dec 20 15:00:23 1991
3 // Author:      Remi GILET
4 //              <reg@topsn3>
5
6 //========================================================================
7 // CREATION D UNE LIGNE TANGENTE A UNE COURBE ET PARALLELE A UNE DROITE. +
8 //========================================================================
9
10 #include <IntAna2d_AnaIntersection.hxx>
11 #include <IntAna2d_IntPoint.hxx>
12 #include <GccIter_IsParallel.hxx>
13 #include <StdFail_NotDone.hxx>
14 #include <GccEnt_BadQualifier.hxx>
15 #include <math_FunctionRoot.hxx>
16 #include <gp_XY.hxx>
17 #include <gp_Dir2d.hxx>
18 #include <gp_Vec2d.hxx>
19 #include <gp_Circ2d.hxx>
20
21 GccIter_Lin2dTanObl::
22    GccIter_Lin2dTanObl (const TheQualifiedCurve& Qualified1 ,
23                         const gp_Lin2d&          TheLin     ,
24                         const Standard_Real      Param1     ,
25                         const Standard_Real      TolAng     ,
26                         const Standard_Real      Angle      ) {
27
28    par1sol = 0.;
29    pararg1 = 0.;
30    WellDone = Standard_False;
31    if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() || 
32          Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
33      GccEnt_BadQualifier::Raise();
34      return;
35    }
36    Paral2 = Standard_False;
37    TheCurve Cu1 = Qualified1.Qualified();
38    Standard_Real U1 = TheCurveTool::FirstParameter(Cu1);
39    Standard_Real U2 = TheCurveTool::LastParameter(Cu1);
40    gp_Dir2d Dir(TheLin.Direction());
41    Standard_Real A = Dir.X();
42    Standard_Real B = Dir.Y();
43    gp_Dir2d TheDirection(Dir);
44    if (Abs(Angle) > Abs(TolAng)) {
45      if (Abs(Abs(Angle)-M_PI) <= Abs(TolAng)) {
46        Paral2 = Standard_True;
47        TheDirection = Dir.Reversed();
48      }
49      else if (Abs(Angle-M_PI/2) <= Abs(TolAng)) { TheDirection=gp_Dir2d(-B,A); }
50      else if (Abs(Angle+M_PI/2) <= Abs(TolAng)) { TheDirection=gp_Dir2d(B,-A); }
51      else {
52        TheDirection=gp_Dir2d(A*Cos(Angle)-B*Sin(Angle),
53                              A*Sin(Angle)+B*Cos(Angle));
54      }
55    }
56    else { Paral2 = Standard_True; }
57    GccIter_FuncTObl func(Cu1,TheDirection);
58    math_FunctionRoot sol(func,Param1,
59                          TheCurveTool::EpsX(Cu1,Abs(TolAng)),U1,U2,100);
60    if (sol.IsDone()) {
61      Standard_Real Usol = sol.Root();
62      gp_Pnt2d Origine;
63      gp_Vec2d Vect1,Vect2;
64      TheCurveTool::D2(Cu1,Usol,Origine,Vect1,Vect2);
65      Standard_Real sign1 = Vect1.XY().Dot(TheDirection.XY());
66      Standard_Real sign2 = Vect2.XY().Crossed(TheDirection.XY());
67      if (Qualified1.IsUnqualified() || 
68          (Qualified1.IsEnclosing() && sign2<=0.) ||
69          (Qualified1.IsOutside() && sign1 <= 0. && sign2 >= 0.) ||
70          (Qualified1.IsEnclosed() && sign1 >= 0. && sign2 >= 0.)) {
71        WellDone = Standard_True;
72        linsol = gp_Lin2d(Origine,TheDirection);
73        pnttg1sol = Origine;
74        qualifier1 = Qualified1.Qualifier();
75        pararg1 = Usol;
76        par1sol = 0.;
77        if (!Paral2) {
78          IntAna2d_AnaIntersection Intp(linsol,TheLin);
79          if (Intp.IsDone() && !Intp.IsEmpty()) {
80            if (Intp.NbPoints()==1) {
81              pntint2sol = Intp.Point(1).Value();
82              par2sol = gp_Vec2d(linsol.Direction()).
83                Dot(gp_Vec2d(linsol.Location(),pntint2sol));
84              pararg2 = gp_Vec2d(TheLin.Direction()).
85                Dot(gp_Vec2d(TheLin.Location(),pntint2sol));
86            }
87          }
88        }
89      }
90    }
91  }
92
93 Standard_Boolean GccIter_Lin2dTanObl::
94    IsDone () const { return WellDone; }
95
96 gp_Lin2d GccIter_Lin2dTanObl::ThisSolution () const 
97 {       
98   if (!WellDone) StdFail_NotDone::Raise();
99
100   return linsol;
101 }
102
103 void GccIter_Lin2dTanObl:: 
104   WhichQualifier (GccEnt_Position& Qualif1) const
105 {
106   if (!WellDone) { StdFail_NotDone::Raise(); }
107   else {
108     Qualif1 = qualifier1;
109   }
110 }
111
112 Standard_Boolean GccIter_Lin2dTanObl::
113    IsParallel2 () const { return Paral2; }
114
115 void GccIter_Lin2dTanObl::
116    Tangency1 (Standard_Real& ParSol    ,
117               Standard_Real& ParArg    ,
118               gp_Pnt2d& PntSol) const {
119    if (!WellDone) { StdFail_NotDone::Raise(); }
120    else {
121      ParSol = par1sol;
122      ParArg = pararg1;
123      PntSol = gp_Pnt2d(pnttg1sol);
124    }
125  }
126
127 void GccIter_Lin2dTanObl::
128   Intersection2 (Standard_Real&     ParSol ,
129                  Standard_Real&     ParArg ,
130                  gp_Pnt2d& PntSol ) const {
131    if (!WellDone) { StdFail_NotDone::Raise(); }
132    else if (Paral2) { GccIter_IsParallel::Raise(); }
133    else {
134      PntSol = pntint2sol;
135      ParSol = par2sol;
136      ParArg = pararg2;
137    }
138  }
139