54e37688 |
1 | // Created on: 1991-12-20 |
2 | // Created by: Remi GILET |
3 | // Copyright (c) 1991-1999 Matra Datavision |
4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
5 | // |
6 | // This file is part of Open CASCADE Technology software library. |
7 | // |
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 |
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. |
13 | // |
14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. |
16 | |
17 | //======================================================================== |
18 | // CREATION D UNE LIGNE TANGENTE A UNE COURBE ET PARALLELE A UNE DROITE. + |
19 | //======================================================================== |
20 | |
54e37688 |
21 | #include <GccEnt_BadQualifier.hxx> |
54e37688 |
22 | #include <Geom2dGcc_CurveTool.hxx> |
23 | #include <Geom2dGcc_FunctionTanObl.hxx> |
42cf5bc1 |
24 | #include <Geom2dGcc_IsParallel.hxx> |
25 | #include <Geom2dGcc_Lin2dTanOblIter.hxx> |
26 | #include <Geom2dGcc_QCurve.hxx> |
27 | #include <gp_Circ2d.hxx> |
28 | #include <gp_Dir2d.hxx> |
29 | #include <gp_Lin2d.hxx> |
30 | #include <gp_Pnt2d.hxx> |
31 | #include <gp_Vec2d.hxx> |
32 | #include <gp_XY.hxx> |
33 | #include <IntAna2d_AnaIntersection.hxx> |
34 | #include <IntAna2d_IntPoint.hxx> |
35 | #include <math_FunctionRoot.hxx> |
36 | #include <StdFail_NotDone.hxx> |
54e37688 |
37 | |
38 | Geom2dGcc_Lin2dTanOblIter:: |
39 | Geom2dGcc_Lin2dTanOblIter (const Geom2dGcc_QCurve& Qualified1 , |
40 | const gp_Lin2d& TheLin , |
41 | const Standard_Real Param1 , |
42 | const Standard_Real TolAng , |
43 | const Standard_Real Angle ) |
44 | { |
45 | |
46 | par1sol = 0.; |
47 | pararg1 = 0.; |
48 | WellDone = Standard_False; |
49 | if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() || |
50 | Qualified1.IsOutside() || Qualified1.IsUnqualified())) { |
9775fa61 |
51 | throw GccEnt_BadQualifier(); |
54e37688 |
52 | return; |
53 | } |
54 | Paral2 = Standard_False; |
55 | Geom2dAdaptor_Curve Cu1 = Qualified1.Qualified(); |
56 | Standard_Real U1 = Geom2dGcc_CurveTool::FirstParameter(Cu1); |
57 | Standard_Real U2 = Geom2dGcc_CurveTool::LastParameter(Cu1); |
58 | gp_Dir2d Dir(TheLin.Direction()); |
59 | Standard_Real A = Dir.X(); |
60 | Standard_Real B = Dir.Y(); |
61 | gp_Dir2d TheDirection(Dir); |
62 | if (Abs(Angle) > Abs(TolAng)) { |
63 | if (Abs(Abs(Angle)-M_PI) <= Abs(TolAng)) { |
64 | Paral2 = Standard_True; |
65 | TheDirection = Dir.Reversed(); |
66 | } |
67 | else if (Abs(Angle-M_PI/2) <= Abs(TolAng)) { TheDirection=gp_Dir2d(-B,A); } |
68 | else if (Abs(Angle+M_PI/2) <= Abs(TolAng)) { TheDirection=gp_Dir2d(B,-A); } |
69 | else { |
70 | TheDirection=gp_Dir2d(A*Cos(Angle)-B*Sin(Angle), |
71 | A*Sin(Angle)+B*Cos(Angle)); |
72 | } |
73 | } |
74 | else { Paral2 = Standard_True; } |
75 | Geom2dGcc_FunctionTanObl func(Cu1,TheDirection); |
76 | math_FunctionRoot sol(func,Param1, |
77 | Geom2dGcc_CurveTool::EpsX(Cu1,Abs(TolAng)),U1,U2,100); |
78 | if (sol.IsDone()) { |
79 | Standard_Real Usol = sol.Root(); |
80 | gp_Pnt2d Origine; |
81 | gp_Vec2d Vect1,Vect2; |
82 | Geom2dGcc_CurveTool::D2(Cu1,Usol,Origine,Vect1,Vect2); |
83 | Standard_Real sign1 = Vect1.XY().Dot(TheDirection.XY()); |
84 | Standard_Real sign2 = Vect2.XY().Crossed(TheDirection.XY()); |
85 | if (Qualified1.IsUnqualified() || |
86 | (Qualified1.IsEnclosing() && sign2<=0.) || |
87 | (Qualified1.IsOutside() && sign1 <= 0. && sign2 >= 0.) || |
88 | (Qualified1.IsEnclosed() && sign1 >= 0. && sign2 >= 0.)) { |
89 | WellDone = Standard_True; |
90 | linsol = gp_Lin2d(Origine,TheDirection); |
91 | pnttg1sol = Origine; |
92 | qualifier1 = Qualified1.Qualifier(); |
93 | pararg1 = Usol; |
94 | par1sol = 0.; |
95 | if (!Paral2) { |
96 | IntAna2d_AnaIntersection Intp(linsol,TheLin); |
97 | if (Intp.IsDone() && !Intp.IsEmpty()) { |
98 | if (Intp.NbPoints()==1) { |
99 | pntint2sol = Intp.Point(1).Value(); |
100 | par2sol = gp_Vec2d(linsol.Direction()). |
101 | Dot(gp_Vec2d(linsol.Location(),pntint2sol)); |
102 | pararg2 = gp_Vec2d(TheLin.Direction()). |
103 | Dot(gp_Vec2d(TheLin.Location(),pntint2sol)); |
104 | } |
105 | } |
106 | } |
107 | } |
108 | } |
109 | } |
110 | |
111 | Standard_Boolean Geom2dGcc_Lin2dTanOblIter:: |
112 | IsDone () const { return WellDone; } |
113 | |
114 | gp_Lin2d Geom2dGcc_Lin2dTanOblIter::ThisSolution () const |
115 | { |
9775fa61 |
116 | if (!WellDone) throw StdFail_NotDone(); |
54e37688 |
117 | |
118 | return linsol; |
119 | } |
120 | |
121 | void Geom2dGcc_Lin2dTanOblIter:: |
122 | WhichQualifier (GccEnt_Position& Qualif1) const |
123 | { |
9775fa61 |
124 | if (!WellDone) { throw StdFail_NotDone(); } |
54e37688 |
125 | else { |
126 | Qualif1 = qualifier1; |
127 | } |
128 | } |
129 | |
130 | Standard_Boolean Geom2dGcc_Lin2dTanOblIter:: |
131 | IsParallel2 () const { return Paral2; } |
132 | |
133 | void Geom2dGcc_Lin2dTanOblIter:: |
134 | Tangency1 (Standard_Real& ParSol , |
135 | Standard_Real& ParArg , |
136 | gp_Pnt2d& PntSol) const { |
9775fa61 |
137 | if (!WellDone) { throw StdFail_NotDone(); } |
54e37688 |
138 | else { |
139 | ParSol = par1sol; |
140 | ParArg = pararg1; |
141 | PntSol = gp_Pnt2d(pnttg1sol); |
142 | } |
143 | } |
144 | |
145 | void Geom2dGcc_Lin2dTanOblIter:: |
146 | Intersection2 (Standard_Real& ParSol , |
147 | Standard_Real& ParArg , |
148 | gp_Pnt2d& PntSol ) const { |
9775fa61 |
149 | if (!WellDone) { throw StdFail_NotDone(); } |
150 | else if (Paral2) { throw Geom2dGcc_IsParallel(); } |
54e37688 |
151 | else { |
152 | PntSol = pntint2sol; |
153 | ParSol = par2sol; |
154 | ParArg = pararg2; |
155 | } |
156 | } |
157 | |