00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "searchableSphere.H"
00027 #include <OpenFOAM/addToRunTimeSelectionTable.H>
00028
00029
00030
00031 namespace Foam
00032 {
00033
00034 defineTypeNameAndDebug(searchableSphere, 0);
00035 addToRunTimeSelectionTable(searchableSurface, searchableSphere, dict);
00036
00037 }
00038
00039
00040
00041
00042 Foam::pointIndexHit Foam::searchableSphere::findNearest
00043 (
00044 const point& sample,
00045 const scalar nearestDistSqr
00046 ) const
00047 {
00048 pointIndexHit info(false, sample, -1);
00049
00050 const vector n(sample-centre_);
00051 scalar magN = mag(n);
00052
00053 if (nearestDistSqr > sqr(magN-radius_))
00054 {
00055 if (magN < ROOTVSMALL)
00056 {
00057 info.rawPoint() = centre_ + vector(1,0,0)/magN*radius_;
00058 }
00059 else
00060 {
00061 info.rawPoint() = centre_ + n/magN*radius_;
00062 }
00063 info.setHit();
00064 info.setIndex(0);
00065 }
00066
00067 return info;
00068 }
00069
00070
00071
00072 void Foam::searchableSphere::findLineAll
00073 (
00074 const point& start,
00075 const point& end,
00076 pointIndexHit& near,
00077 pointIndexHit& far
00078 ) const
00079 {
00080 near.setMiss();
00081 far.setMiss();
00082
00083 vector dir(end-start);
00084 scalar magSqrDir = magSqr(dir);
00085
00086 if (magSqrDir > ROOTVSMALL)
00087 {
00088 const vector toCentre(centre_-start);
00089 scalar magSqrToCentre = magSqr(toCentre);
00090
00091 dir /= Foam::sqrt(magSqrDir);
00092
00093 scalar v = (toCentre & dir);
00094
00095 scalar disc = sqr(radius_) - (magSqrToCentre - sqr(v));
00096
00097 if (disc >= 0)
00098 {
00099 scalar d = Foam::sqrt(disc);
00100
00101 scalar nearParam = v-d;
00102
00103 if (nearParam >= 0 && sqr(nearParam) <= magSqrDir)
00104 {
00105 near.setHit();
00106 near.setPoint(start + nearParam*dir);
00107 near.setIndex(0);
00108 }
00109
00110 scalar farParam = v+d;
00111
00112 if (farParam >= 0 && sqr(farParam) <= magSqrDir)
00113 {
00114 far.setHit();
00115 far.setPoint(start + farParam*dir);
00116 far.setIndex(0);
00117 }
00118 }
00119 }
00120 }
00121
00122
00123
00124
00125 Foam::searchableSphere::searchableSphere
00126 (
00127 const IOobject& io,
00128 const point& centre,
00129 const scalar radius
00130 )
00131 :
00132 searchableSurface(io),
00133 centre_(centre),
00134 radius_(radius)
00135 {}
00136
00137
00138 Foam::searchableSphere::searchableSphere
00139 (
00140 const IOobject& io,
00141 const dictionary& dict
00142 )
00143 :
00144 searchableSurface(io),
00145 centre_(dict.lookup("centre")),
00146 radius_(readScalar(dict.lookup("radius")))
00147 {}
00148
00149
00150
00151
00152 Foam::searchableSphere::~searchableSphere()
00153 {}
00154
00155
00156
00157
00158 const Foam::wordList& Foam::searchableSphere::regions() const
00159 {
00160 if (regions_.empty())
00161 {
00162 regions_.setSize(1);
00163 regions_[0] = "region0";
00164 }
00165 return regions_;
00166 }
00167
00168
00169
00170 void Foam::searchableSphere::findNearest
00171 (
00172 const pointField& samples,
00173 const scalarField& nearestDistSqr,
00174 List<pointIndexHit>& info
00175 ) const
00176 {
00177 info.setSize(samples.size());
00178
00179 forAll(samples, i)
00180 {
00181 info[i] = findNearest(samples[i], nearestDistSqr[i]);
00182 }
00183 }
00184
00185
00186 void Foam::searchableSphere::findLine
00187 (
00188 const pointField& start,
00189 const pointField& end,
00190 List<pointIndexHit>& info
00191 ) const
00192 {
00193 info.setSize(start.size());
00194
00195 pointIndexHit b;
00196
00197 forAll(start, i)
00198 {
00199
00200 findLineAll(start[i], end[i], info[i], b);
00201 if (!info[i].hit() && b.hit())
00202 {
00203 info[i] = b;
00204 }
00205 }
00206 }
00207
00208
00209 void Foam::searchableSphere::findLineAny
00210 (
00211 const pointField& start,
00212 const pointField& end,
00213 List<pointIndexHit>& info
00214 ) const
00215 {
00216 info.setSize(start.size());
00217
00218 pointIndexHit b;
00219
00220 forAll(start, i)
00221 {
00222
00223 findLineAll(start[i], end[i], info[i], b);
00224 if (!info[i].hit() && b.hit())
00225 {
00226 info[i] = b;
00227 }
00228 }
00229 }
00230
00231
00232 void Foam::searchableSphere::findLineAll
00233 (
00234 const pointField& start,
00235 const pointField& end,
00236 List<List<pointIndexHit> >& info
00237 ) const
00238 {
00239 info.setSize(start.size());
00240
00241 forAll(start, i)
00242 {
00243 pointIndexHit near, far;
00244 findLineAll(start[i], end[i], near, far);
00245
00246 if (near.hit())
00247 {
00248 if (far.hit())
00249 {
00250 info[i].setSize(2);
00251 info[i][0] = near;
00252 info[i][1] = far;
00253 }
00254 else
00255 {
00256 info[i].setSize(1);
00257 info[i][0] = near;
00258 }
00259 }
00260 else
00261 {
00262 if (far.hit())
00263 {
00264 info[i].setSize(1);
00265 info[i][0] = far;
00266 }
00267 else
00268 {
00269 info[i].clear();
00270 }
00271 }
00272 }
00273 }
00274
00275
00276 void Foam::searchableSphere::getRegion
00277 (
00278 const List<pointIndexHit>& info,
00279 labelList& region
00280 ) const
00281 {
00282 region.setSize(info.size());
00283 region = 0;
00284 }
00285
00286
00287 void Foam::searchableSphere::getNormal
00288 (
00289 const List<pointIndexHit>& info,
00290 vectorField& normal
00291 ) const
00292 {
00293 normal.setSize(info.size());
00294 normal = vector::zero;
00295
00296 forAll(info, i)
00297 {
00298 if (info[i].hit())
00299 {
00300 normal[i] = info[i].hitPoint() - centre_;
00301
00302 normal[i] /= mag(normal[i])+VSMALL;
00303 }
00304 else
00305 {
00306
00307 }
00308 }
00309 }
00310
00311
00312 void Foam::searchableSphere::getVolumeType
00313 (
00314 const pointField& points,
00315 List<volumeType>& volType
00316 ) const
00317 {
00318 volType.setSize(points.size());
00319 volType = INSIDE;
00320
00321 forAll(points, pointI)
00322 {
00323 const point& pt = points[pointI];
00324
00325 if (magSqr(pt - centre_) <= sqr(radius_))
00326 {
00327 volType[pointI] = INSIDE;
00328 }
00329 else
00330 {
00331 volType[pointI] = OUTSIDE;
00332 }
00333 }
00334 }
00335
00336
00337