0023024: Update headers of OCCT files
[occt.git] / src / GccAna / GccAna_Circ2d2TanOn_4.cxx
CommitLineData
b311480e 1// Created on: 1992-01-02
2// Created by: Remi GILET
3// Copyright (c) 1992-1999 Matra Datavision
4// Copyright (c) 1999-2012 OPEN CASCADE SAS
5//
6// The content of this file is subject to the Open CASCADE Technology Public
7// License Version 6.5 (the "License"). You may not use the content of this file
8// except in compliance with the License. Please obtain a copy of the License
9// at http://www.opencascade.org and read it completely before using this file.
10//
11// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13//
14// The Original Code and all software distributed under the License is
15// distributed on an "AS IS" basis, without warranty of any kind, and the
16// Initial Developer hereby disclaims all such warranties, including without
17// limitation, any warranties of merchantability, fitness for a particular
18// purpose or non-infringement. Please see the License for the specific terms
19// and conditions governing the rights and limitations under the License.
20
7fd59977 21
22#include <GccAna_Circ2d2TanOn.jxx>
23
24#include <ElCLib.hxx>
25#include <gp_Dir2d.hxx>
26#include <gp_Ax2d.hxx>
27#include <GccAna_LinPnt2dBisec.hxx>
28#include <IntAna2d_AnaIntersection.hxx>
29#include <IntAna2d_IntPoint.hxx>
30#include <GccInt_IType.hxx>
31#include <GccInt_Bisec.hxx>
32#include <GccInt_BCirc.hxx>
33#include <GccInt_BLine.hxx>
34#include <IntAna2d_Conic.hxx>
35#include <GccEnt_BadQualifier.hxx>
36#include <Precision.hxx>
37//=========================================================================
0d969553
Y
38// Creation of a circle Tangent to : 1 straight line L1. +
39// Passing by : 1 point Point2. +
40// Centered on : 1 straight line OnLine. +
41// with a Tolerance of precision : Tolerance. +
7fd59977 42// +
0d969553
Y
43// We start by making difference with various boundary cases that will be +
44// processed separately. +
45// For the general case: +
7fd59977 46// ==================== +
0d969553
Y
47// We calculate bissectrices to L1 and Point2 that give us +
48// all possible locations of centers of all circles +
49// tangent to L1 and passing through Point2. +
50// We intersect these bissectrices with straight line OnLine which gives us +
51// the points among which we'll choose the solutions. +
52// The choices are made basing on Qualifieurs of L1. +
7fd59977 53//=========================================================================
54
55GccAna_Circ2d2TanOn::
56 GccAna_Circ2d2TanOn (const GccEnt_QualifiedLin& Qualified1 ,
57 const gp_Pnt2d& Point2 ,
58 const gp_Lin2d& OnLine ,
59 const Standard_Real Tolerance ):
60 cirsol(1,4) ,
61 qualifier1(1,4) ,
62 qualifier2(1,4),
63 TheSame1(1,4) ,
64 TheSame2(1,4) ,
65 pnttg1sol(1,4) ,
66 pnttg2sol(1,4) ,
67 pntcen(1,4) ,
68 par1sol(1,4) ,
69 par2sol(1,4) ,
70 pararg1(1,4) ,
71 pararg2(1,4) ,
72 parcen3(1,4)
73{
74 TheSame1.Init(0);
75 TheSame2.Init(0);
76 WellDone = Standard_False;
77 NbrSol = 0;
78 if (!(Qualified1.IsEnclosed() ||
79 Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
80 GccEnt_BadQualifier::Raise();
81 return;
82 }
83 Standard_Real Tol = Abs(Tolerance);
84 gp_Dir2d dirx(1.,0.);
85 gp_Lin2d L1 = Qualified1.Qualified();
86 gp_Pnt2d originL1(L1.Location());
87 gp_Dir2d dirL1(L1.Direction());
88 gp_Dir2d normal(-dirL1.Y(),dirL1.X());
89
90//=========================================================================
0d969553 91// Processing of boundary cases. +
7fd59977 92//=========================================================================
93
94 if (dirL1.IsEqual(OnLine.Direction(),Precision::Confusion()) &&
95 OnLine.Distance(originL1)<Precision::Confusion()) {
0d969553 96 // POP : l2s 2 straight line are identic : no Sol
7fd59977 97 NbrSol = 0;
98 return ;
99 }
100
101
102 Standard_Real dp2l = OnLine.Distance(Point2);
103 gp_Dir2d donline(OnLine.Direction());
104 gp_Pnt2d pinterm(Point2.XY()+dp2l*gp_XY(-donline.Y(),donline.X()));
105 if (OnLine.Distance(pinterm) > Tol) {
106 pinterm = gp_Pnt2d(Point2.XY()-dp2l*gp_XY(-donline.Y(),donline.X()));
107 }
108 Standard_Real dist = L1.Distance(pinterm);
109 if (Abs(dist-dp2l) <= Tol) {
110 gp_Dir2d dirbid(originL1.XY()-pinterm.XY());
111 if (Qualified1.IsEnclosed() && dirbid.Dot(normal)<0.) {
112 WellDone = Standard_True;
113 }
114 else if (Qualified1.IsOutside() && dirbid.Dot(normal) > 0.) {
115 WellDone = Standard_True;
116 }
117 else if (Qualified1.IsUnqualified()) { WellDone = Standard_True; }
118 if (WellDone) {
119 NbrSol++;
120 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(pinterm,dirx),dp2l);
121// ======================================================
122 qualifier2(NbrSol) = GccEnt_noqualifier;
123 gp_Dir2d dc2(originL1.XY()-pinterm.XY());
124 if (!Qualified1.IsUnqualified()) {
125 qualifier1(NbrSol) = Qualified1.Qualifier();
126 }
127 else if (dc2.Dot(normal) > 0.0) {
128 qualifier1(NbrSol) = GccEnt_outside;
129 }
130 else { qualifier1(NbrSol) = GccEnt_enclosed; }
131 Standard_Real sign = dc2.Dot(gp_Dir2d(-dirL1.Y(),
132 dirL1.X()));
133 dc2 = gp_Dir2d(sign*gp_XY(-dirL1.Y(),dirL1.X()));
134 pnttg1sol(NbrSol) = gp_Pnt2d(pinterm.XY()+dp2l*dc2.XY());
135 pnttg2sol(NbrSol) = Point2;
136 pntcen(NbrSol) = pinterm;
137 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),pnttg1sol(NbrSol));
138 pararg1(NbrSol)=ElCLib::Parameter(L1,pnttg1sol(NbrSol));
139 par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),pnttg2sol(NbrSol));
140 pararg2(NbrSol) = 0.;
141 parcen3(NbrSol)=ElCLib::Parameter(OnLine,pntcen(NbrSol));
142 return;
143 }
144 }
145
146//=========================================================================
0d969553 147// General case. +
7fd59977 148//=========================================================================
149
150 GccAna_LinPnt2dBisec Bis(L1,Point2);
151 if (Bis.IsDone()) {
152 Handle(GccInt_Bisec) Sol = Bis.ThisSolution();
153 GccInt_IType type = Sol->ArcType();
154 IntAna2d_AnaIntersection Intp;
155 if (type == GccInt_Lin) {
156 Intp.Perform(OnLine,Sol->Line());
157 }
158 if (type == GccInt_Par) {
159 Intp.Perform(OnLine,IntAna2d_Conic(Sol->Parabola()));
160 }
161 if (Intp.IsDone()) {
162 if (!Intp.IsEmpty()) {
163 for (Standard_Integer j = 1 ; j <= Intp.NbPoints() ; j++) {
164 gp_Pnt2d Center(Intp.Point(j).Value());
165 Standard_Real Radius = L1.Distance(Center);
166// Standard_Integer nbsol = 1;
167 Standard_Boolean ok = Standard_False;
168 if (Qualified1.IsEnclosed()) {
169 if ((((originL1.X()-Center.X())*(-dirL1.Y()))+
170 ((originL1.Y()-Center.Y())*(dirL1.X())))<=0){
171 ok = Standard_True;
172 }
173 }
174 else if (Qualified1.IsOutside()) {
175 if ((((originL1.X()-Center.X())*(-dirL1.Y()))+
176 ((originL1.Y()-Center.Y())*(dirL1.X())))>=0){
177 ok = Standard_True;
178 }
179 }
180 else if (Qualified1.IsUnqualified()) {
181 ok = Standard_True;
182 }
183 if (ok) {
184 NbrSol++;
185 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
186// =======================================================
187 qualifier2(NbrSol) = GccEnt_noqualifier;
188 gp_Dir2d dc2(originL1.XY()-Center.XY());
189 if (!Qualified1.IsUnqualified()) {
190 qualifier1(NbrSol) = Qualified1.Qualifier();
191 }
192 else if (dc2.Dot(normal) > 0.0) {
193 qualifier1(NbrSol) = GccEnt_outside;
194 }
195 else { qualifier1(NbrSol) = GccEnt_enclosed; }
196 TheSame1(NbrSol) = 0;
197 TheSame2(NbrSol) = 0;
198 gp_Dir2d dc1(originL1.XY()-Center.XY());
199 Standard_Real sign = dc1.Dot(gp_Dir2d(normal));
200 dc1=gp_Dir2d(sign*(normal.XY()));
201 pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius*dc1.XY());
202 pnttg2sol(NbrSol) = Point2;
203 pntcen(NbrSol) = Center;
204 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
205 pnttg1sol(NbrSol));
206 pararg1(NbrSol)=ElCLib::Parameter(L1,pnttg1sol(NbrSol));
207 par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
208 pnttg2sol(NbrSol));
209 pararg2(NbrSol) = 0.;
210 parcen3(NbrSol)=ElCLib::Parameter(OnLine,pntcen(NbrSol));
211 }
212 }
213 }
214 WellDone = Standard_True;
215 }
216 }
217}
218