ENH: additional methods and improvements to plane

- signedDistance() method is like distance() but retains
  the positive/negative sign for the side of the plane.

- the sign() method returns the sign as -1,0,+1 integer for
  classification purposes where it is important to distinguish between
  a zero value and a positive value (eg, for cutting). Optional
  tolerance can be supplied to round for zero.

- refactor and inlined simple and frequently used methods.

- add boundBox faceCentre() method, which can be useful for creating
  clipping planes from a bounding box.
  Relocated treeBoundBox faceNormals to boundBox since they apply
  equally there - the meaning of the faces (x-min, x-max, etc)
  is the same, even if the point addressing for the faces differs.
This commit is contained in:
Mark Olesen
2018-08-03 23:17:49 +02:00
parent 84e2df4994
commit de2eed3e7d
32 changed files with 537 additions and 442 deletions

View File

@ -44,7 +44,7 @@ Foam::scalar Foam::faceAreaIntersect::tol = 1e-6;
void Foam::faceAreaIntersect::triSliceWithPlane
(
const triPoints& tri,
const plane& p,
const plane& pln,
FixedList<triPoints, 10>& tris,
label& nTris,
const scalar len
@ -61,7 +61,7 @@ void Foam::faceAreaIntersect::triSliceWithPlane
label copI = -1;
forAll(tri, i)
{
d[i] = ((tri[i] - p.refPoint()) & p.normal());
d[i] = pln.signedDistance(tri[i]);
if (mag(d[i]) < tol*len)
{

View File

@ -133,7 +133,7 @@ private:
void triSliceWithPlane
(
const triPoints& tri,
const plane& p,
const plane& pln,
FixedList<triPoints, 10>& tris,
label& nTris,
const scalar len

View File

@ -57,26 +57,21 @@ Foam::pointIndexHit Foam::searchableDisk::findNearest
{
pointIndexHit info(false, sample, -1);
vector v(sample - origin_);
vector v(sample - origin());
// Decompose sample-origin into normal and parallel component
const scalar parallel = (v & normal_);
const scalar parallel = (v & normal());
// Remove the parallel component and normalise
v -= parallel*normal_;
scalar magV = mag(v);
v -= parallel * normal();
const scalar magV = mag(v);
v.normalise();
if (magV < ROOTVSMALL)
{
v = Zero;
}
else
{
v /= magV;
}
// Clip to radius.
info.setPoint(origin_ + min(magV, radius_)*v);
info.setPoint(origin() + min(magV, radius_)*v);
if (magSqr(sample - info.rawPoint()) < nearestDistSqr)
{
@ -97,31 +92,26 @@ void Foam::searchableDisk::findLine
{
info = pointIndexHit(false, Zero, -1);
vector v(start - origin_);
vector v(start - origin());
// Decompose sample-origin into normal and parallel component
const scalar parallel = (v & normal_);
const scalar parallel = (v & normal());
if (sign(parallel) == sign((end - origin_) & normal_))
if (Foam::sign(parallel) == Foam::sign(plane::signedDistance(end)))
{
return;
}
// Remove the parallel component and normalise
v -= parallel*normal_;
scalar magV = mag(v);
v -= parallel * normal();
const scalar magV = mag(v);
v.normalise();
if (magV < ROOTVSMALL)
{
v = Zero;
}
else
{
v /= magV;
}
// Set (hit or miss) to intersection of ray and plane of disk
info.setPoint(origin_ + magV*v);
info.setPoint(origin() + magV*v);
if (magV <= radius_)
{
@ -136,30 +126,29 @@ void Foam::searchableDisk::findLine
Foam::searchableDisk::searchableDisk
(
const IOobject& io,
const point& origin,
const point& normal,
const point& originPoint,
const vector& normalVector,
const scalar radius
)
:
searchableSurface(io),
origin_(origin),
normal_(normal/mag(normal)),
plane(originPoint, normalVector),
radius_(radius)
{
// Rough approximation of bounding box
//vector span(radius_, radius_, radius_);
// vector span(radius_, radius_, radius_);
// See searchableCylinder
vector span
(
sqrt(sqr(normal_.y()) + sqr(normal_.z())),
sqrt(sqr(normal_.x()) + sqr(normal_.z())),
sqrt(sqr(normal_.x()) + sqr(normal_.y()))
sqrt(sqr(normal().y()) + sqr(normal().z())),
sqrt(sqr(normal().x()) + sqr(normal().z())),
sqrt(sqr(normal().x()) + sqr(normal().y()))
);
span *= radius_;
bounds().min() = origin_ - span;
bounds().max() = origin_ + span;
bounds().min() = origin() - span;
bounds().max() = origin() + span;
}
@ -169,28 +158,14 @@ Foam::searchableDisk::searchableDisk
const dictionary& dict
)
:
searchableSurface(io),
origin_(dict.get<point>("origin")),
normal_(dict.get<vector>("normal")),
radius_(dict.get<scalar>("radius"))
{
normal_ /= mag(normal_);
// Rough approximation of bounding box
//vector span(radius_, radius_, radius_);
// See searchableCylinder
vector span
searchableDisk
(
sqrt(sqr(normal_.y()) + sqr(normal_.z())),
sqrt(sqr(normal_.x()) + sqr(normal_.z())),
sqrt(sqr(normal_.x()) + sqr(normal_.y()))
);
span *= radius_;
bounds().min() = origin_ - span;
bounds().max() = origin_ + span;
}
io,
dict.get<point>("origin"),
dict.get<vector>("normal"),
dict.get<scalar>("radius")
)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
@ -213,7 +188,7 @@ void Foam::searchableDisk::boundingSpheres
) const
{
centres.setSize(1);
centres[0] = origin_;
centres[0] = origin();
radiusSqr.setSize(1);
radiusSqr[0] = sqr(radius_);
@ -299,7 +274,7 @@ void Foam::searchableDisk::getRegion
labelList& region
) const
{
region.setSize(info.size());
region.resize(info.size());
region = 0;
}
@ -307,11 +282,11 @@ void Foam::searchableDisk::getRegion
void Foam::searchableDisk::getNormal
(
const List<pointIndexHit>& info,
vectorField& normal
vectorField& normals
) const
{
normal.setSize(info.size());
normal = normal_;
normals.resize(info.size());
normals = normal();
}

View File

@ -45,7 +45,7 @@ SourceFiles
#ifndef searchableDisk_H
#define searchableDisk_H
#include "treeBoundBox.H"
#include "plane.H"
#include "searchableSurface.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -59,18 +59,13 @@ namespace Foam
class searchableDisk
:
public searchableSurface
public searchableSurface,
public plane
{
private:
// Private Member Data
//- Origin
const point origin_;
//- Normal
vector normal_;
//- Radius
const scalar radius_;
@ -116,8 +111,8 @@ public:
searchableDisk
(
const IOobject& io,
const point& origin,
const point& normal,
const point& originPoint,
const vector& normalVector,
const scalar radius
);
@ -128,6 +123,7 @@ public:
const dictionary& dict
);
//- Destructor
virtual ~searchableDisk() = default;
@ -153,7 +149,7 @@ public:
// Usually the element centres (should be of length size()).
virtual tmp<pointField> coordinates() const
{
return tmp<pointField>::New(1, origin_);
return tmp<pointField>::New(one(), origin());
}
//- Get bounding spheres (centre and radius squared), one per element.
@ -220,7 +216,7 @@ public:
virtual void getNormal
(
const List<pointIndexHit>&,
vectorField& normal
vectorField& normals
) const;
//- Determine type (inside/outside/mixed) for point.

View File

@ -145,7 +145,7 @@ void Foam::searchablePlane::boundingSpheres
) const
{
centres.setSize(1);
centres[0] = refPoint();
centres[0] = origin();
radiusSqr.setSize(1);
radiusSqr[0] = Foam::sqr(GREAT);

View File

@ -134,7 +134,7 @@ public:
// Usually the element centres (should be of length size()).
virtual tmp<pointField> coordinates() const
{
return tmp<pointField>::New(1, refPoint());
return tmp<pointField>::New(1, origin());
}
//- Get bounding spheres (centre and radius squared), one per element.

View File

@ -855,7 +855,7 @@ Foam::surfaceLocation Foam::triSurfaceTools::cutEdge
scalar norm = 0;
forAll(d, fp)
{
d[fp] = (points[f[fp]]-cutPlane.refPoint()) & cutPlane.normal();
d[fp] = cutPlane.signedDistance(points[f[fp]]);
norm += mag(d[fp]);
}