Path: blob/devel/ElmerGUI/netgen/libsrc/meshing/findip.hpp
3206 views
// find inner point1234inline void Minimize (const ARRAY<Vec3d> & a,5const ARRAY<double> & c,6int * act,7Vec<3> & x, double & f,8int * sol)9{10int act1[4];11Mat<3> m, inv;12Vec<3> rs, xmax, center;1314f = 1e99;1516for (int j = 0; j < 5; j++)17{18for (int hk = 0, k = 0; hk < 4; hk++)19{20if (hk == j) k++;21act1[hk] = act[k];22k++;23}2425for (int k = 0; k < 3; k++)26{27m(k, 0) = a[act1[0]].X() - a[act1[k+1]].X();28m(k, 1) = a[act1[0]].Y() - a[act1[k+1]].Y();29m(k, 2) = a[act1[0]].Z() - a[act1[k+1]].Z();30rs(k) = c[act1[k+1]] - c[act1[0]];31}3233/*34(*testout) << "act1 = "35<< act1[0] << " "36<< act1[1] << " "37<< act1[2] << " "38<< act1[3] << endl;39(*testout) << "Det = " << Det(m) << endl;40*/4142if (fabs (Det (m)) > 1e-10)43{44CalcInverse (m, inv);45xmax = inv * rs;4647double fmax = -1e10;48for (int k = 0; k < 5; k++)49{50double hd =51xmax(0) * a[act[k]].X() + xmax(1) * a[act[k]].Y() + xmax(2) * a[act[k]].Z() + c[act[k]];52if (hd > fmax) fmax = hd;53}5455if (fmax < f)56{57f = fmax;58x = xmax;59for (int k = 0; k < 4; k++)60sol[k] = act1[k];61}62}63}64}6566676869template <typename POINTARRAY, typename FACEARRAY>70inline int FindInnerPoint (POINTARRAY & points,71FACEARRAY & faces,72Point3d & p)73{74static int timer = NgProfiler::CreateTimer ("FindInnerPoint");75NgProfiler::RegionTimer reg (timer);7677ARRAY<Vec3d> a;78ARRAY<double> c;79Mat<3> m, inv;80Vec<3> rs, x, center;81double f;8283int nf = faces.Size();8485// minimize_x max_i a_i x + c_i8687a.SetSize (nf+4);88c.SetSize (nf+4);8990for (int i = 0; i < nf; i++)91{92Point3d p1 = points.Get(faces[i][0]);93a[i] = Cross (points.Get(faces[i][1]) - p1,94points.Get(faces[i][2]) - p1);95a[i] /= a[i].Length();96c[i] = - (a[i].X() * p1.X() + a[i].Y() * p1.Y() + a[i].Z() * p1.Z());97}9899/*100center = 0;101for (int i = 0; i < points.Size(); i++)102center += Vec<3> (points[i]);103center /= points.Size();104*/105106center = 0;107for (int i = 0; i < faces.Size(); i++)108for (int j = 0; j < 3; j++)109center += Vec<3> (points.Get(faces[i][j]));110center /= (3*faces.Size());111112113// (*testout) << "center = " << center << endl;114115double hmax = 0;116for (int i = 0; i < nf; i++)117{118// const Element2d & el = faces[i];119// (*testout) << "el[" << i << "] = " << el << endl;120for (int j = 1; j <= 3; j++)121{122double hi = Dist (points.Get(faces[i].PNumMod(j)),123points.Get(faces[i].PNumMod(j+1)));124if (hi > hmax) hmax = hi;125}126}127128// (*testout) << "hmax = " << hmax << endl;129130a[nf] = Vec<3> (1, 0, 0);131c[nf] = -center(0) - hmax;132a[nf+1] = Vec<3> (0, 1, 0);133c[nf+1] = -center(1) - hmax;134a[nf+2] = Vec<3> (0, 0, 1);135c[nf+2] = -center(2) - hmax;136a[nf+3] = Vec<3> (-1, -1, -1);137c[nf+3] = center(0)+center(1)+center(2)-3*hmax;138139/*140(*testout) << "findip, a now = " << endl << a << endl;141(*testout) << "findip, c now = " << endl << c << endl;142*/143144int act[5] = { 0, nf, nf+1, nf+2, nf+3 };145int sol[4];146147while (1)148{149/*150(*testout) << "try ";151for (int j = 0; j < 5; j++)152(*testout) << act[j] << " ";153*/154155Minimize (a, c, act, x, f, sol);156157/*158(*testout) << endl << "sol = ";159for (int j = 0; j < 4; j++)160(*testout) << sol[j] << " ";161162(*testout) << " fmin = " << f << endl;163*/164for (int j = 0; j < 4; j++) act[j] = sol[j];165166bool found = 0;167double maxval = f;168for (int j = 0; j < nf; j++)169{170double val = x(0) * a[j].X() + x(1) * a[j].Y() + x(2) * a[j].Z() + c[j];171if (val > maxval + hmax * 1e-6)172{173found = 1;174maxval = val;175act[4] = j;176}177}178179// (*testout) << "maxval = " << maxval << endl;180if (!found) break;181}182183// cout << "converged, f = " << f << endl;184185p = Point3d (x(0), x(1), x(2));186// (*testout) << "findip, f = " << f << ", hmax = " << hmax << endl;187return (f < -1e-5 * hmax);188}189190191192193194