Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/meshgen2d/src/VSVertex.cpp
3196 views
1
#include "VSVertex.h"
2
#include <iostream>
3
#include <math.h>
4
#include "coreGeometry.h"
5
#include <algorithm>
6
7
#ifdef _NO_STD_MINMAX
8
#include "minmaxpatch.h"
9
#endif
10
11
//#define ORIGINAL
12
13
#if defined(ORIGINAL)
14
15
int VSVertex::
16
computeNewCoordinates( BGMesh& bg, double& nx, double& ny )
17
{
18
double rho;
19
double mx,my;
20
double P;
21
double Q;
22
double ex,ey;
23
double len;
24
double dist;
25
double rhohat;
26
int i,pick;
27
Node *a,*b;
28
bool touched = false;
29
30
len = 2 * radius;
31
pick = 0;
32
33
for(i = 0; i < 3; ++i)
34
{
35
VSVertex *vtx = static_cast<VSVertex *>( vertices[i] );
36
if(vtx->isExternal() || vtx->isAccepted())
37
{
38
dist = distance(nodes[i]->x, nodes[i]->y,
39
nodes[(i + 1) % 3]->x,
40
nodes[(i + 1) % 3]->y);
41
if(dist < len)
42
{
43
len = dist;
44
pick = i;
45
touched = true;
46
}
47
}
48
}
49
50
if(!touched)
51
{
52
makeWaiting();
53
return 0;
54
}
55
a = nodes[pick];
56
b = nodes[(pick + 1)%3];
57
58
dist = distance(vx,vy,vertices[pick]->vx,vertices[pick]->vy);
59
ex = (vx - vertices[pick]->vx) / dist;
60
ey = (vy - vertices[pick]->vy) / dist;
61
62
mx = (a->x + b->x) / 2.0;
63
my = (a->y + b->y) / 2.0;
64
65
rho = bg.interpolate( mx, my );
66
rho /= sqrt( 3.0 );
67
68
Q = distance(vx,vy,mx,my);
69
P = len / 2.0;
70
rhohat = std::min(std::max(rho,P),((P*P + Q*Q) / (2.0 * Q)));
71
double diff = rhohat*rhohat - P*P;
72
if(diff < 0) dist = rhohat;
73
else dist = rhohat + sqrt(diff);
74
75
nx = mx + dist * ex;
76
ny = my + dist * ey;
77
return 1;
78
}
79
#else
80
81
const double htor = 1.0 / sqrt( 3.0 );
82
const double rtoh = 0.5 * sqrt( 3.0 );
83
84
#if 1
85
int VSVertex::
86
computeNewCoordinates( BGMesh& bg, double& lx, double& ly )
87
{
88
double h = 0;
89
double mx,my;
90
double len;
91
double dist;
92
double nx, ny;
93
int i,pick;
94
Node *a,*b,*c;
95
bool touched = false;
96
97
nx = 0; ny = 0;
98
len = 2 * radius;
99
pick = 0;
100
101
for(i = 0; i < 3; ++i)
102
{
103
VSVertex *vtx = static_cast<VSVertex *>( vertices[i] );
104
if(vtx->isExternal() || vtx->isAccepted())
105
{
106
dist = distance(nodes[i]->x, nodes[i]->y,
107
nodes[(i + 1) % 3]->x,
108
nodes[(i + 1) % 3]->y);
109
if(dist < len)
110
{
111
len = dist;
112
pick = i;
113
touched = true;
114
}
115
}
116
}
117
118
if(!touched)
119
{
120
makeWaiting();
121
return 0;
122
}
123
124
a = nodes[pick];
125
b = nodes[(pick + 1)%3];
126
c = nodes[(pick + 2)%3];
127
128
mx = (a->x + b->x) / 2.0;
129
my = (a->y + b->y) / 2.0;
130
131
h = bg.interpolate( mx, my );
132
133
ny = b->x - a->x;
134
nx = b->y - a->y;
135
nx = -nx;
136
nx /= len;
137
ny /= len;
138
139
double error, A, B, C = h, D = h;
140
141
do
142
{
143
A = (len * len + C * C - D * D) / (2.0 * len);
144
145
if (A > C || (len - A) > D)
146
{
147
lx = vx;
148
ly = vy;
149
return 5;
150
}
151
152
B = sqrt(C * C - A * A);
153
154
lx = a->x + A * ny + B * nx;
155
ly = a->y - A * nx + B * ny;
156
157
double vx1 = (lx + a->x) / 2.0, vy1 = (ly + a->y) / 2.0,
158
vx2 = (lx + b->x) / 2.0, vy2 = (ly + b->y) / 2.0;
159
160
double h1 = bg.interpolate(vx1, vy1);
161
double h2 = bg.interpolate(vx2, vy2);
162
163
double e1 = fabs(distance(lx, ly, a->x, a->y) - h1) / h1, e2 = fabs(distance(lx, ly, b->x, b->y) - h2) / h2;
164
165
C = 0.75 * C + 0.25 * h1;
166
D = 0.75 * D + 0.25 * h2;
167
168
error = e1 + e2;
169
} while (error > 1e-2);
170
171
if (C > radius && D > radius)
172
{
173
lx = vx;
174
ly = vy;
175
}
176
177
return 4;
178
}
179
180
#else
181
int VSVertex::
182
computeNewCoordinates( BGMesh& bg, double& lx, double& ly )
183
{
184
double h = 0;
185
double rho;
186
double mx,my;
187
double P;
188
double Q;
189
double ex,ey;
190
double len;
191
double dist;
192
double rhohat;
193
double nx, ny;
194
int i,pick;
195
Node *a,*b,*c;
196
bool touched = false;
197
198
nx = 0; ny = 0;
199
len = 2 * radius;
200
pick = 0;
201
202
for(i = 0; i < 3; ++i)
203
{
204
VSVertex *vtx = static_cast<VSVertex *>( vertices[i] );
205
if(vtx->isExternal() || vtx->isAccepted())
206
{
207
dist = distance(nodes[i]->x, nodes[i]->y,
208
nodes[(i + 1) % 3]->x,
209
nodes[(i + 1) % 3]->y);
210
if(dist < len)
211
{
212
len = dist;
213
pick = i;
214
touched = true;
215
}
216
}
217
}
218
219
if(!touched)
220
{
221
makeWaiting();
222
return 0;
223
}
224
225
a = nodes[pick];
226
b = nodes[(pick + 1)%3];
227
c = nodes[(pick + 2)%3];
228
229
mx = (a->x + b->x) / 2.0;
230
my = (a->y + b->y) / 2.0;
231
232
h = bg.interpolate( mx, my );
233
// rho = h / std::sqrt( 3.0 );
234
rho = h * htor;
235
236
Q = distance(vx,vy,mx,my);
237
P = len / 2.0;
238
239
double minrad = (P*P + Q*Q) / (2.0 * Q);
240
241
if(minrad < rho || minrad < P)
242
{
243
lx = vx;
244
ly = vy;
245
return 2;
246
}
247
248
ny = b->x - a->x;
249
nx = b->y - a->y;
250
nx = -nx;
251
nx /= len;
252
ny /= len;
253
254
if(P > rho)
255
{
256
lx = mx + P * nx;
257
ly = my + P * ny;
258
return 3;
259
}
260
261
// dist = 0.5 * std::sqrt( 3.0 ) * h;
262
dist = h * rtoh;
263
lx = mx + dist * nx;
264
ly = my + dist * ny;
265
266
return 1;
267
}
268
#endif
269
270
#endif
271
272