0031642: Visualization - crash in Graphic3d_Structure::SetVisual() on redisplaying...
[occt.git] / src / GccAna / GccAna_Circ2d2TanRad_3.cxx
CommitLineData
b311480e 1// Created on: 1991-09-24
2// Created by: Joelle CHAUVET
3// Copyright (c) 1991-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 8// This library is free software; you can redistribute it and/or modify it under
9// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 10// by the Free Software Foundation, with special exception defined in the file
11// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12// distribution for complete text of the license and disclaimer of any warranty.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
b311480e 16
7fd59977 17// Modified: Thu Jun 18 15:45:00 1998
7fd59977 18// PRO10310 : cas ou le point est sur la droite
19
7fd59977 20#include <ElCLib.hxx>
42cf5bc1 21#include <GccAna_Circ2d2TanRad.hxx>
22#include <GccEnt_BadQualifier.hxx>
23#include <GccEnt_QualifiedCirc.hxx>
24#include <GccEnt_QualifiedLin.hxx>
25#include <gp_Ax2d.hxx>
7fd59977 26#include <gp_Circ2d.hxx>
27#include <gp_Lin2d.hxx>
42cf5bc1 28#include <gp_Pnt2d.hxx>
7fd59977 29#include <IntAna2d_AnaIntersection.hxx>
30#include <IntAna2d_IntPoint.hxx>
7fd59977 31#include <Standard_NegativeValue.hxx>
42cf5bc1 32#include <Standard_OutOfRange.hxx>
33#include <StdFail_NotDone.hxx>
34#include <TColStd_Array1OfReal.hxx>
7fd59977 35
0d969553 36// circular tangent to a line and a point and a given radius
7fd59977 37//=============================================================
38//========================================================================
0d969553
Y
39// Initialize WellDone to false. +
40// Return line L1. +
41// Leave with error if the construction is impossible. +
42// Create parallel to L1 in the proper direction. +
43// Create the circle with center at Point1 of radius Radius. +
44// Intersect the parallel and the circle. +
45// ==> The center point of the solution. +
46// Create the solution to be added to already found solutions. +
47// Fill the fields. +
7fd59977 48//========================================================================
7fd59977 49GccAna_Circ2d2TanRad::
50 GccAna_Circ2d2TanRad (const GccEnt_QualifiedLin& Qualified1 ,
51 const gp_Pnt2d& Point2 ,
52 const Standard_Real Radius ,
53 const Standard_Real Tolerance ):
54 qualifier1(1,2) ,
55 qualifier2(1,2),
56 TheSame1(1,2) ,
57 TheSame2(1,2) ,
58 cirsol(1,2) ,
59 pnttg1sol(1,2) ,
60 pnttg2sol(1,2) ,
61 par1sol(1,2) ,
62 par2sol(1,2) ,
63 pararg1(1,2) ,
64 pararg2(1,2)
65{
66
67 gp_Dir2d dirx(1.0,0.0);
68 Standard_Real Tol = Abs(Tolerance);
69 NbrSol = 0;
70 WellDone = Standard_False;
71 if (!(Qualified1.IsEnclosed() || Qualified1.IsOutside() ||
72 Qualified1.IsUnqualified())) {
9775fa61 73 throw GccEnt_BadQualifier();
7fd59977 74 return;
75 }
76 Standard_Integer nbsol = 0;
77 Standard_Integer nbcote=0;
78 TColStd_Array1OfReal cote(1,2);
79 gp_Lin2d L1 = Qualified1.Qualified();
80 Standard_Real displ1 = L1.Distance(Point2);
81 Standard_Real xdir = (L1.Direction()).X();
82 Standard_Real ydir = (L1.Direction()).Y();
83 Standard_Real lxloc = (L1.Location()).X();
84 Standard_Real lyloc = (L1.Location()).Y();
85 gp_Pnt2d origin1(lxloc,lyloc);
86 gp_Dir2d normL1(-ydir,xdir);
87 Standard_Real cxloc = Point2.X();
88 Standard_Real cyloc = Point2.Y();
89
9775fa61 90 if (Radius < 0.0) { throw Standard_NegativeValue(); }
7fd59977 91
92 else {
93 if ( displ1-Radius*2.0 > Tol) { WellDone = Standard_True; }
94 else if (Qualified1.IsEnclosed()) {
95// =================================
96 if ((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)<0.0)) {
97 WellDone = Standard_True;
98 }
99 else {
100 if ( displ1-Radius*2.0 > 0.0) {
101 nbsol = 2;
102 NbrSol = 1;
103 nbcote = 1;
104 cote(1) = 1.0;
105 }
106 else {
107 nbsol = 1;
108 nbcote = 1;
109 cote(1) = 1.0;
110 }
111 }
112 }
113 else if (Qualified1.IsOutside()) {
114// ================================
115 if ((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)>0.0)) {
116 WellDone = Standard_True;
117 }
118 else {
119 if ( displ1-Radius*2.0 > 0.0) {
120 nbsol = 2;
121 nbcote = 1;
122 cote(1) = -1.0;
123 }
124 else {
125 nbsol = 1;
126 nbcote = 1;
127 cote(1) = -1.0;
128 }
129 }
130 }
131 else if (Qualified1.IsUnqualified()) {
132// ====================================
133 if ( displ1-Radius*2.0 > 0.0) {
134 if ((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)>0.0)) {
135 nbsol = 2;
136 nbcote = 1;
137 cote(1) = 1.0;
138 }
139 else if ((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)<0.0)) {
140 nbsol = 2;
141 nbcote = 1;
142 cote(1) = -1.0;
143 }
144 }
145 else {
146 nbsol = 1;
147 nbcote = 2;
148 cote(1) = 1.0;
149 cote(2) = -1.0;
150 }
151 }
152
153 if (nbsol == 1) {
154 if (displ1<1.e-10) {
0d969553
Y
155 // particular case when Point2 is on the line
156 // construct two solutions directly
7fd59977 157 for (Standard_Integer jcote = 1 ; jcote <= nbcote ; jcote++) {
158 NbrSol++;
159 gp_Pnt2d Center(cxloc-cote(jcote)*ydir*Radius,
160 cyloc+cote(jcote)*xdir*Radius);
161 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
162// =======================================================
163 qualifier2(NbrSol) = GccEnt_noqualifier;
164 if (!Qualified1.IsUnqualified()) {
165 qualifier1(NbrSol) = Qualified1.Qualifier();
166 }
167 else if (cote(jcote) > 0.0) {
168 qualifier1(NbrSol) = GccEnt_outside;
169 }
170 else {
171 qualifier1(NbrSol) = GccEnt_enclosed;
172 }
173 TheSame1(NbrSol) = 0;
174 TheSame2(NbrSol) = 0;
175 pnttg1sol(NbrSol) = Point2;
176 pnttg2sol(NbrSol) = Point2;
177 }
178 WellDone = Standard_True;
179 }
180 else {
181 gp_Circ2d cirint(gp_Ax2d(Point2,dirx),Radius);
182 for (Standard_Integer jcote = 1 ; jcote <= nbcote ; jcote++) {
183 gp_Lin2d linint(gp_Pnt2d(lxloc-cote(jcote)*ydir*Radius,
184 lyloc+cote(jcote)*xdir*Radius),
185 L1.Direction());
186 IntAna2d_AnaIntersection Intp(linint,cirint);
187 if (Intp.IsDone()) {
188 if (!Intp.IsEmpty()) {
189 for (Standard_Integer i = 1 ; i <= Intp.NbPoints() && NbrSol<2; i++) {
190 NbrSol++;
191 gp_Pnt2d Center(Intp.Point(i).Value());
192 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
193 // =======================================================
194 gp_Dir2d dc1(origin1.XY()-Center.XY());
195 qualifier2(NbrSol) = GccEnt_noqualifier;
196 if (!Qualified1.IsUnqualified()) {
197 qualifier1(NbrSol) = Qualified1.Qualifier();
198 }
199 else if (dc1.Dot(normL1) > 0.0) {
200 qualifier1(NbrSol) = GccEnt_outside;
201 }
202 else { qualifier1(NbrSol) = GccEnt_enclosed; }
203 TheSame1(NbrSol) = 0;
204 TheSame2(NbrSol) = 0;
205 pnttg1sol(NbrSol)=gp_Pnt2d(Center.XY()+
206 cote(jcote)*Radius*gp_XY(ydir,-xdir));
207 pnttg2sol(NbrSol) = Point2;
208 }
209 }
210 WellDone = Standard_True;
211 }
212 }
213 }
214 }
215
216 else if (nbsol == 2) {
217 gp_Pnt2d Center(Point2.XY()+cote(1)*Radius*gp_XY(-ydir,xdir));
218 WellDone = Standard_True;
219 NbrSol = 1;
220 cirsol(1) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
221// ==================================================
222 qualifier2(1) = GccEnt_noqualifier;
223 TheSame1(1) = 0;
224 TheSame2(1) = 0;
225 pnttg1sol(1)=gp_Pnt2d(Center.XY()+cote(1)*Radius*gp_XY(ydir,-xdir));
226 pnttg2sol(1) = Point2;
227 }
228 }
229
230 for (Standard_Integer i = 1 ; i <= NbrSol ; i++) {
231 par1sol(i)=ElCLib::Parameter(cirsol(i),pnttg1sol(i));
232 pararg1(i)=ElCLib::Parameter(L1,pnttg1sol(i));
233 par2sol(i)=ElCLib::Parameter(cirsol(i),pnttg2sol(i));
234 pararg2(i)=0.;
235 }
236
237}
238
239
240
241