Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/ElmerGUI/netgen/libsrc/meshing/findip.hpp
3206 views
1
// find inner point
2
3
4
5
inline void Minimize (const ARRAY<Vec3d> & a,
6
const ARRAY<double> & c,
7
int * act,
8
Vec<3> & x, double & f,
9
int * sol)
10
{
11
int act1[4];
12
Mat<3> m, inv;
13
Vec<3> rs, xmax, center;
14
15
f = 1e99;
16
17
for (int j = 0; j < 5; j++)
18
{
19
for (int hk = 0, k = 0; hk < 4; hk++)
20
{
21
if (hk == j) k++;
22
act1[hk] = act[k];
23
k++;
24
}
25
26
for (int k = 0; k < 3; k++)
27
{
28
m(k, 0) = a[act1[0]].X() - a[act1[k+1]].X();
29
m(k, 1) = a[act1[0]].Y() - a[act1[k+1]].Y();
30
m(k, 2) = a[act1[0]].Z() - a[act1[k+1]].Z();
31
rs(k) = c[act1[k+1]] - c[act1[0]];
32
}
33
34
/*
35
(*testout) << "act1 = "
36
<< act1[0] << " "
37
<< act1[1] << " "
38
<< act1[2] << " "
39
<< act1[3] << endl;
40
(*testout) << "Det = " << Det(m) << endl;
41
*/
42
43
if (fabs (Det (m)) > 1e-10)
44
{
45
CalcInverse (m, inv);
46
xmax = inv * rs;
47
48
double fmax = -1e10;
49
for (int k = 0; k < 5; k++)
50
{
51
double hd =
52
xmax(0) * a[act[k]].X() + xmax(1) * a[act[k]].Y() + xmax(2) * a[act[k]].Z() + c[act[k]];
53
if (hd > fmax) fmax = hd;
54
}
55
56
if (fmax < f)
57
{
58
f = fmax;
59
x = xmax;
60
for (int k = 0; k < 4; k++)
61
sol[k] = act1[k];
62
}
63
}
64
}
65
}
66
67
68
69
70
template <typename POINTARRAY, typename FACEARRAY>
71
inline int FindInnerPoint (POINTARRAY & points,
72
FACEARRAY & faces,
73
Point3d & p)
74
{
75
static int timer = NgProfiler::CreateTimer ("FindInnerPoint");
76
NgProfiler::RegionTimer reg (timer);
77
78
ARRAY<Vec3d> a;
79
ARRAY<double> c;
80
Mat<3> m, inv;
81
Vec<3> rs, x, center;
82
double f;
83
84
int nf = faces.Size();
85
86
// minimize_x max_i a_i x + c_i
87
88
a.SetSize (nf+4);
89
c.SetSize (nf+4);
90
91
for (int i = 0; i < nf; i++)
92
{
93
Point3d p1 = points.Get(faces[i][0]);
94
a[i] = Cross (points.Get(faces[i][1]) - p1,
95
points.Get(faces[i][2]) - p1);
96
a[i] /= a[i].Length();
97
c[i] = - (a[i].X() * p1.X() + a[i].Y() * p1.Y() + a[i].Z() * p1.Z());
98
}
99
100
/*
101
center = 0;
102
for (int i = 0; i < points.Size(); i++)
103
center += Vec<3> (points[i]);
104
center /= points.Size();
105
*/
106
107
center = 0;
108
for (int i = 0; i < faces.Size(); i++)
109
for (int j = 0; j < 3; j++)
110
center += Vec<3> (points.Get(faces[i][j]));
111
center /= (3*faces.Size());
112
113
114
// (*testout) << "center = " << center << endl;
115
116
double hmax = 0;
117
for (int i = 0; i < nf; i++)
118
{
119
// const Element2d & el = faces[i];
120
// (*testout) << "el[" << i << "] = " << el << endl;
121
for (int j = 1; j <= 3; j++)
122
{
123
double hi = Dist (points.Get(faces[i].PNumMod(j)),
124
points.Get(faces[i].PNumMod(j+1)));
125
if (hi > hmax) hmax = hi;
126
}
127
}
128
129
// (*testout) << "hmax = " << hmax << endl;
130
131
a[nf] = Vec<3> (1, 0, 0);
132
c[nf] = -center(0) - hmax;
133
a[nf+1] = Vec<3> (0, 1, 0);
134
c[nf+1] = -center(1) - hmax;
135
a[nf+2] = Vec<3> (0, 0, 1);
136
c[nf+2] = -center(2) - hmax;
137
a[nf+3] = Vec<3> (-1, -1, -1);
138
c[nf+3] = center(0)+center(1)+center(2)-3*hmax;
139
140
/*
141
(*testout) << "findip, a now = " << endl << a << endl;
142
(*testout) << "findip, c now = " << endl << c << endl;
143
*/
144
145
int act[5] = { 0, nf, nf+1, nf+2, nf+3 };
146
int sol[4];
147
148
while (1)
149
{
150
/*
151
(*testout) << "try ";
152
for (int j = 0; j < 5; j++)
153
(*testout) << act[j] << " ";
154
*/
155
156
Minimize (a, c, act, x, f, sol);
157
158
/*
159
(*testout) << endl << "sol = ";
160
for (int j = 0; j < 4; j++)
161
(*testout) << sol[j] << " ";
162
163
(*testout) << " fmin = " << f << endl;
164
*/
165
for (int j = 0; j < 4; j++) act[j] = sol[j];
166
167
bool found = 0;
168
double maxval = f;
169
for (int j = 0; j < nf; j++)
170
{
171
double val = x(0) * a[j].X() + x(1) * a[j].Y() + x(2) * a[j].Z() + c[j];
172
if (val > maxval + hmax * 1e-6)
173
{
174
found = 1;
175
maxval = val;
176
act[4] = j;
177
}
178
}
179
180
// (*testout) << "maxval = " << maxval << endl;
181
if (!found) break;
182
}
183
184
// cout << "converged, f = " << f << endl;
185
186
p = Point3d (x(0), x(1), x(2));
187
// (*testout) << "findip, f = " << f << ", hmax = " << hmax << endl;
188
return (f < -1e-5 * hmax);
189
}
190
191
192
193
194