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