mirror of
https://github.com/NGSolve/netgen.git
synced 2024-11-14 10:08:32 +05:00
robust Polyhedron::VecInSolid option
This commit is contained in:
parent
f55e3e6eb4
commit
476a4c350c
@ -100,64 +100,45 @@ INSOLID_TYPE Polyhedra :: BoxInSolid (const BoxSphere<3> & box) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// check how many faces a ray starting in p intersects
|
||||||
INSOLID_TYPE Polyhedra :: PointInSolid (const Point<3> & p,
|
INSOLID_TYPE Polyhedra :: PointInSolid (const Point<3> & p,
|
||||||
double eps) const
|
double eps) const
|
||||||
{
|
{
|
||||||
//(*testout) << "PointInSolid p " << p << " eps " << eps << endl;
|
if (!poly_bbox.IsIn (p, eps))
|
||||||
//(*testout) << "bbox " << poly_bbox << endl;
|
|
||||||
|
|
||||||
if((p(0) > poly_bbox.PMax()(0) + eps) || (p(0) < poly_bbox.PMin()(0) - eps) ||
|
|
||||||
(p(1) > poly_bbox.PMax()(1) + eps) || (p(1) < poly_bbox.PMin()(1) - eps) ||
|
|
||||||
(p(2) > poly_bbox.PMax()(2) + eps) || (p(2) < poly_bbox.PMin()(2) - eps))
|
|
||||||
{
|
|
||||||
//(*testout) << "returning IS_OUTSIDE" << endl;
|
|
||||||
return IS_OUTSIDE;
|
return IS_OUTSIDE;
|
||||||
}
|
|
||||||
|
|
||||||
Vec<3> n, v1, v2;
|
// random (?) direction:
|
||||||
|
Vec<3> n(-0.424621, 0.1543, 0.89212238);
|
||||||
// random (?) numbers:
|
|
||||||
n(0) = -0.424621;
|
|
||||||
n(1) = 0.15432;
|
|
||||||
n(2) = 0.89212238;
|
|
||||||
|
|
||||||
int cnt = 0;
|
int cnt = 0;
|
||||||
|
for (auto & face : faces)
|
||||||
for (int i = 0; i < faces.Size(); i++)
|
|
||||||
{
|
{
|
||||||
const Point<3> & p1 = points[faces[i].pnums[0]];
|
Vec<3> v0 = p - points[face.pnums[0]];
|
||||||
|
|
||||||
Vec<3> v0 = p - p1;
|
double lam3 = face.nn * v0;
|
||||||
|
|
||||||
double lam3 = faces[i].nn * v0;
|
if (fabs(lam3) < eps) // point is in plance of face
|
||||||
|
|
||||||
if(fabs(lam3) < eps)
|
|
||||||
{
|
{
|
||||||
double lam1 = (faces[i].w1 * v0);
|
double lam1 = face.w1 * v0;
|
||||||
double lam2 = (faces[i].w2 * v0);
|
double lam2 = face.w2 * v0;
|
||||||
if (lam1 >= -eps_base1 && lam2 >= -eps_base1 && lam1+lam2 <= 1+eps_base1)
|
if (lam1 >= -eps_base1 && lam2 >= -eps_base1 && lam1+lam2 <= 1+eps_base1)
|
||||||
{
|
|
||||||
//(*testout) << "returning DOES_INTERSECT" << endl;
|
|
||||||
return DOES_INTERSECT;
|
return DOES_INTERSECT;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
lam3 = -(faces[i].n * v0) / (faces[i].n * n);
|
double lam3 = -(face.n * v0) / (face.n * n);
|
||||||
|
|
||||||
if (lam3 < 0) continue;
|
if (lam3 < 0) continue; // ray goes not in direction of face
|
||||||
|
|
||||||
Vec<3> rs = v0 + lam3 * n;
|
Vec<3> rs = v0 + lam3 * n;
|
||||||
|
|
||||||
double lam1 = (faces[i].w1 * rs);
|
double lam1 = face.w1 * rs;
|
||||||
double lam2 = (faces[i].w2 * rs);
|
double lam2 = face.w2 * rs;
|
||||||
if (lam1 >= 0 && lam2 >= 0 && lam1+lam2 <= 1)
|
if (lam1 >= 0 && lam2 >= 0 && lam1+lam2 <= 1)
|
||||||
cnt++;
|
cnt++;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//(*testout) << " cnt = " << cnt%2 << endl;
|
|
||||||
return (cnt % 2) ? IS_INSIDE : IS_OUTSIDE;
|
return (cnt % 2) ? IS_INSIDE : IS_OUTSIDE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,15 +150,16 @@ void Polyhedra :: GetTangentialSurfaceIndices (const Point<3> & p,
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < faces.Size(); i++)
|
for (int i = 0; i < faces.Size(); i++)
|
||||||
{
|
{
|
||||||
const Point<3> & p1 = points[faces[i].pnums[0]];
|
auto & face = faces[i];
|
||||||
|
const Point<3> & p1 = points[face.pnums[0]];
|
||||||
|
|
||||||
Vec<3> v0 = p - p1;
|
Vec<3> v0 = p - p1;
|
||||||
double lam3 = -(faces[i].nn * v0); // n->nn
|
double lam3 = -(face.nn * v0); // n->nn
|
||||||
|
|
||||||
if (fabs (lam3) > eps) continue;
|
if (fabs (lam3) > eps) continue;
|
||||||
|
|
||||||
double lam1 = (faces[i].w1 * v0);
|
double lam1 = (face.w1 * v0);
|
||||||
double lam2 = (faces[i].w2 * v0);
|
double lam2 = (face.w2 * v0);
|
||||||
|
|
||||||
if (lam1 >= -eps_base1 && lam2 >= -eps_base1 && lam1+lam2 <= 1+eps_base1)
|
if (lam1 >= -eps_base1 && lam2 >= -eps_base1 && lam1+lam2 <= 1+eps_base1)
|
||||||
if (!surfind.Contains (GetSurfaceId(i)))
|
if (!surfind.Contains (GetSurfaceId(i)))
|
||||||
@ -186,8 +168,8 @@ void Polyhedra :: GetTangentialSurfaceIndices (const Point<3> & p,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define OLDVECINSOLD
|
||||||
|
#ifdef OLDVECINSOLD
|
||||||
INSOLID_TYPE Polyhedra :: VecInSolid (const Point<3> & p,
|
INSOLID_TYPE Polyhedra :: VecInSolid (const Point<3> & p,
|
||||||
const Vec<3> & v,
|
const Vec<3> & v,
|
||||||
double eps) const
|
double eps) const
|
||||||
@ -250,16 +232,103 @@ INSOLID_TYPE Polyhedra :: VecInSolid (const Point<3> & p,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Point<3> p2 = p + (1e-2*mindist) * vn;
|
Point<3> p2 = p + (1e-4*mindist) * vn;
|
||||||
res = PointInSolid (p2, eps);
|
res = PointInSolid (p2, eps);
|
||||||
|
|
||||||
// (*testout) << "mindist " << mindist << " res " << res << endl;
|
// (*testout) << "mindist " << mindist << " res " << res << endl;
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
|
||||||
|
// check how many faces a ray starting in p+alpha*v intersects
|
||||||
|
INSOLID_TYPE Polyhedra :: VecInSolid (const Point<3> & p,
|
||||||
|
const Vec<3> & v,
|
||||||
|
double eps) const
|
||||||
|
{
|
||||||
|
if (!poly_bbox.IsIn (p, eps))
|
||||||
|
return IS_OUTSIDE;
|
||||||
|
|
||||||
|
// random (?) direction:
|
||||||
|
Vec<3> n(-0.424621, 0.1543, 0.89212238);
|
||||||
|
|
||||||
|
int cnt = 0;
|
||||||
|
for (auto & face : faces)
|
||||||
|
{
|
||||||
|
Vec<3> v0 = p - points[face.pnums[0]];
|
||||||
|
|
||||||
|
double lamn = face.nn * v0;
|
||||||
|
|
||||||
|
if (fabs(lamn) < eps) // point is in plance of face
|
||||||
|
{
|
||||||
|
double lam1 = face.w1 * v0;
|
||||||
|
double lam2 = face.w2 * v0;
|
||||||
|
double lam3 = 1-lam1-lam2;
|
||||||
|
|
||||||
|
if (lam1 >= -eps_base1 && lam2 >= -eps_base1 && lam3 >= -eps_base1)
|
||||||
|
{ // point is close to trianlge, perturbe by alpha*v
|
||||||
|
double dlamn = face.nn*v;
|
||||||
|
double dlam1 = face.w1 * v;
|
||||||
|
double dlam2 = face.w2 * v;
|
||||||
|
double dlam3 = 1-dlam1-dlam2;
|
||||||
|
|
||||||
|
if (fabs(dlamn) < 1e-8) // vec also in plane
|
||||||
|
{
|
||||||
|
bool in1 = lam1 > eps_base1 || dlam1 > -eps_base1;
|
||||||
|
bool in2 = lam2 > eps_base1 || dlam2 > -eps_base1;
|
||||||
|
bool in3 = lam3 > eps_base1 || dlam3 > -eps_base1;
|
||||||
|
if (in1 && in2 && in3)
|
||||||
|
return DOES_INTERSECT;
|
||||||
|
}
|
||||||
|
else // vec out of plane
|
||||||
|
{
|
||||||
|
double dlamn = -(face.n * v) / (face.n * n);
|
||||||
|
if (dlamn < 0) continue; // ray goes not in direction of face
|
||||||
|
|
||||||
|
Vec<3> drs = v0 + lamn * n;
|
||||||
|
|
||||||
|
double dlam1 = dlamn * face.w1 * v;
|
||||||
|
double dlam2 = dlamn * face.w2 * v;
|
||||||
|
double dlam3 = 1-dlam1-dlam2;
|
||||||
|
|
||||||
|
bool in1 = lam1 > eps_base1 || dlam1 > -eps_base1;
|
||||||
|
bool in2 = lam2 > eps_base1 || dlam2 > -eps_base1;
|
||||||
|
bool in3 = lam3 > eps_base1 || dlam3 > -eps_base1;
|
||||||
|
|
||||||
|
if (in1 && in2 && in3)
|
||||||
|
cnt++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
double lamn = -(face.n * v0) / (face.n * n);
|
||||||
|
|
||||||
|
if (lamn < 0) continue; // ray goes not in direction of face
|
||||||
|
|
||||||
|
Vec<3> rs = v0 + lamn * n;
|
||||||
|
|
||||||
|
double lam1 = face.w1 * rs;
|
||||||
|
double lam2 = face.w2 * rs;
|
||||||
|
double lam3 = 1-lam1-lam2;
|
||||||
|
if (lam1 >= 0 && lam2 >= 0 && lam3 >= 0)
|
||||||
|
cnt++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (cnt % 2) ? IS_INSIDE : IS_OUTSIDE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
INSOLID_TYPE Polyhedra :: VecInSolid2 (const Point<3> & p,
|
INSOLID_TYPE Polyhedra :: VecInSolid2 (const Point<3> & p,
|
||||||
|
@ -384,8 +384,16 @@ namespace netgen
|
|||||||
bool IsIn (const Point<D> & p) const
|
bool IsIn (const Point<D> & p) const
|
||||||
{
|
{
|
||||||
for (int i = 0; i < D; i++)
|
for (int i = 0; i < D; i++)
|
||||||
if (p(i) < pmin(i) || p(i) > pmax(i)) return 0;
|
if (p(i) < pmin(i) || p(i) > pmax(i)) return false;
|
||||||
return 1;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// is point in eps-increased box
|
||||||
|
bool IsIn (const Point<D> & p, double eps) const
|
||||||
|
{
|
||||||
|
for (int i = 0; i < D; i++)
|
||||||
|
if (p(i) < pmin(i)-eps || p(i) > pmax(i)+eps) return false;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user