#ifndef SHARED_CONTINUOUS_FUNCTION_CACHE_H #define SHARED_CONTINUOUS_FUNCTION_CACHE_H #include "../graph/graph/graph_view.h" #include #include #include namespace Shared { class ContinuousFunction; class ContinuousFunctionCache { public: static constexpr int k_numberOfAvailableCaches = 2; static void PrepareForCaching(void * fun, ContinuousFunctionCache * cache, float tMin, float tStep); ContinuousFunctionCache() { clear(); } float step() const { return m_tStep; } void clear(); Poincare::Coordinate2D valueForParameter(const ContinuousFunction * function, Poincare::Context * context, float t); // Sets step parameters for non-cartesian curves static void ComputeNonCartesianSteps(float * tStep, float * tCacheStep, float tMax, float tMin); private: /* The size of the cache is chosen to optimize the display of cartesian * functions */ static constexpr int k_sizeOfCache = Ion::Display::Width; /* We need a certain amount of tolerance since we try to evaluate the * equality of floats. But the value has to be chosen carefully. Too high of * a tolerance causes false positives, which lead to errors in curves * (ex : 1/x with a vertical line at 0). Too low of a tolerance causes false * negatives, which slows down the drawing. * * The value 128*FLT_EPSILON has been found to be the lowest for which all * indices verify indexForParameter(tMin + index * tStep) = index. */ static constexpr float k_cacheHitTolerance = 128.0f * FLT_EPSILON; void invalidateBetween(int iInf, int iSup); void setRange(ContinuousFunction * function, float tMin, float tStep); int indexForParameter(const ContinuousFunction * function, float t) const; Poincare::Coordinate2D valuesAtIndex(const ContinuousFunction * function, Poincare::Context * context, float t, int i); void pan(ContinuousFunction * function, float newTMin); float m_tMin, m_tStep; float m_cache[k_sizeOfCache]; /* m_startOfCache is used to implement a circular buffer for easy panning * with cartesian functions. When dealing with parametric or polar functions, * m_startOfCache should be zero.*/ int m_startOfCache; }; } #endif