14 #ifndef ESYS_LSMSPHEREFITTER_H
15 #define ESYS_LSMSPHEREFITTER_H
28 template <
typename TmplFitTraits>
59 return Particle::INVALID;
82 void write(std::ostream &oStream)
const
93 std::stringstream sStream;
121 template <
typename TmplFitTraits>
123 std::ostream &oStream,
127 fitter.
write(oStream);
131 template <
typename TmplFitTraits>
132 class MoveToSurfaceFitter :
public SphereFitter<TmplFitTraits>
151 const Vec3 centreDiff = movable.getPos() - stationary.getPos();
152 const double centreDist = centreDiff.
norm();
153 if (centreDist > 0.0) {
154 const Vec3 newCentrePos =
157 (centreDiff/(centreDist))*(stationary.getRad() + movable.getRad());
158 moved.moveTo(newCentrePos);
171 if (neighbours.size() > 0) {
173 (particle.getPos() - neighbours[0]->getPos()).norm()
175 (particle.getRad() + neighbours[0]->getRad())
183 }
else if (newParticle.isValid()) {
190 template <
typename TmplFitTraits>
215 if (particleVector.size() > 3) {
216 const bool foundFit =
218 particleVector[0]->getPos(),
219 particleVector[1]->getPos(),
220 particleVector[2]->getPos(),
221 particleVector[3]->getPos(),
222 particleVector[0]->getRad(),
223 particleVector[1]->getRad(),
224 particleVector[2]->getRad(),
225 particleVector[3]->getRad(),
230 fittedParticle =
Particle(M, r,
id);
233 throw std::runtime_error(
"findAFit: particleVector argument has fewer than 4 elements.");
235 return fittedParticle;
246 if(neighbours.size() > 3){
247 const Particle &Pi = *(neighbours[0]);
248 const double ndist=(particle.getPos()-Pi.getPos()).norm();
250 newParticle = particle;
251 if (ndist < Pi.getRad()){
253 Pi.getPos()+((particle.getPos()-Pi.getPos())*(Pi.getRad()/ndist))
256 const double dist_p = plane.sep(newParticle.getPos());
257 const double dist_3 = (newParticle.getPos()-neighbours[3]->getPos()).norm()-neighbours[3]->getRad();
258 if (dist_p > dist_3) {
259 newParticle =
findAFit(newParticle, neighbours);
269 }
else if (newParticle.isValid()) {
276 template <
typename TmplFitTraits>
301 if (particleVector.size() > 2) {
302 const bool foundFit =
304 particleVector[0]->getPos(),
305 particleVector[1]->getPos(),
306 particleVector[2]->getPos(),
307 particleVector[0]->getRad(),
308 particleVector[1]->getRad(),
309 particleVector[2]->getRad(),
314 fittedParticle =
Particle(M, r,
id);
317 throw std::runtime_error(
"findAFit: particleVector argument has fewer than 3 elements.");
319 return fittedParticle;
330 if(neighbours.size() > 2){
331 const Particle &Pi = *(neighbours[0]);
332 const double ndist=(particle.getPos()-Pi.getPos()).norm();
334 newParticle = particle;
335 if (ndist < Pi.getRad()){
337 Pi.getPos()+((particle.getPos()-Pi.getPos())*(Pi.getRad()/ndist))
340 const double dist_p = plane.sep(newParticle.getPos());
341 const double dist_2 = (newParticle.getPos()-neighbours[2]->getPos()).norm()-neighbours[2]->getRad();
342 if (dist_p > dist_2) {
343 newParticle =
findAFit(newParticle, neighbours);
353 }
else if (newParticle.isValid()) {
360 template <
typename TmplFitTraits>
374 :
Inherited(
" 2D Sph Fitter", validator),
389 if (particleVector.size() >= 2) {
390 const bool foundFit =
393 particleVector[0]->getPos(),
394 particleVector[1]->getPos(),
396 particleVector[0]->getRad(),
397 particleVector[1]->getRad(),
402 fittedParticle =
Particle(M, r,
id);
405 throw std::runtime_error(
406 "TwoDSphereSphereFitter::findAFit: particleVector "
407 "argument has fewer than 2 elements."
410 return fittedParticle;
421 if (neighbours.size() >= 2) {
422 const Particle &Pi = *(neighbours[0]);
423 const double ndist=(particle.getPos()-Pi.getPos()).norm();
428 (neighbours.size() == 2)
433 (particle.getPos()-neighbours[2]->getPos()).norm()-neighbours[2]->getRad()
437 newParticle = particle;
438 if (ndist < Pi.getRad()) {
440 Pi.getPos() + ((particle.getPos() - Pi.getPos()) * (Pi.getRad()/ndist))
443 newParticle =
findAFit(newParticle, neighbours);
449 }
else if (newParticle.isValid()) {
459 template <
typename TmplFitTraits>
473 :
Inherited(
" 3D Sph Fitter", validator),
488 if (particleVector.size() > 2) {
489 const bool foundFit =
492 particleVector[0]->getPos(),
493 particleVector[1]->getPos(),
494 particleVector[2]->getPos(),
496 particleVector[0]->getRad(),
497 particleVector[1]->getRad(),
498 particleVector[2]->getRad(),
503 fittedParticle =
Particle(M, r,
id);
508 "ThreeDSphereSphereFitter::findAFit: particleVector argument"
509 " has fewer than 3 elements."
512 return fittedParticle;
523 if (neighbours.size() >= 3) {
524 const Particle &Pi = *(neighbours[0]);
525 const double ndist=(particle.getPos()-Pi.getPos()).norm();
530 (neighbours.size() == 3)
535 (particle.getPos()-neighbours[3]->getPos()).norm()-neighbours[3]->getRad()
539 newParticle = particle;
540 if (ndist < Pi.getRad()) {
542 Pi.getPos() + ((particle.getPos() - Pi.getPos()) * (Pi.getRad()/ndist))
545 newParticle =
findAFit(newParticle, neighbours);
551 }
else if (newParticle.isValid()) {
561 template <
typename TmplFitTraits>
585 const int id = particle.getID();
587 if (particleVector.size() > 1) {
588 const bool foundFit =
590 particleVector[0]->getPos(),
591 particleVector[1]->getPos(),
594 particleVector[0]->getRad(),
595 particleVector[1]->getRad(),
600 fittedParticle =
Particle(M, r,
id);
603 throw std::runtime_error(
"findAFit: particleVector vector contains less than 2 particles.");
606 return fittedParticle;
617 if (neighbours.size() >= 2) {
618 const Particle &Pi = *(neighbours[0]);
619 const double ndist=(particle.getPos()-Pi.getPos()).norm();
624 (neighbours.size() == 2)
627 plane.sep(particle.getPos())
629 (particle.getPos()-neighbours[2]->getPos()).norm()-neighbours[2]->getRad()
633 newParticle = particle;
634 if (ndist < Pi.getRad()) {
636 Pi.getPos() + ((particle.getPos() - Pi.getPos()) * (Pi.getRad()/ndist))
639 newParticle =
findAFit(newParticle, neighbours, plane);
645 }
else if (newParticle.isValid()) {
652 template <
typename TmplFitTraits>
676 const int id = particle.getID();
678 if (particleVector.size() > 2) {
679 const bool foundFit =
681 particleVector[0]->getPos(),
682 particleVector[1]->getPos(),
683 particleVector[2]->getPos(),
686 particleVector[0]->getRad(),
687 particleVector[1]->getRad(),
688 particleVector[2]->getRad(),
693 fittedParticle =
Particle(M, r,
id);
696 throw std::runtime_error(
"findAFit: particleVector vector contains less than 3 particles.");
699 return fittedParticle;
710 if (neighbours.size() >= 3) {
711 const Particle &Pi = *(neighbours[0]);
712 const double ndist=(particle.getPos()-Pi.getPos()).norm();
717 (neighbours.size() == 3)
720 plane.sep(particle.getPos())
722 (particle.getPos()-neighbours[3]->getPos()).norm()-neighbours[3]->getRad()
726 newParticle = particle;
727 if (ndist < Pi.getRad()) {
729 Pi.getPos() + ((particle.getPos() - Pi.getPos()) * (Pi.getRad()/ndist))
732 newParticle =
findAFit(newParticle, neighbours, plane);
738 }
else if (newParticle.isValid()) {