Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/ElmerGUI/netgen/libsrc/csg/bspline2d.cpp
3206 views
1
#include <mystdlib.h>
2
3
#include <csg.hpp>
4
5
namespace netgen
6
{
7
8
BSplineCurve2d :: BSplineCurve2d ()
9
{
10
redlevel = 0;
11
}
12
13
14
void BSplineCurve2d :: AddPoint (const Point<2> & apoint)
15
{
16
points.Append (apoint);
17
intervallused.Append (0);
18
}
19
20
bool BSplineCurve2d :: Inside (const Point<2> & p, double & dist) const
21
{
22
Point<2> hp = p;
23
double t = ProjectParam (p);
24
hp = Eval(t);
25
Vec<2> v = EvalPrime (t);
26
27
Vec<2> n (v(0), -v(1));
28
29
cout << "p = " << p << ", hp = " << hp << endl;
30
dist = Dist (p, hp);
31
double scal = (hp-p) * n;
32
cout << "scal = " << scal << endl;
33
34
return scal >= 0;
35
}
36
37
double BSplineCurve2d :: ProjectParam (const Point<2> & p) const
38
{
39
double t, dt, mindist, mint = 0.0;
40
int n1;
41
42
mindist = 1e10;
43
dt = 0.2;
44
for (n1 = 1; n1 <= points.Size(); n1++)
45
if (intervallused.Get(n1) == 0)
46
for (t = n1; t <= n1+1; t += dt)
47
if (Dist (Eval(t), p) < mindist)
48
{
49
mint = t;
50
mindist = Dist (Eval(t), p);
51
}
52
53
if (mindist > 1e9)
54
{
55
for (t = 0; t <= points.Size(); t += dt)
56
if (Dist (Eval(t), p) < mindist)
57
{
58
mint = t;
59
mindist = Dist (Eval(t), p);
60
}
61
}
62
63
while (Dist (Eval (mint-dt), p) < mindist)
64
{
65
mindist = Dist (Eval (mint-dt), p);
66
mint -= dt;
67
}
68
while (Dist (Eval (mint+dt), p) < mindist)
69
{
70
mindist = Dist (Eval (mint+dt), p);
71
mint += dt;
72
}
73
74
75
return NumericalProjectParam (p, mint-dt, mint+dt);
76
}
77
78
79
// t \in (n1, n2)
80
81
Point<2> BSplineCurve2d :: Eval (double t) const
82
{
83
int n, n1, n2, n3, n4;
84
double loct, b1, b2, b3, b4;
85
Point<2> hp;
86
87
static int cnt = 0;
88
cnt++;
89
if (cnt % 100000 == 0) (*mycout) << "cnt = " << cnt << endl;
90
91
n = int(t);
92
loct = t - n;
93
94
b1 = 0.25 * (1 - loct) * (1 - loct);
95
b4 = 0.25 * loct * loct;
96
b2 = 0.5 - b4;
97
b3 = 0.5 - b1;
98
99
n1 = (n + 10 * points.Size() -1) % points.Size() + 1;
100
n2 = n1+1;
101
if (n2 > points.Size()) n2 = 1;
102
n3 = n2+1;
103
if (n3 > points.Size()) n3 = 1;
104
n4 = n3+1;
105
if (n4 > points.Size()) n4 = 1;
106
107
// (*mycout) << "t = " << t << " n = " << n << " loct = " << loct
108
// << " n1 = " << n1 << endl;
109
110
111
hp(0) = b1 * points.Get(n1)(0) + b2 * points.Get(n2)(0) +
112
b3 * points.Get(n3)(0) + b4 * points.Get(n4)(0);
113
hp(1) = b1 * points.Get(n1)(1) + b2 * points.Get(n2)(1) +
114
b3 * points.Get(n3)(1) + b4 * points.Get(n4)(1);
115
return hp;
116
}
117
118
Vec<2> BSplineCurve2d :: EvalPrime (double t) const
119
{
120
int n, n1, n2, n3, n4;
121
double loct, db1, db2, db3, db4;
122
Vec<2> hv;
123
124
n = int(t);
125
loct = t - n;
126
127
db1 = 0.5 * (loct - 1);
128
db4 = 0.5 * loct;
129
db2 = -db4;
130
db3 = -db1;
131
132
n1 = (n + 10 * points.Size() -1) % points.Size() + 1;
133
n2 = n1+1;
134
if (n2 > points.Size()) n2 = 1;
135
n3 = n2+1;
136
if (n3 > points.Size()) n3 = 1;
137
n4 = n3+1;
138
if (n4 > points.Size()) n4 = 1;
139
140
hv(0) = db1 * points.Get(n1)(0) + db2 * points.Get(n2)(0) +
141
db3 * points.Get(n3)(0) + db4 * points.Get(n4)(0);
142
hv(1) = db1 * points.Get(n1)(1) + db2 * points.Get(n2)(1) +
143
db3 * points.Get(n3)(1) + db4 * points.Get(n4)(1);
144
return hv;
145
}
146
147
Vec<2> BSplineCurve2d :: EvalPrimePrime (double t) const
148
{
149
int n, n1, n2, n3, n4;
150
double ddb1, ddb2, ddb3, ddb4;
151
Vec<2> hv;
152
153
n = int(t);
154
// double loct = t - n;
155
156
ddb1 = 0.5;
157
ddb4 = 0.5;
158
ddb2 = -0.5;
159
ddb3 = -0.5;
160
161
n1 = (n + 10 * points.Size() -1) % points.Size() + 1;
162
n2 = n1+1;
163
if (n2 > points.Size()) n2 = 1;
164
n3 = n2+1;
165
if (n3 > points.Size()) n3 = 1;
166
n4 = n3+1;
167
if (n4 > points.Size()) n4 = 1;
168
169
hv(0) = ddb1 * points.Get(n1)(0) + ddb2 * points.Get(n2)(0) +
170
ddb3 * points.Get(n3)(0) + ddb4 * points.Get(n4)(0);
171
hv(1) = ddb1 * points.Get(n1)(1) + ddb2 * points.Get(n2)(1) +
172
ddb3 * points.Get(n3)(1) + ddb4 * points.Get(n4)(1);
173
return hv;
174
}
175
176
177
int BSplineCurve2d :: SectionUsed (double t) const
178
{
179
int n1 = int(t);
180
n1 = (n1 + 10 * points.Size() - 1) % points.Size() + 1;
181
return (intervallused.Get(n1) == 0);
182
}
183
184
void BSplineCurve2d :: Reduce (const Point<2> & p, double rad)
185
{
186
int n1, n;
187
int j;
188
double minx, miny, maxx, maxy;
189
190
// (*testout) << "Reduce: " << p << "," << rad << endl;
191
192
redlevel++;
193
194
for (n1 = 1; n1 <= points.Size(); n1++)
195
{
196
if (intervallused.Get(n1) != 0) continue;
197
198
minx = maxx = points.Get(n1)(0);
199
miny = maxy = points.Get(n1)(1);
200
201
n = n1;
202
for (j = 1; j <= 3; j++)
203
{
204
n++;
205
if (n > points.Size()) n = 1;
206
if (points.Get(n)(0) < minx) minx = points.Get(n)(0);
207
if (points.Get(n)(1) < miny) miny = points.Get(n)(1);
208
if (points.Get(n)(0) > maxx) maxx = points.Get(n)(0);
209
if (points.Get(n)(1) > maxy) maxy = points.Get(n)(1);
210
}
211
212
if (minx > p(0) + rad || maxx < p(0) - rad ||
213
miny > p(1) + rad || maxy < p(1) - rad)
214
{
215
intervallused.Elem(n1) = redlevel;
216
// (*testout) << 0;
217
}
218
else
219
{
220
// (*testout) << 1;
221
intervallused.Elem(n1) = 0;
222
}
223
}
224
// (*testout) << endl;
225
}
226
227
void BSplineCurve2d :: UnReduce ()
228
{
229
int i;
230
for (i = 1; i <= intervallused.Size(); i++)
231
if (intervallused.Get(i) == redlevel)
232
intervallused.Set (i, 0);
233
redlevel--;
234
}
235
236
void BSplineCurve2d :: Print (ostream & ost) const
237
{
238
ost << "SplineCurve: " << points.Size() << " points." << endl;
239
for (int i = 1; i <= points.Size(); i++)
240
ost << "P" << i << " = " << points.Get(i) << endl;
241
}
242
}
243
244