summaryrefslogtreecommitdiff
path: root/inc/GccGeo_Circ2dTanCen.gxx
blob: 411019d1de51edbb17739a7c76f140640df66505 (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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
// File GccGeo_Circ2dTanCen.gxx, REG 19/07/91

#include <StdFail_NotDone.hxx>
#include <Standard_OutOfRange.hxx>
#include <Standard_Failure.hxx>
#include <gp.hxx>
#include <gp_Ax2d.hxx>
#include <gp_Vec2d.hxx>
#include <TColStd_Array1OfInteger.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <Extrema_POnCurv2d.hxx>

//=========================================================================
//   Creation d un cercle tangent a une courbe centre en un point.        +
//=========================================================================

GccGeo_Circ2dTanCen::
   GccGeo_Circ2dTanCen (const TheQualifiedCurve& Qualified1,
                        const gp_Pnt2d&          Pcenter   ,
			const Standard_Real      Tolerance ):

//========================================================================
//   Initialisation des champs.                                          +
//========================================================================

   cirsol(1,2)    ,
   qualifier1(1,2),
   pnttg1sol(1,2) ,
   par1sol(1,2)   ,
   pararg1(1,2)   
{

  Standard_Real Tol = Abs(Tolerance);
  TColgp_Array1OfPnt2d pTan(1,2);
  TColStd_Array1OfInteger Index(1,2);
  TColStd_Array1OfReal theDist2(1,2);
  TColStd_Array1OfReal theParam(1,2);
  theDist2(1) = RealLast();
  theDist2(2) = 0.;
  Standard_Integer i = 1;
  Standard_Integer nbsol = 0;
  gp_Dir2d dirx(1.0,0.0);
  Standard_Real thePar;
  TheCurve curve = Qualified1.Qualified();
  TheExtPC distmin(Pcenter,curve,TheCurveTool::NbSamples(curve),
		   TheCurveTool::EpsX(curve,Tol),Tol);
  if (!distmin.IsDone() ) { Standard_Failure::Raise(); }
  Standard_Integer nbext = distmin.NbExt();
  if(nbext==0) { Standard_Failure::Raise(); }
  while (i<=nbext) {
    thePar = distmin.Point(i).Parameter();
    if (distmin.SquareDistance(i)<theDist2(1) && 
	thePar>=TheCurveTool::FirstParameter(curve) && 
	thePar <= TheCurveTool::LastParameter(curve)) {
      theDist2(1) = distmin.SquareDistance(i);
      theParam(1) = thePar;
      pTan(1) = distmin.Point(i).Value();
    }
    if (distmin.SquareDistance(i)>theDist2(2) && 
	thePar>=TheCurveTool::FirstParameter(curve) && 
	thePar <= TheCurveTool::LastParameter(curve)) {
      theDist2(2) = distmin.SquareDistance(i);
      theParam(2) = thePar;
      pTan(2) = distmin.Point(i).Value();
    }
    i++;
  }
  if (Index(1) == Index(2)) { nbsol = 1; }
  else { nbsol = 2; }
  for (i = 1 ; i <= nbsol; i++) {
    gp_Pnt2d point1;
    gp_Vec2d Tan1;
    TheCurveTool::D1(curve,theParam(i),point1,Tan1);
    Standard_Real normetan1 = Tan1.Magnitude();
    gp_Vec2d Vec1(point1,Pcenter);
    Standard_Real normevec1 = Vec1.Magnitude();
    Standard_Real dot1;
    if (normevec1 >= gp::Resolution() && normetan1 >= gp::Resolution()) {
      dot1 = Vec1.Dot(Tan1)/(normevec1*normetan1);
    }
    else { dot1 = 0.; }
    Tol = 1.e-12;
    if (dot1 <= Tol) {
      Standard_Real Angle1 = Vec1.Angle(Tan1);
      if (Qualified1.IsUnqualified()||
	  (Qualified1.IsEnclosing()&&Angle1<=0.)||
	  (Qualified1.IsOutside() && Angle1 >= 0.) ||
	  (Qualified1.IsEnclosed() && Angle1 <= 0.)) {
	NbrSol++;
	cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Pcenter,dirx),sqrt (theDist2(i)));
	qualifier1(NbrSol) = Qualified1.Qualifier();
	pararg1(NbrSol) = theParam(i);
	par1sol(NbrSol) = 0.;
	pnttg1sol(NbrSol) = pTan(i);
	WellDone = Standard_True;
      }
    }
  }
}



//=========================================================================


Standard_Boolean GccGeo_Circ2dTanCen::
   IsDone () const { return WellDone; }

Standard_Integer GccGeo_Circ2dTanCen::
   NbSolutions () const { return NbrSol; }

gp_Circ2d GccGeo_Circ2dTanCen::
   ThisSolution (const Standard_Integer Index) const 
{
  if (Index > NbrSol || Index <= 0) Standard_OutOfRange::Raise();

  return cirsol(Index);
}

void GccGeo_Circ2dTanCen::
  WhichQualifier(const Standard_Integer Index   ,
		       GccEnt_Position& Qualif1 ) const
{
  if (!WellDone) { StdFail_NotDone::Raise(); }
  else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
  else {
    Qualif1 = qualifier1(Index);
  }
}

void GccGeo_Circ2dTanCen::
   Tangency1 (const Standard_Integer Index,
                    Standard_Real&   ParSol,
                    Standard_Real&   ParArg,
              gp_Pnt2d& PntSol) const{
   if (!WellDone) {
     StdFail_NotDone::Raise();
   }
   else if (Index <= 0 ||Index > NbrSol) {
     Standard_OutOfRange::Raise();
   }
   else {
     PntSol = gp_Pnt2d(pnttg1sol(Index));
     ParSol = par1sol(Index);
     ParArg = pararg1(Index);
   }
 }