Commit 6476cdb3 authored by Hans-Christian Ebke's avatar Hans-Christian Ebke
Browse files

Added ACG::ColorGenerator.

git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@12517 383ad7c9-94d9-4d36-a494-682f7c89f535
parent 43afa3d3
/*
* ColorGenerator.cc
*
* Created on: Sep 28, 2011
* Author: Hans-Christian Ebke
*/
#include "ColorGenerator.hh"
#include <cmath>
#include <qcolor.h>
namespace ACG {
const float ColorGenerator::defaultSaturation_ = 1.0f;
const float ColorGenerator::defaultValue_ = 1.0f;
ColorGenerator::ColorGenerator(float _alpha, float _baseHue) :
currentSubdiv_(2), currentIt_(0), currentTriadIt_(0),
alpha_(_alpha), baseHue_(_baseHue) {
}
static inline float wrap01(float v) {
float dummy;
if (v > 1.0f) v = modff(v, &dummy);
if (v < 0.0f) v = 1.0f - modff(v, &dummy);
return v;
}
Vec4f ColorGenerator::generateNextColor() {
const float resultHue =
baseHue_
+ .33333333f / currentSubdiv_ * currentIt_
+ .33333333f * currentTriadIt_;
// Convert color to RGB and store result.
double r, g, b, a;
QColor::fromHsvF(wrap01(resultHue), defaultSaturation_, defaultValue_, alpha_).getRgbF(
&r, &g, &b, &a);
const Vec4f result(r, g, b, alpha_);
/*
* Increment the three level iterator state.
*/
// Level 1: Increment triad it.
if (++currentTriadIt_ <= 2)
return result;
// Level 2: Increment subdiv it.
currentTriadIt_ = 0;
// Starting from the second subdivison, only visit odd numbers.
currentIt_ += (currentSubdiv_ == 2 ? 1 : 2);
if (currentIt_ < currentSubdiv_)
return result;
// Level 3: Increment subdivision level.
currentIt_ = 1;
currentSubdiv_ *= 2;
return result;
}
} /* namespace ACG */
/*
* ColorGenerator.hh
*
* Created on: Sep 28, 2011
* Author: Hans-Christian Ebke
*/
#ifndef COLORGENERATOR_HH_
#define COLORGENERATOR_HH_
#include <ACG/Math/VectorT.hh>
namespace ACG {
/**
* The ColorGenerator tries to generate a set of well distinguishable
* and esthetically somewhat pleasing colors.
*
* Note that it intentionally behaves totally deterministic. (Because
* reproducibility rocks.)
*/
class ColorGenerator {
public:
/**
* Constructor
*
* @param _alpha The alpha value for all the colors.
*
* @param _baseHue The HSV-hue from which to start. This is the
* hue of the first requested color. Default is an utterly
* delighting shade of blue awesomeness.
*/
ColorGenerator(
float _alpha = 1.0f,
float _baseHue = 0.5694f);
/**
* @return A new color.
*/
Vec4f generateNextColor();
/**
* Put a bunch of colors into the output iterator.
*
* Generates the same colors as if calling
* generateNextColor() n times.
*
* Typically, you would use std::back_inserter(container) as
* the argument for oit.
*
* @param n How many colors to generate.
* @param oit An output iterator. Should support "*oit++ = <Vec4f>;".
*/
template <class OUTPUT_ITERATOR>
void generateNextNColors(int n, OUTPUT_ITERATOR oit) {
for (int i = 0; i < n; ++i)
*oit++ = generateNextColor();
}
/**
* Convenience method if you just need a bunch of
* colors and don't need to instantiate a ColorGenerator.
*
* See description of generateNextNColors() for details.
*/
template <class OUTPUT_ITERATOR>
static void generateNColors(int n, OUTPUT_ITERATOR oit) {
ColorGenerator cg;
cg.generateNextNColors(n, oit);
}
private:
int currentSubdiv_;
int currentIt_;
int currentTriadIt_;
float alpha_;
float baseHue_;
static const float defaultSaturation_, defaultValue_;
};
} /* namespace ACG */
#endif /* COLORGENERATOR_HH_ */
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment