2009-01-13 04:40:13 +05:00
|
|
|
// find inner point
|
|
|
|
|
2009-01-25 17:35:25 +05:00
|
|
|
template <typename POINTArray, typename FACEArray>
|
|
|
|
inline int FindInnerPoint2 (POINTArray & points,
|
|
|
|
FACEArray & faces,
|
2009-01-13 04:40:13 +05:00
|
|
|
Point3d & p)
|
|
|
|
{
|
|
|
|
static int timer = NgProfiler::CreateTimer ("FindInnerPoint2");
|
|
|
|
NgProfiler::RegionTimer reg (timer);
|
|
|
|
|
2019-07-09 13:39:16 +05:00
|
|
|
NgArray<Vec3d> a;
|
|
|
|
NgArray<double> c;
|
2009-01-13 04:40:13 +05:00
|
|
|
Mat<3> m, inv;
|
|
|
|
Vec<3> rs, x, pmin;
|
|
|
|
|
|
|
|
int nf = faces.Size();
|
|
|
|
|
|
|
|
a.SetSize (nf);
|
|
|
|
c.SetSize (nf);
|
|
|
|
|
|
|
|
for (int i = 0; i < nf; i++)
|
|
|
|
{
|
|
|
|
Point3d p1 = points.Get(faces[i][0]);
|
|
|
|
a[i] = Cross (points.Get(faces[i][1]) - p1,
|
|
|
|
points.Get(faces[i][2]) - p1);
|
|
|
|
a[i] /= a[i].Length();
|
|
|
|
c[i] = - (a[i].X() * p1.X() + a[i].Y() * p1.Y() + a[i].Z() * p1.Z());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
x = 0;
|
|
|
|
|
|
|
|
|
|
|
|
double hmax = 0;
|
|
|
|
for (int i = 0; i < nf; i++)
|
|
|
|
{
|
|
|
|
const Element2d & el = faces[i];
|
|
|
|
for (int j = 1; j <= 3; j++)
|
|
|
|
{
|
|
|
|
double hi = Dist (points.Get(el.PNumMod(j)),
|
|
|
|
points.Get(el.PNumMod(j+1)));
|
|
|
|
if (hi > hmax) hmax = hi;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
double fmin = 0;
|
|
|
|
|
|
|
|
for (int i1 = 1; i1 <= nf; i1++)
|
|
|
|
for (int i2 = i1+1; i2 <= nf; i2++)
|
|
|
|
for (int i3 = i2+1; i3 <= nf; i3++)
|
|
|
|
for (int i4 = i3+1; i4 <= nf; i4++)
|
|
|
|
{
|
|
|
|
m(0, 0) = a.Get(i1).X() - a.Get(i2).X();
|
|
|
|
m(0, 1) = a.Get(i1).Y() - a.Get(i2).Y();
|
|
|
|
m(0, 2) = a.Get(i1).Z() - a.Get(i2).Z();
|
|
|
|
rs(0) = c.Get(i2) - c.Get(i1);
|
|
|
|
|
|
|
|
m(1, 0) = a.Get(i1).X() - a.Get(i3).X();
|
|
|
|
m(1, 1) = a.Get(i1).Y() - a.Get(i3).Y();
|
|
|
|
m(1, 2) = a.Get(i1).Z() - a.Get(i3).Z();
|
|
|
|
rs(1) = c.Get(i3) - c.Get(i1);
|
|
|
|
|
|
|
|
m(2, 0) = a.Get(i1).X() - a.Get(i4).X();
|
|
|
|
m(2, 1) = a.Get(i1).Y() - a.Get(i4).Y();
|
|
|
|
m(2, 2) = a.Get(i1).Z() - a.Get(i4).Z();
|
|
|
|
rs(2) = c.Get(i4) - c.Get(i1);
|
|
|
|
|
|
|
|
|
|
|
|
if (fabs (Det (m)) > 1e-10)
|
|
|
|
{
|
|
|
|
CalcInverse (m, inv);
|
|
|
|
x = inv * rs;
|
|
|
|
|
|
|
|
double f = -1e10;
|
|
|
|
for (int i = 0; i < nf; i++)
|
|
|
|
{
|
|
|
|
double hd =
|
|
|
|
x(0) * a[i].X() + x(1) * a[i].Y() + x(2) * a[i].Z() + c[i];
|
|
|
|
if (hd > f) f = hd;
|
|
|
|
if (hd > fmin) break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (f < fmin)
|
|
|
|
{
|
|
|
|
fmin = f;
|
|
|
|
pmin = x;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
p = Point3d (pmin(0), pmin(1), pmin(2));
|
|
|
|
(*testout) << "fmin = " << fmin << endl;
|
|
|
|
return (fmin < -1e-3 * hmax);
|
|
|
|
}
|
|
|
|
|