Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/ElmerGUI/netgen/libsrc/gprim/geom2d.cpp
3206 views
1
#include <mystdlib.h>
2
3
#include <myadt.hpp>
4
#include <gprim.hpp>
5
6
#ifndef M_PI
7
#define M_PI 3.14159265358979323846
8
#endif
9
10
namespace netgen
11
{
12
13
ostream & operator<<(ostream & s, const Point2d & p)
14
{
15
return s << "(" << p.px << ", " << p.py << ")";
16
}
17
18
ostream & operator<<(ostream & s, const Vec2d & v)
19
{
20
return s << "(" << v.vx << ", " << v.vy << ")";
21
}
22
23
#ifdef none
24
ostream & operator<<(ostream & s, const Line2d & l)
25
{
26
return s << l.p1 << "-" << l.p2;
27
}
28
29
ostream & operator<<(ostream & s, const TRIANGLE2D & t)
30
{
31
return s << t.p1 << "-" << t.p2 << "-" << t.p3;
32
}
33
#endif
34
35
36
double Fastatan2 (double x, double y)
37
{
38
if (y > 0)
39
{
40
if (x > 0)
41
return y / (x+y);
42
else
43
return 1 - x / (y-x);
44
}
45
else if (y < 0)
46
{
47
if (x < 0)
48
return 2 + y / (x+y);
49
else
50
return 3 - x / (y-x);
51
}
52
else
53
{
54
if (x >= 0)
55
return 0;
56
else
57
return 2;
58
}
59
}
60
61
62
double Angle (const Vec2d & v)
63
{
64
if (v.X() == 0 && v.Y() == 0)
65
return 0;
66
67
double ang = atan2 (v.Y(), v.X());
68
if (ang < 0) ang+= 2 * M_PI;
69
return ang;
70
}
71
72
double FastAngle (const Vec2d & v)
73
{
74
return Fastatan2 (v.X(), v.Y());
75
}
76
77
double Angle (const Vec2d & v1, const Vec2d & v2)
78
{
79
double ang = Angle(v2) - Angle(v1);
80
if (ang < 0) ang += 2 * M_PI;
81
return ang;
82
}
83
84
double FastAngle (const Vec2d & v1, const Vec2d & v2)
85
{
86
double ang = FastAngle(v2) - FastAngle(v1);
87
if (ang < 0) ang += 4;
88
return ang;
89
}
90
91
/*
92
int CW (const Point2d & p1,const Point2d & p2,const Point2d & p3)
93
{
94
return Cross (p2 - p1, p3 - p2) < 0;
95
}
96
97
int CCW (const Point2d & p1,const Point2d & p2,const Point2d & p3)
98
{
99
return Cross (p2 - p1, p3 - p2) > 0;
100
}
101
*/
102
103
double Dist2(const Line2d & g, const Line2d & h )
104
{
105
double dd = 0.0, d1,d2,d3,d4;
106
Point2d cp = CrossPoint(g,h);
107
108
if ( Parallel(g,h) || !IsOnLine(g,cp) || !IsOnLine(h,cp) )
109
{
110
d1 = Dist2(g.P1(),h.P1());
111
d2 = Dist2(g.P1(),h.P2());
112
d3 = Dist2(g.P2(),h.P1());
113
d4 = Dist2(g.P2(),h.P2());
114
if (d1<d2) d2 = d1;
115
if (d3<d4) d4 = d3;
116
dd = ( d2 < d4 ) ? d2 : d4;
117
}
118
return dd;
119
}
120
121
122
Point2d CrossPoint (const Line2d & l1, const Line2d & l2)
123
{
124
double den = Cross (l1.Delta(), l2.Delta());
125
double num = Cross ( (l2.P1() - l1.P1()), l2.Delta());
126
127
if (den == 0)
128
return l1.P1();
129
else
130
return l1.P1() + (num/den) * l1.Delta();
131
}
132
133
134
int CrossPointBarycentric (const Line2d & l1, const Line2d & l2,
135
double & lam1, double & lam2)
136
{
137
// p = l1.1 + lam1 (l1.2-l1.1) = l2.1 + lam2 (l2.2-l2.1)
138
double a11 = l1.p2.X() - l1.p1.X();
139
double a21 = l1.p2.Y() - l1.p1.Y();
140
double a12 = -(l2.p2.X() - l2.p1.X());
141
double a22 = -(l2.p2.Y() - l2.p1.Y());
142
143
double b1 = l2.p1.X() - l1.p1.X();
144
double b2 = l2.p1.Y() - l1.p1.Y();
145
146
double det = a11*a22 - a12 * a21;
147
if (det == 0)
148
return 1;
149
150
lam1 = (a22 * b1 - a12 * b2) / det;
151
lam2 = (a11 * b2 - a21 * b1) / det;
152
return 0;
153
}
154
155
156
157
158
int Parallel (const Line2d & l1, const Line2d & l2, double peps)
159
{
160
double p = fabs (Cross (l1.Delta(), l2.Delta()));
161
// (*mycout) << endl << p << " " << l1.Length() << " " << l2.Length() << endl;
162
return p <= peps * l1.Length() * l2.Length();
163
}
164
165
int IsOnLine (const Line2d & l, const Point2d & p, double heps)
166
{
167
double c1 = (p - l.P1()) * l.Delta();
168
double c2 = (p - l.P2()) * l.Delta();
169
double d = fabs (Cross ( (p - l.P1()), l.Delta()));
170
double len2 = l.Length2();
171
172
return c1 >= -heps * len2 && c2 <= heps * len2 && d <= heps * len2;
173
}
174
175
#ifdef none
176
int IsOnLine (const PLine2d & l, const Point2d & p, double heps)
177
{
178
double c1 = (p - l.P1()) * l.Delta();
179
double c2 = (p - l.P2()) * l.Delta();
180
double d = fabs (Cross ( (p - l.P1()), l.Delta()));
181
double len2 = l.Length2();
182
183
return c1 >= -heps * len2 && c2 <= heps * len2 && d <= heps * len2;
184
}
185
186
int IsOnLongLine (const Line2d & l, const Point2d & p)
187
{
188
double d = fabs (Cross ( (p - l.P1()), l.Delta()));
189
return d <= EPSGEOM * l.Length();
190
}
191
192
int Hit (const Line2d & l1, const Line2d & l2, double heps)
193
{
194
double den = Cross ( (l1.P2() - l1.P1()), (l2.P1() - l2.P2()));
195
double num1 = Cross ( (l2.P1() - l1.P1()), (l2.P1() - l2.P2()));
196
double num2 = Cross ( (l1.P2() - l1.P1()), (l2.P1() - l1.P1()));
197
num1 *= sgn (den);
198
num2 *= sgn (den);
199
den = fabs (den);
200
201
int ch = (-den * heps <= num1 && num1 <= den * (1 + heps) &&
202
-den * heps <= num2 && num2 <= den * (1 + heps));
203
return ch;
204
}
205
206
207
void Line2d :: GetNormal (Line2d & n) const
208
{
209
double ax = P2().X()-P1().X(),
210
ay = P2().Y()-P1().Y();
211
Point2d mid(P1().X()+.5*ax, P1().Y()+.5*ay);
212
213
n=Line2d(mid,Point2d(mid.X()+ay,mid.Y()-ax)) ;
214
}
215
216
Vec2d Line2d :: NormalDelta () const
217
{
218
Line2d tmp;
219
GetNormal(tmp);
220
return tmp.Delta();
221
}
222
223
int TRIANGLE2D :: IsOn (const Point2d & p) const
224
{
225
return IsOnLine (Line2d (p1, p2), p) ||
226
IsOnLine (Line2d (p1, p3), p) ||
227
IsOnLine (Line2d (p2, p3), p);
228
}
229
230
231
int TRIANGLE2D :: IsIn (const Point2d & p) const
232
{
233
return ::CW(p, p1, p2) == ::CW(p, p2, p3) &&
234
::CW(p, p1, p2) == ::CW(p, p3, p1);
235
}
236
237
238
239
int PTRIANGLE2D :: IsOn (const Point2d & p) const
240
{
241
return IsOnLine (Line2d (*p1, *p2), p) ||
242
IsOnLine (Line2d (*p1, *p3), p) ||
243
IsOnLine (Line2d (*p2, *p3), p);
244
}
245
246
247
int PTRIANGLE2D :: IsIn (const Point2d & p) const
248
{
249
return ::CW(p, *p1, *p2) == ::CW(p, *p2, *p3) &&
250
::CW(p, *p1, *p2) == ::CW(p, *p3, *p1);
251
}
252
253
#endif
254
255
256
257
258
259
260
Polygon2d :: Polygon2d ()
261
{
262
;
263
}
264
265
Polygon2d :: ~Polygon2d ()
266
{
267
;
268
}
269
270
void Polygon2d :: AddPoint (const Point2d & p)
271
{
272
points.Append(p);
273
}
274
275
276
double Polygon2d :: HArea () const
277
{
278
int i;
279
double ar = 0;
280
for (i = 1; i <= points.Size(); i++)
281
{
282
const Point2d & p1 = points.Get(i);
283
const Point2d & p2 = points.Get(i%points.Size()+1);
284
ar +=
285
(p2.X()-p1.X()) * p1.Y() -
286
(p2.Y()-p1.Y()) * p1.X();
287
}
288
return ar/2;
289
/*
290
CURSOR c;
291
double ar = 0;
292
Point2d * p1, * p2, p0 = Point2d(0, 0);
293
Vec2d v1, v2 = Vec2d(1, 0);
294
295
p2 = points[points.Last()];
296
for (c = points.First(); c != points.Head(); c++)
297
{
298
p1 = p2;
299
p2 = points[c];
300
ar += Cross ( (*p2-*p1), (*p1 - p0));
301
}
302
return ar / 2;
303
*/
304
}
305
306
307
int Polygon2d :: IsOn (const Point2d & p) const
308
{
309
int i;
310
for (i = 1; i <= points.Size(); i++)
311
{
312
const Point2d & p1 = points.Get(i);
313
const Point2d & p2 = points.Get(i%points.Size()+1);
314
if (IsOnLine (Line2d(p1, p2), p)) return 1;
315
}
316
return 0;
317
/*
318
CURSOR c;
319
Point2d * p1, * p2;
320
321
p2 = points[points.Last()];
322
for (c = points.First(); c != points.Head(); c++)
323
{
324
p1 = p2;
325
p2 = points[c];
326
if (IsOnLine (Line2d(*p1, *p2), p)) return 1;
327
}
328
return 0;
329
*/
330
}
331
332
333
int Polygon2d :: IsIn (const Point2d & p) const
334
{
335
int i;
336
double sum = 0, ang;
337
for (i = 1; i <= points.Size(); i++)
338
{
339
const Point2d & p1 = points.Get(i);
340
const Point2d & p2 = points.Get(i%points.Size()+1);
341
ang = Angle ( (p1 - p), (p2 - p) );
342
if (ang > M_PI) ang -= 2 * M_PI;
343
sum += ang;
344
}
345
return fabs(sum) > M_PI;
346
/*
347
CURSOR c;
348
Point2d * p1, * p2;
349
double sum = 0, ang;
350
351
p2 = points[points.Last()];
352
for (c = points.First(); c != points.Head(); c++)
353
{
354
p1 = p2;
355
p2 = points[c];
356
ang = Angle ( (*p1 - p), (*p2 - p) );
357
if (ang > M_PI) ang -= 2 * M_PI;
358
sum += ang;
359
}
360
361
return fabs(sum) > M_PI;
362
*/
363
}
364
365
int Polygon2d :: IsConvex () const
366
{
367
/*
368
Point2d *p, *pold, *pnew;
369
char cw;
370
CURSOR c;
371
372
if (points.Length() < 3) return 0;
373
374
c = points.Last();
375
p = points[c];
376
c--;
377
pold = points[c];
378
pnew = points[points.First()];
379
cw = ::CW (*pold, *p, *pnew);
380
381
for (c = points.First(); c != points.Head(); c++)
382
{
383
pnew = points[c];
384
if (cw != ::CW (*pold, *p, *pnew))
385
return 0;
386
pold = p;
387
p = pnew;
388
}
389
*/
390
return 0;
391
}
392
393
394
int Polygon2d :: IsStarPoint (const Point2d & p) const
395
{
396
/*
397
Point2d *pnew, *pold;
398
char cw;
399
CURSOR c;
400
401
if (points.Length() < 3) return 0;
402
403
pold = points[points.Last()];
404
pnew = points[points.First()];
405
406
cw = ::CW (p, *pold, *pnew);
407
408
for (c = points.First(); c != points.Head(); c++)
409
{
410
pnew = points[c];
411
if (cw != ::CW (p, *pold, *pnew))
412
return 0;
413
pold = pnew;
414
}
415
return 1;
416
*/
417
return 0;
418
}
419
420
421
Point2d Polygon2d :: Center () const
422
{
423
/*
424
double ai, a = 0, x = 0, y = 0;
425
Point2d * p, *p2;
426
Point2d p0 = Point2d(0, 0);
427
CURSOR c;
428
429
p2 = points[points.Last()];
430
431
for (c = points.First(); c != points.Head(); c++)
432
{
433
p = points[c];
434
ai = Cross (*p2 - p0, *p - p0);
435
x += ai / 3 * (p2->X() + p->X());
436
y += ai / 3 * (p2->Y() + p->Y());
437
a+= ai;
438
p2 = p;
439
}
440
if (a != 0)
441
return Point2d (x / a, y / a);
442
else
443
return Point2d (0, 0);
444
*/
445
return Point2d (0, 0);
446
}
447
448
449
450
Point2d Polygon2d :: EqualAreaPoint () const
451
{
452
/*
453
double a11 = 0, a12 = 0, a21= 0, a22 = 0;
454
double b1 = 0, b2 = 0, dx, dy;
455
double det;
456
Point2d * p, *p2;
457
CURSOR c;
458
459
p = points[points.Last()];
460
461
for (c = points.First(); c != points.Head(); c++)
462
{
463
p2 = p;
464
p = points[c];
465
466
dx = p->X() - p2->X();
467
dy = p->Y() - p2->Y();
468
469
a11 += sqr (dy);
470
a12 -= dx * dy;
471
a21 -= dx * dy;
472
a22 += sqr (dx);
473
b1 -= dy * (p->X() * p2->Y() - p2->X() * p->Y());
474
b2 -= dx * (p->Y() * p2->X() - p2->Y() * p->X());
475
}
476
477
det = a11 * a22 - a21 * a12;
478
479
if (det != 0)
480
return Point2d ( (b1 * a22 - b2 * a12) / det,
481
(a11 * b2 - a21 * b1) / det);
482
else
483
return Point2d (0, 0);
484
*/
485
return Point2d (0, 0);
486
}
487
488
489
}
490
491