0022627: Change OCCT memory management defaults
[occt.git] / src / IntPatch / IntPatch_PolyLine.cxx
CommitLineData
7fd59977 1// File: IntPatch_PolyLine.cxx
2// Created: Fri Jan 29 17:14:59 1993
3// Author: Isabelle GRIGNON
4// Copyright: Matra Datavision 1993
5
6//-- lbr le 12 juin : Ajout des fleches sur les Lines
7//-- msv 13.03.2002 : compute deflection for WLine; Error() returns deflection
8
9#include <IntPatch_PolyLine.ixx>
10
11#include <Precision.hxx>
12
13#define INITDEFLE Precision::PConfusion()*100.
14
15//=======================================================================
16//function : IntPatch_PolyLine
17//purpose :
18//=======================================================================
19
20IntPatch_PolyLine::IntPatch_PolyLine ()
9530af27 21 : IntPatch_Polygo(INITDEFLE)
7fd59977 22{}
23
24//=======================================================================
25//function : IntPatch_PolyLine
26//purpose :
27//=======================================================================
28
29IntPatch_PolyLine::IntPatch_PolyLine (const Standard_Real InitDefle)
9530af27 30 : IntPatch_Polygo(InitDefle)
7fd59977 31{}
32
33//=======================================================================
34//function : SetWLine
35//purpose :
36//=======================================================================
37
38void IntPatch_PolyLine::SetWLine(const Standard_Boolean OnFirst, const Handle(IntPatch_WLine)& Line)
39{
40 typ = IntPatch_Walking;
41 wpoly = Line;
42 onfirst = OnFirst;
43 Prepare();
44}
45
46//=======================================================================
47//function : SetRLine
48//purpose :
49//=======================================================================
50
51void IntPatch_PolyLine::SetRLine(const Standard_Boolean OnFirst, const Handle(IntPatch_RLine)& Line)
52{
53 typ = IntPatch_Restriction;
54 rpoly = Line;
55 onfirst = OnFirst;
56 Prepare();
57}
58
59//=======================================================================
60//function : Prepare
61//purpose :
62//=======================================================================
63
64void IntPatch_PolyLine::Prepare()
65{
66 Standard_Integer i;
9530af27 67 myBox.SetVoid();
7fd59977 68 Standard_Integer n=NbPoints();
9530af27 69 Standard_Real eps = myError;
7fd59977 70
71 gp_Pnt2d P1, P2;
72 if (n >= 3) {
73 P1 = Point(1); P2 = Point(2);
74 }
75 for (i=1; i<=n ;i++) {
76 const gp_Pnt2d& P3 = Point(i);
77 if (i >= 3) {
78 gp_XY V13 = P3.XY() - P1.XY();
79 gp_XY V12 = P2.XY() - P1.XY();
80 Standard_Real d13 = V13.Modulus(), d;
81 if (d13 > eps)
82 d = V13.CrossMagnitude(V12) / d13;
83 else
84 d = eps;
9530af27 85 if (d > myError) {
7fd59977 86 // try to compute deflection more precisely using parabola interpolation
87 gp_XY V23 = P3.XY() - P2.XY();
88 Standard_Real d12 = V12.Modulus(), d23 = V23.Modulus();
89 // compute parameter of P2 (assume parameters of P1,P3 are 0,1)
90 Standard_Real tm = d12 / (d12+d23);
91 if (tm > 0.1 && tm < 0.9) {
92 tm -= (tm-0.5) * 0.6;
93 Standard_Real tm1mtm = tm*(1-tm);
94 // coefficients of parabola
95 Standard_Real Ax = (tm*V13.X() - V12.X()) / tm1mtm;
96 Standard_Real Bx = (V12.X() - tm*tm*V13.X()) / tm1mtm;
97 Standard_Real Cx = P1.X();
98 Standard_Real Ay = (tm*V13.Y() - V12.Y()) / tm1mtm;
99 Standard_Real By = (V12.Y() - tm*tm*V13.Y()) / tm1mtm;
100 Standard_Real Cy = P1.Y();
101 // equations of lines P1-P2 and P2-P3
102 Standard_Real A1 = V12.Y() / d12;
103 Standard_Real B1 = -V12.X() / d12;
104 Standard_Real C1 = (P2.X()*P1.Y() - P1.X()*P2.Y()) / d12;
105 Standard_Real A2 = V23.Y() / d23;
106 Standard_Real B2 = -V23.X() / d23;
107 Standard_Real C2 = (P3.X()*P2.Y() - P2.X()*P3.Y()) / d23;
108 // points on parabola with max deflection
109 Standard_Real t1 = -0.5 * (A1*Bx + B1*By) / (A1*Ax + B1*Ay);
110 Standard_Real t2 = -0.5 * (A2*Bx + B2*By) / (A2*Ax + B2*Ay);
111 Standard_Real xt1 = Ax*t1*t1 + Bx*t1 + Cx;
112 Standard_Real yt1 = Ay*t1*t1 + By*t1 + Cy;
113 Standard_Real xt2 = Ax*t2*t2 + Bx*t2 + Cx;
114 Standard_Real yt2 = Ay*t2*t2 + By*t2 + Cy;
115 // max deflection on segments P1-P2 and P2-P3
116 Standard_Real d1 = Abs (A1*xt1 + B1*yt1 + C1);
117 Standard_Real d2 = Abs (A2*xt2 + B2*yt2 + C2);
118 if (d2 > d1) d1 = d2;
119 // select min deflection from linear and parabolic ones
120 if (d1 < d) d = d1;
121 }
9530af27 122 if (d > myError) myError=d;
7fd59977 123 }
124 P1 = P2; P2 = P3;
125 }
9530af27 126 myBox.Add(P3);
7fd59977 127 }
9530af27 128 myBox.Enlarge(myError);
7fd59977 129}
130
131//=======================================================================
132//function : ResetError
133//purpose :
134//=======================================================================
135
136void IntPatch_PolyLine::ResetError()
137{
9530af27 138 myError = INITDEFLE;
7fd59977 139}
140
141//=======================================================================
142//function : NbPoints
143//purpose :
144//=======================================================================
145
146Standard_Integer IntPatch_PolyLine::NbPoints() const
147{
148 return (typ == IntPatch_Walking ? wpoly->NbPnts() : rpoly->NbPnts());
149}
150
151//=======================================================================
152//function : Point
153//purpose :
154//=======================================================================
155
156gp_Pnt2d IntPatch_PolyLine::Point(const Standard_Integer Index ) const
157{
158 Standard_Real X,Y,X1,Y1,DX,DY;
159 DX=DY=0;
160 if (onfirst) {
161 if (typ == IntPatch_Walking) {
162 wpoly->Point(Index).ParametersOnS1(X,Y);
163 if(Index==1) {
164 wpoly->Point(2).ParametersOnS1(X1,Y1);
165 DX=0.0000001*(X-X1);
166 DY=0.0000001*(Y-Y1);
167 }
168 else if(Index==wpoly->NbPnts()) {
169 wpoly->Point(Index-1).ParametersOnS1(X1,Y1);
170 DX=0.0000001*(X-X1);
171 DY=0.0000001*(Y-Y1);
172 }
173 }
174 else {
175 rpoly->Point(Index).ParametersOnS1(X,Y);
176 }
177 }
178 else {
179 if (typ == IntPatch_Walking) {
180 wpoly->Point(Index).ParametersOnS2(X,Y);
181 if(Index==1) {
182 wpoly->Point(2).ParametersOnS2(X1,Y1);
183 DX=0.0000001*(X-X1);
184 DY=0.0000001*(Y-Y1);
185 }
186 else if(Index==wpoly->NbPnts()) {
187 wpoly->Point(Index-1).ParametersOnS2(X1,Y1);
188 DX=0.0000001*(X-X1);
189 DY=0.0000001*(Y-Y1);
190 }
191 }
192 else {
193 rpoly->Point(Index).ParametersOnS2(X,Y);
194 }
195 }
196
197 return(gp_Pnt2d(X+DX,Y+DY));
198}