Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/ElmerGUI/netgen/libsrc/geom2d/spline2d.cpp
3206 views
1
2
2d Spline curve for Mesh generator
3
4
5
OLD IMPLEMENTATION, NOT USED ANYMORE!
6
7
8
9
#include <mystdlib.h>
10
#include <csg.hpp>
11
#include <linalg.hpp>
12
#include <meshing.hpp>
13
14
namespace netgen
15
{
16
#include "spline2d.hpp"
17
18
19
void CalcPartition (double l, double h, double r1, double r2,
20
double ra, double elto0, ARRAY<double> & points);
21
22
23
24
// calculates length of spline-curve
25
double SplineSegment :: Length () const
26
{
27
Point<2> p, pold;
28
29
int i, n = 100;
30
double dt = 1.0 / n;
31
32
pold = GetPoint (0);
33
34
double l = 0;
35
for (i = 1; i <= n; i++)
36
{
37
p = GetPoint (i * dt);
38
l += Dist (p, pold);
39
pold = p;
40
}
41
return l;
42
}
43
44
45
46
// partitionizes spline curve
47
void SplineSegment :: Partition (double h, double elto0,
48
Mesh & mesh, Point3dTree & searchtree, int segnr) const
49
{
50
int i, j;
51
double l, r1, r2, ra;
52
double lold, dt, frac;
53
int n = 100;
54
Point<2> p, pold, mark, oldmark;
55
ARRAY<double> curvepoints;
56
double edgelength, edgelengthold;
57
l = Length();
58
59
r1 = StartPI().refatpoint;
60
r2 = EndPI().refatpoint;
61
ra = reffak;
62
63
// cout << "Partition, l = " << l << ", h = " << h << endl;
64
CalcPartition (l, h, r1, r2, ra, elto0, curvepoints);
65
// cout << "curvepoints = " << curvepoints << endl;
66
67
dt = 1.0 / n;
68
69
l = 0;
70
j = 1;
71
72
pold = GetPoint (0);
73
lold = 0;
74
oldmark = pold;
75
edgelengthold = 0;
76
ARRAY<int> locsearch;
77
78
for (i = 1; i <= n; i++)
79
{
80
p = GetPoint (i*dt);
81
l = lold + Dist (p, pold);
82
while (j < curvepoints.Size() && (l >= curvepoints[j] || i == n))
83
{
84
frac = (curvepoints[j]-lold) / (l-lold);
85
mark = pold + frac * (p-pold);
86
edgelength = i*dt + (frac-1)*dt;
87
{
88
PointIndex pi1 = -1, pi2 = -1;
89
90
Point3d mark3(mark(0), mark(1), 0);
91
Point3d oldmark3(oldmark(0), oldmark(1), 0);
92
93
Vec<3> v (1e-4*h, 1e-4*h, 1e-4*h);
94
searchtree.GetIntersecting (oldmark3 - v, oldmark3 + v, locsearch);
95
if (locsearch.Size()) pi1 = locsearch[0];
96
97
searchtree.GetIntersecting (mark3 - v, mark3 + v, locsearch);
98
if (locsearch.Size()) pi2 = locsearch[0];
99
/*
100
for (PointIndex pk = PointIndex::BASE;
101
pk < mesh.GetNP()+PointIndex::BASE; pk++)
102
{
103
if (Dist (mesh[pk], oldmark3) < 1e-4 * h) pi1 = pk;
104
if (Dist (mesh[pk], mark3) < 1e-4 * h) pi2 = pk;
105
}
106
*/
107
108
109
// cout << "pi1 = " << pi1 << endl;
110
// cout << "pi2 = " << pi2 << endl;
111
112
if (pi1 == -1)
113
{
114
pi1 = mesh.AddPoint(oldmark3);
115
searchtree.Insert (oldmark3, pi1);
116
}
117
if (pi2 == -1)
118
{
119
pi2 = mesh.AddPoint(mark3);
120
searchtree.Insert (mark3, pi2);
121
}
122
123
// cout << "pi1 = " << pi1 << endl;
124
// cout << "pi2 = " << pi2 << endl;
125
126
Segment seg;
127
seg.edgenr = segnr;
128
seg.si = bc; // segnr;
129
seg.p1 = pi1;
130
seg.p2 = pi2;
131
seg.domin = leftdom;
132
seg.domout = rightdom;
133
seg.epgeominfo[0].edgenr = segnr;
134
seg.epgeominfo[0].dist = edgelengthold;
135
seg.epgeominfo[1].edgenr = segnr;
136
seg.epgeominfo[1].dist = edgelength;
137
seg.singedge_left = hpref_left;
138
seg.singedge_right = hpref_right;
139
mesh.AddSegment (seg);
140
}
141
142
oldmark = mark;
143
edgelengthold = edgelength;
144
j++;
145
}
146
147
pold = p;
148
lold = l;
149
}
150
}
151
152
153
void SplineSegment :: GetPoints (int n, ARRAY<Point<2> > & points)
154
{
155
points.SetSize (n);
156
if (n >= 2)
157
for (int i = 0; i < n; i++)
158
points[i] = GetPoint(double(i) / (n-1));
159
}
160
161
void SplineSegment :: PrintCoeff (ostream & ost) const
162
{
163
Vector u(6);
164
165
GetCoeff(u);
166
167
for ( int i=0; i<6; i++)
168
ost << u[i] << " ";
169
ost << endl;
170
}
171
172
173
174
/*
175
Implementation of line-segment from p1 to p2
176
*/
177
178
179
LineSegment :: LineSegment (const GeomPoint2d & ap1,
180
const GeomPoint2d & ap2)
181
: p1(ap1), p2(ap2)
182
{
183
;
184
}
185
186
187
Point<2> LineSegment :: GetPoint (double t) const
188
{
189
return p1 + t * (p2 - p1);
190
}
191
192
double LineSegment :: Length () const
193
{
194
return Dist (p1, p2);
195
}
196
197
198
void LineSegment :: GetCoeff (Vector & coeffs) const
199
{
200
coeffs.SetSize(6);
201
202
double dx = p2(0) - p1(0);
203
double dy = p2(1) - p1(1);
204
205
coeffs[0] = coeffs[1] = coeffs[2] = 0;
206
coeffs[3] = dy;
207
coeffs[4] = -dx;
208
coeffs[5] = dx * p1(1) - dy * p1(0);
209
}
210
211
212
213
void LineSegment :: LineIntersections (const double a, const double b, const double c,
214
ARRAY < Point<2> > & points, const double eps) const
215
{
216
points.SetSize(0);
217
218
double denom = -a*p2(0)+a*p1(0)-b*p2(1)+b*p1(1);
219
if(fabs(denom) < 1e-20)
220
return;
221
222
double t = (a*p1(0)+b*p1(1)+c)/denom;
223
if((t > -eps) && (t < 1.+eps))
224
points.Append(GetPoint(t));
225
}
226
227
228
SplineSegment3 :: SplineSegment3 (const GeomPoint2d & ap1,
229
const GeomPoint2d & ap2,
230
const GeomPoint2d & ap3)
231
: p1(ap1), p2(ap2), p3(ap3)
232
{
233
;
234
}
235
236
Point<2> SplineSegment3 :: GetPoint (double t) const
237
{
238
double x, y, w;
239
double b1, b2, b3;
240
241
b1 = (1-t)*(1-t);
242
b2 = sqrt(2.0) * t * (1-t);
243
b3 = t * t;
244
245
x = p1(0) * b1 + p2(0) * b2 + p3(0) * b3;
246
y = p1(1) * b1 + p2(1) * b2 + p3(1) * b3;
247
w = b1 + b2 + b3;
248
249
return Point<2> (x/w, y/w);
250
}
251
252
253
void SplineSegment3 :: GetCoeff (Vector & u) const
254
{
255
double t;
256
int i;
257
Point<2> p;
258
DenseMatrix a(6, 6);
259
DenseMatrix ata(6, 6);
260
Vector f(6);
261
262
u.SetSize(6);
263
264
// ata.SetSymmetric(1);
265
266
t = 0;
267
for (i = 1; i <= 5; i++, t += 0.25)
268
{
269
p = GetPoint (t);
270
a.Elem(i, 1) = p(0) * p(0);
271
a.Elem(i, 2) = p(1) * p(1);
272
a.Elem(i, 3) = p(0) * p(1);
273
a.Elem(i, 4) = p(0);
274
a.Elem(i, 5) = p(1);
275
a.Elem(i, 6) = 1;
276
}
277
a.Elem(6, 1) = 1;
278
279
CalcAtA (a, ata);
280
281
u = 0;
282
u.Elem(6) = 1;
283
a.MultTrans (u, f);
284
ata.Solve (f, u);
285
}
286
287
double SplineSegment3 :: MaxCurvature(void) const
288
{
289
Vec<2> v1 = p1-p2;
290
Vec<2> v2 = p3-p2;
291
double l1 = v1.Length();
292
double l2 = v2.Length();
293
294
double cosalpha = v1*v2/(l1*l2);
295
296
297
return sqrt(cosalpha + 1.)/(min2(l1,l2)*(1.-cosalpha));
298
}
299
300
301
void SplineSegment3 :: LineIntersections (const double a, const double b, const double c,
302
ARRAY < Point<2> > & points, const double eps) const
303
{
304
points.SetSize(0);
305
306
double t;
307
308
const double c1 = a*p1(0) - sqrt(2.)*a*p2(0) + a*p3(0)
309
+ b*p1(1) - sqrt(2.)*b*p2(1) + b*p3(1)
310
+ (2.-sqrt(2.))*c;
311
const double c2 = -2.*a*p1(0) + sqrt(2.)*a*p2(0) -2.*b*p1(1) + sqrt(2.)*b*p2(1) + (sqrt(2.)-2.)*c;
312
const double c3 = a*p1(0) + b*p1(1) + c;
313
314
if(fabs(c1) < 1e-20)
315
{
316
if(fabs(c2) < 1e-20)
317
return;
318
319
t = -c3/c2;
320
if((t > -eps) && (t < 1.+eps))
321
points.Append(GetPoint(t));
322
return;
323
}
324
325
const double D = c2*c2-4.*c1*c3;
326
327
if(D < 0)
328
return;
329
330
if(fabs(D/(c1*c1)) < 1e-14)
331
{
332
t = -0.5*c2/c1;
333
if((t > -eps) && (t < 1.+eps))
334
points.Append(GetPoint(t));
335
return;
336
}
337
338
t = (-c2 + sqrt(D))/(2.*c1);
339
if((t > -eps) && (t < 1.+eps))
340
points.Append(GetPoint(t));
341
342
t = (-c2 - sqrt(D))/(2.*c1);
343
if((t > -eps) && (t < 1.+eps))
344
points.Append(GetPoint(t));
345
}
346
347
348
349
//########################################################################
350
// circlesegment
351
352
CircleSegment :: CircleSegment (const GeomPoint2d & ap1,
353
const GeomPoint2d & ap2,
354
const GeomPoint2d & ap3)
355
: p1(ap1), p2(ap2), p3(ap3)
356
{
357
Vec<2> v1,v2;
358
359
v1 = p1 - p2;
360
v2 = p3 - p2;
361
362
Point<2> p1t(p1(0)+v1[1], p1(1)-v1[0]);
363
Point<2> p2t(p3(0)+v2[1], p3(1)-v2[0]);
364
Line2d g1t(p1, p1t), g2t(p3, p2t);
365
366
pm = CrossPoint (g1t,g2t);
367
radius = Dist(pm,StartPI());
368
w1 = Angle(Vec2d (p1 - pm));
369
w3 = Angle(Vec2d (p3 - pm));
370
if ( fabs(w3-w1) > M_PI )
371
{
372
if ( w3>M_PI ) w3 -= 2*M_PI;
373
if ( w1>M_PI ) w1 -= 2*M_PI;
374
}
375
}
376
377
Point<2> CircleSegment :: GetPoint (double t) const
378
{
379
if (t >= 1.0) { return p3; }
380
381
double phi = StartAngle() + t*(EndAngle()-StartAngle());
382
Vec2d tmp(cos(phi),sin(phi));
383
384
return pm + Radius()*tmp;
385
}
386
387
void CircleSegment :: GetCoeff (Vector & coeff) const
388
{
389
coeff[0] = coeff[1] = 1.0;
390
coeff[2] = 0.0;
391
coeff[3] = -2.0 * pm[0];
392
coeff[4] = -2.0 * pm[1];
393
coeff[5] = sqr(pm[0]) + sqr(pm[1]) - sqr(Radius());
394
}
395
396
397
void CircleSegment :: LineIntersections (const double a, const double b, const double c,
398
ARRAY < Point<2> > & points, const double eps) const
399
{
400
points.SetSize(0);
401
402
double px=0,py=0;
403
404
if(fabs(b) > 1e-20)
405
py = -c/b;
406
else
407
px = -c/a;
408
409
const double c1 = a*a + b*b;
410
const double c2 = 2. * ( a*(py-pm(1)) - b*(px-pm(0)));
411
const double c3 = pow(px-pm(0),2) + pow(py-pm(1),2) - pow(Radius(),2);
412
413
const double D = c2*c2 - 4*c1*c3;
414
415
if(D < 0)
416
return;
417
418
ARRAY<double> t;
419
420
if(fabs(D) < 1e-20)
421
t.Append(-0.5*c2/c1);
422
else
423
{
424
t.Append((-c2+sqrt(D))/(2.*c1));
425
t.Append((-c2-sqrt(D))/(2.*c1));
426
}
427
428
for(int i=0; i<t.Size(); i++)
429
{
430
Point<2> p (px-t[i]*b,py+t[i]*a);
431
432
double angle = atan2(p(1),p(0))+M_PI;
433
434
if(angle > StartAngle()-eps && angle < EndAngle()+eps)
435
points.Append(p);
436
}
437
}
438
439
440
441
DiscretePointsSegment :: DiscretePointsSegment (const ARRAY<Point<2> > & apts)
442
: pts (apts),
443
p1 (apts[0](0), apts[0](1), 1),
444
p2 (apts.Last()(0), apts.Last()(1), 1)
445
446
{ ; }
447
448
449
DiscretePointsSegment :: ~DiscretePointsSegment ()
450
{ ; }
451
452
Point<2> DiscretePointsSegment :: GetPoint (double t) const
453
{
454
double t1 = t * (pts.Size()-1);
455
int segnr = int(t1);
456
if (segnr < 0) segnr = 0;
457
if (segnr >= pts.Size()) segnr = pts.Size()-1;
458
459
double rest = t1 - segnr;
460
461
return Point<2> ((1-rest)*pts[segnr](0) + rest*pts[segnr+1](0),
462
(1-rest)*pts[segnr](1) + rest*pts[segnr+1](1));
463
}
464
465
466
467
468
469
470
//########################################################################
471
472
473
474
475
void CalcPartition (double l, double h, double r1, double r2,
476
double ra, double elto0, ARRAY<double> & points)
477
{
478
int i, j, n, nel;
479
double sum, t, dt, fun, fperel, oldf, f;
480
481
n = 1000;
482
483
points.SetSize (0);
484
485
sum = 0;
486
dt = l / n;
487
t = 0.5 * dt;
488
for (i = 1; i <= n; i++)
489
{
490
fun = min3 (h/ra, t/elto0 + h/r1, (l-t)/elto0 + h/r2);
491
sum += dt / fun;
492
t += dt;
493
}
494
495
nel = int (sum+1);
496
fperel = sum / nel;
497
498
points.Append (0);
499
500
i = 1;
501
oldf = 0;
502
t = 0.5 * dt;
503
for (j = 1; j <= n && i < nel; j++)
504
{
505
fun = min3 (h/ra, t/elto0 + h/r1, (l-t)/elto0 + h/r2);
506
507
f = oldf + dt / fun;
508
509
while (f > i * fperel && i < nel)
510
{
511
points.Append ( (l/n) * (j-1 + (i * fperel - oldf) / (f - oldf)) );
512
i++;
513
}
514
oldf = f;
515
t += dt;
516
}
517
points.Append (l);
518
}
519
520
521
}
522
523