|
|
|
|
|
|
|
#ifndef UNRAVELHEART3D_HPP
|
|
|
|
#define UNRAVELHEART3D_HPP
|
|
|
|
|
|
|
|
#include "../AttractorKernel.hpp"
|
|
|
|
|
|
|
|
#include <cmath>
|
|
|
|
|
|
|
|
class UnravelHeart3D : public AttractorKernel {
|
|
|
|
public:
|
|
|
|
UnravelHeart3D():
|
|
|
|
AttractorKernel(3, 8) {}
|
|
|
|
|
|
|
|
virtual std::string type() const { return "unravel heart"; };
|
|
|
|
|
|
|
|
virtual void operator()() {
|
|
|
|
std::swap(vectorNew, vectorOld);
|
|
|
|
|
|
|
|
vectorNew[0] = parameters[0]*(vectorOld[2] + parameters[1]);
|
|
|
|
vectorNew[1] = parameters[2]*(vectorOld[0] + parameters[3]);
|
|
|
|
vectorNew[2] = parameters[4]*(vectorOld[1] + parameters[5]);
|
|
|
|
|
|
|
|
const double x = vectorNew[0];
|
|
|
|
const double y = vectorNew[1];
|
|
|
|
const double z = vectorNew[2];
|
|
|
|
const double dist = x*x + y*y + 2.0*z*z - 1.0;//parameters[7];
|
|
|
|
const double lh = dist*dist*dist;
|
|
|
|
const double rh = parameters[6]*x*x*y*y*y;
|
|
|
|
|
|
|
|
if(lh > rh) {
|
|
|
|
const double sqrtDist = std::pow(std::abs(lh), 1.0/6.0);
|
|
|
|
const double sqrtDist2 = std::pow(std::abs(rh), 1.0/6.0) * sign(parameters[6]);
|
|
|
|
const double p = 1.0 - sqrtDist2 * (static_cast<int>(sqrtDist / sqrtDist2) + 1.0) / sqrtDist;
|
|
|
|
vectorNew[0] *= p;
|
|
|
|
vectorNew[1] *= -p;
|
|
|
|
vectorNew[2] *= p;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
double sign(double x){
|
|
|
|
return (x > 0) - (x < 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif // UNRAVEL_HPP
|
|
|
|
|