SO3Engine
SO3ColourGradient.cpp
Go to the documentation of this file.
1/*
2-----------------------------------------------------------------------------
3This source file is part of OpenSpace3D
4For the latest info, see http://www.openspace3d.com
5
6Copyright (c) 2012 I-maginer
7
8This program is free software; you can redistribute it and/or modify it under
9the terms of the GNU Lesser General Public License as published by the Free Software
10Foundation; either version 2 of the License, or (at your option) any later
11version.
12
13This program is distributed in the hope that it will be useful, but WITHOUT
14ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
16
17You should have received a copy of the GNU Lesser General Public License along with
18this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19Place - Suite 330, Boston, MA 02111-1307, USA, or go to
20http://www.gnu.org/copyleft/lesser.txt
21
22-----------------------------------------------------------------------------
23*/
24
26
27namespace SO3
28{
29
30 SColourGradient::SColourGradient(const bool& fillBoundsWithDefault) : fillBounds(fillBoundsWithDefault),
31 minBoundDefaultColour(Ogre::ColourValue::Black),
32 maxBoundDefaultColour(Ogre::ColourValue::White)
33 {
34 }
35
36 SColourGradient::SColourGradient(const Ogre::ColourValue& overridedMinDefaultColour, const Ogre::ColourValue& overridedMaxDefaultColour) : fillBounds(true),
37 minBoundDefaultColour(overridedMinDefaultColour),
38 maxBoundDefaultColour(overridedMaxDefaultColour)
39 {
40 }
41
45
46 const Ogre::ColourValue SColourGradient::GetColour(const float& gradientPos) const
47 {
48 // Check parameter
49 float gradientPosition = gradientPos;
50 if(gradientPos < 0.0f)
51 gradientPosition = 0.0f;
52 if(gradientPos > 1.0f)
53 gradientPosition = 1.0f;
54
55 // No colours in the gradient!
56 if (colourFrames.empty())
57 {
58 if(!fillBounds)
59 return Ogre::ColourValue::Black;
60 else
61 return Interpolate(ColourFrame(0.0f, minBoundDefaultColour), ColourFrame(1.0f, maxBoundDefaultColour), gradientPosition);
62 }
63
64 // If the requested colour is exactly on a colour frame position
65 ColourFrames::const_iterator iSearchedColourFrame = colourFrames.find(gradientPosition);
66 if(iSearchedColourFrame != colourFrames.end())
67 return iSearchedColourFrame->second;
68
69 // Only one colour
70 if (colourFrames.size() == 1)
71 {
72 if(!fillBounds)
73 {
74 // No bound filling, return the unique colour.
75 return colourFrames.begin()->second;
76 }
77 else
78 {
79 if(gradientPosition < colourFrames.begin()->first)
80 {
81 // Interpolate between default colour frame (0.0, Ogre::ColourValue::Black) and unique colour that is in the gradient.
82 return Interpolate(ColourFrame(0.0f, minBoundDefaultColour), *colourFrames.begin(), gradientPosition);
83 }
84 else
85 {
86 // Interpolate between the unique colour that is in the gradient and default colour frame (1.0, Ogre::ColourValue::White).
87 return Interpolate(*colourFrames.begin(), ColourFrame(1.0f, maxBoundDefaultColour), gradientPosition);
88 }
89 }
90 }
91
92 // Min colour value
93 ColourFrames::const_iterator iMinBound = colourFrames.lower_bound(gradientPosition);
94 if(iMinBound != colourFrames.begin())
95 iMinBound--;
96
97 // Max value
98 ColourFrames::const_iterator iMaxBound = colourFrames.upper_bound(gradientPosition);
99
100 // Handle the case where the requested value is below the smaller value in the gradient
101 if(gradientPosition < iMinBound->first)
102 {
103 if(!fillBounds)
104 {
105 // No bound filling, return the colour which is just above the searched value.
106 return iMinBound->second;
107 }
108 else
109 {
110 // Interpolate between default colour frame (0.0, Ogre::ColourValue::Black) and the colour just above the searched value.
111 return Interpolate(ColourFrame(0.0f, minBoundDefaultColour), *iMinBound, gradientPosition);
112 }
113 }
114
115 // Handle the case where the requested value is above the greater value in the gradient
116 if(iMaxBound == colourFrames.end())
117 {
118 iMaxBound--;
119 if(!fillBounds)
120 {
121 // No bound filling, return the colour which is just below the searched value.
122 return iMaxBound->second;
123 }
124 else
125 {
126 // Interpolate between the colour just below the searched value and the default colour frame (1.0, Ogre::ColourValue::White).
127 return Interpolate(*iMaxBound, ColourFrame(1.0f, maxBoundDefaultColour), gradientPosition);
128 }
129 }
130
131 // Normal case
132 return Interpolate(*iMinBound, *iMaxBound, gradientPosition);
133 }
134
135 Ogre::ColourValue SColourGradient::Interpolate(const ColourFrame& minColourFrame, const ColourFrame& maxColourFrame, const float& mediumRangeValue) const
136 {
137 float range = maxColourFrame.first - minColourFrame.first;
138 float rangePoint = (mediumRangeValue - minColourFrame.first) / range;
139 return ((minColourFrame.second * (1.0f - rangePoint)) + (maxColourFrame.second * rangePoint));
140 }
141
142}
SColourGradient(const bool &fillBoundsWithDefault=true)
ColourFrames::value_type ColourFrame
A single colour frame.
const Ogre::ColourValue GetColour(const float &gradientPosition) const