Last active
February 24, 2024 16:14
-
-
Save NickBeeuwsaert/6258245 to your computer and use it in GitHub Desktop.
Small C++ Gradient class
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "Gradient.h" | |
#include <vector> | |
Gradient::GradientColor::GradientColor(float _r, float _g, float _b, float _a):r(_r), g(_g), b(_b), a(_a) {} | |
Gradient::GradientColor::GradientColor():r(), g(0), b(0), a(0) {} | |
const Gradient::GradientColor & Gradient::GradientColor::operator+=(const GradientColor &lhs){ | |
r += lhs.r; | |
g += lhs.g; | |
b += lhs.b; | |
a += lhs.a; | |
return *this; | |
} | |
const Gradient::GradientColor & Gradient::GradientColor::operator-=(const GradientColor &lhs){ | |
r -= lhs.r; | |
g -= lhs.g; | |
b -= lhs.b; | |
a -= lhs.a; | |
return *this; | |
} | |
const Gradient::GradientColor & Gradient::GradientColor::operator*=(const float &lhs){ | |
r *= lhs; | |
g *= lhs; | |
b *= lhs; | |
a *= lhs; | |
return *this; | |
} | |
const Gradient::GradientColor Gradient::GradientColor::operator+(const GradientColor& lhs) const{ | |
GradientColor res = *this; | |
res += lhs; | |
return res; | |
} | |
const Gradient::GradientColor Gradient::GradientColor::operator-(const GradientColor& lhs) const { | |
GradientColor res = *this; | |
res -= lhs; | |
return res; | |
} | |
const Gradient::GradientColor Gradient::GradientColor::operator*(const float& lhs) const { | |
GradientColor res = *this; | |
res *= lhs; | |
return res; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef __GRADIENT_H__ | |
#define __GRADIENT_H__ | |
#include <vector> | |
#include <math.h> | |
namespace Gradient { | |
template<class T> | |
class GradientStop { | |
float t; | |
T value; | |
template <class Ta> | |
friend class Gradient; | |
public: | |
GradientStop(float _t, T _val):t(_t), value(_val){ | |
} | |
}; | |
template<class T> | |
T lerp(T s, T e, float t){ | |
return s + (e - s) * t; | |
} | |
template<class T> | |
T cerp(T a,T b,float x){ | |
float ft = x * M_PI; | |
float f = (1.0-cos(ft)) / 2.0; | |
return a * (1.0-f) + b*f; | |
} | |
class GradientColor { | |
public: | |
float r,g,b,a; | |
GradientColor(float, float, float, float); | |
GradientColor(); | |
const GradientColor & operator+=(const GradientColor &); | |
const GradientColor & operator-=(const GradientColor &); | |
const GradientColor & operator*=(const float &); | |
const GradientColor operator+(const GradientColor&) const; | |
const GradientColor operator-(const GradientColor&) const; | |
const GradientColor operator*(const float&) const; | |
}; | |
template<class T> | |
class Gradient { | |
std::vector<GradientStop<T>*> stops; | |
public: | |
void addColorStop(float t, T val){ | |
typename std::vector<GradientStop<T>*>::iterator it; | |
for(it = stops.begin(); it != stops.end(); it++){ | |
if((*it)->t > t)break; | |
} | |
stops.insert(it, new GradientStop<T>(t, val)); | |
} | |
T getColorAt(float t){ | |
typename std::vector<GradientStop<T>*>::iterator it; | |
GradientStop<T> *start, *stop; | |
for(it = stops.begin(); it != stops.end(); it++){ | |
stop = *it; | |
if(stop->t > t) | |
break; | |
} | |
if(it == stops.begin() || it == stops.end()) return stop->value; | |
start = *(--it); | |
float frac = (t - start->t) / (stop->t - start->t); | |
return lerp(start->value, stop->value, frac); | |
} | |
~Gradient(){ | |
for(typename std::vector<GradientStop<T>*>::iterator it = stops.begin(); it != stops.end(); it++){ | |
delete *it; | |
} | |
} | |
}; | |
} | |
#endif//__GRADIENT_H__ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Any chance for a usage example?