CommitLineData
b311480e 1// Copyright (c) 1995-1999 Matra Datavision
b311480e 3//
973c2be1 4// This file is part of Open CASCADE Technology software library.
b311480e 5//
973c2be1 6// This library is free software; you can redistribute it and / or modify it
7// under the terms of the GNU Lesser General Public version 2.1 as published
8// by the Free Software Foundation, with special exception defined in the file
9// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10// distribution for complete text of the license and disclaimer of any warranty.
b311480e 11//
973c2be1 12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
7fd59977 14
16
17#include <ElCLib.hxx>
18#include <math_DirectPolynomialRoots.hxx>
19#include <Standard_NegativeValue.hxx>
20#include <Standard_OutOfRange.hxx>
21#include <gp_Dir2d.hxx>
22
23//=========================================================================
0d969553 24// typedef of handled objects : +
7fd59977 25//=========================================================================
26
27typedef math_DirectPolynomialRoots Roots;
28
29//=========================================================================
0d969553
Y
30// Circle tangent to a point Point1. +
31// center on straight line OnLine. +
7fd59977 33// +
0d969553
Y
34// Initialize the table of solutions cirsol and all fields. +
35// Eliminate cases not being the solution. +
36// Solve the equation of second degree showing that the found center point +
37// (xc,yc) is at distance Radius from point Point1 and on the straight line OnLine. +
38// The solutions are represented by circles : +
39// - of center Pntcen(xc,yc) +
7fd59977 41//=========================================================================
42
44 GccAna_Circ2dTanOnRad (const gp_Pnt2d& Point1 ,
45 const gp_Lin2d& OnLine ,
47 const Standard_Real Tolerance ):
48 cirsol(1,2) ,
49 qualifier1(1,2) ,
50 TheSame1(1,2) ,
51 pnttg1sol(1,2),
52 pntcen3(1,2) ,
53 par1sol(1,2) ,
54 pararg1(1,2) ,
55 parcen3(1,2)
56{
57
58 gp_Dir2d dirx(1.0,0.0);
59 Standard_Real Tol = Abs(Tolerance);
60 WellDone = Standard_False;
61 NbrSol = 0;
62 Standard_Real dp1lin = OnLine.Distance(Point1);
63
64 if (Radius < 0.0) { Standard_NegativeValue::Raise(); }
65 else {
66 if (dp1lin > Radius+Tol) { WellDone = Standard_True; }
67 Standard_Real xc;
68 Standard_Real yc;
69 Standard_Real x1 = Point1.X();
70 Standard_Real y1 = Point1.Y();
71 Standard_Real xbid = 0;
72 Standard_Real xdir = (OnLine.Direction()).X();
73 Standard_Real ydir = (OnLine.Direction()).Y();
74 Standard_Real lxloc = (OnLine.Location()).X();
75 Standard_Real lyloc = (OnLine.Location()).Y();
76 if (Abs(dp1lin-Radius) < Tol) {
77 WellDone = Standard_True;
78 NbrSol = 1;
79 if (-ydir*(x1-lxloc)+xdir*(y1-lyloc)<0.0) {
80 gp_Ax2d axe(gp_Pnt2d(x1-ydir*dp1lin,y1+xdir*dp1lin),dirx);
82// ======================================
83 qualifier1(NbrSol) = GccEnt_noqualifier;
84 }
85 else {
86 gp_Ax2d axe(gp_Pnt2d(x1+ydir*dp1lin,y1-xdir*dp1lin),dirx);
88// ======================================
89 qualifier1(NbrSol) = GccEnt_noqualifier;
90 }
91 TheSame1(NbrSol) = 0;
92 pnttg1sol(NbrSol) = Point1;
93 pntcen3(NbrSol) = cirsol(NbrSol).Location();
94 pararg1(NbrSol) = 0.0;
95 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),pnttg1sol(NbrSol));
96 parcen3(NbrSol)=ElCLib::Parameter(OnLine,pntcen3(NbrSol));
97 }
98 else if (dp1lin < Tol) {
101 pntcen3(1) = ElCLib::Value(ElCLib::Parameter(OnLine,pntcen3(1)),OnLine);
102 pntcen3(2) = ElCLib::Value(ElCLib::Parameter(OnLine,pntcen3(2)),OnLine);
103 gp_Ax2d axe(pntcen3(1),OnLine.Direction());
105 axe = gp_Ax2d(pntcen3(2),OnLine.Direction());
107 TheSame1(1) = 0;
108 pnttg1sol(1) = Point1;
109 pararg1(1) = 0.0;
110 par1sol(1)=ElCLib::Parameter(cirsol(1),pnttg1sol(1));
111 parcen3(1)=ElCLib::Parameter(OnLine,pntcen3(1));
112 TheSame1(2) = 0;
113 pnttg1sol(2) = Point1;
114 pararg1(2) = 0.0;
115 par1sol(2)=ElCLib::Parameter(cirsol(2),pnttg1sol(2));
116 parcen3(2)=ElCLib::Parameter(OnLine,pntcen3(2));
117 NbrSol = 2;
118 }
119 else {
120 Standard_Real A,B,C;
121 OnLine.Coefficients(A,B,C);
122 Standard_Real D = A;
123 if (A == 0.0) {
124 A = B;
125 B = D;
126 xbid = x1;
127 x1 = y1;
128 y1 = xbid;
129 }
130 if (A != 0.0) {
131 Roots Sol((B*B+A*A)/(A*A),
132 2.0*(B*C/(A*A)+(B/A)*x1-y1),
134 if (Sol.IsDone()) {
135 for (Standard_Integer i = 1 ; i <= Sol.NbSolutions() ; i++) {
136 if (D != 0.0) {
137 yc = Sol.Value(i);
138 xc = -(B/A)*yc-C/A;
139 }
140 else {
141 xc = Sol.Value(i);
142 yc = -(B/A)*xc-C/A;
143 }
144 NbrSol++;
145 gp_Pnt2d Center(xc,yc);
147// =======================================================
148 qualifier1(NbrSol) = GccEnt_noqualifier;
149 TheSame1(NbrSol) = 0;
150 pnttg1sol(NbrSol) = Point1;
151 pntcen3(NbrSol) = cirsol(NbrSol).Location();
152 pararg1(NbrSol) = 0.0;
153 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
154 pnttg1sol(NbrSol));
155 parcen3(NbrSol)=ElCLib::Parameter(OnLine,pntcen3(NbrSol));
156 }
157 WellDone = Standard_True;
158 }
159 }
160 }
161 }
162 }