Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members

Color4f.h

Go to the documentation of this file.
00001 //------------------------------------------------------------------------------
00002 // Lamp : Open source game middleware
00003 // Copyright (C) 2004  Junpei Ohtani ( Email : junpee@users.sourceforge.jp )
00004 //
00005 // This library is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU Lesser General Public
00007 // License as published by the Free Software Foundation; either
00008 // version 2.1 of the License, or (at your option) any later version.
00009 //
00010 // This library is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 // Lesser General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU Lesser General Public
00016 // License along with this library; if not, write to the Free Software
00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018 //------------------------------------------------------------------------------
00019 
00020 /** @file
00021  * 四要素実数カラーヘッダ
00022  * @author Junpee
00023  */
00024 
00025 #ifndef COLOR_4F_H_
00026 #define COLOR_4F_H_
00027 
00028 #include <Core/System/Math.h>
00029 
00030 namespace Lamp{
00031 
00032 class Color3c;
00033 class Color4c;
00034 class Color3f;
00035 
00036 //------------------------------------------------------------------------------
00037 /**
00038  * 四要素実数カラー
00039  *
00040  * このクラスは継承しないで下さい。
00041  */
00042 class Color4f{
00043 public:
00044     //--------------------------------------------------------------------------
00045     // メンバ変数
00046     //--------------------------------------------------------------------------
00047     /// メンバ変数
00048     union{
00049         /// 各要素
00050         struct{
00051             /// 赤
00052             float r;
00053             /// 緑
00054             float g;
00055             /// 青
00056             float b;
00057             /// アルファ
00058             float a;
00059         };
00060 
00061         /// 各要素
00062         struct{
00063             /// 色相
00064             float h;
00065             /// 彩度
00066             float s;
00067             /// 明度
00068             float v;
00069             /// アルファ
00070             float a;
00071         };
00072 
00073         /// 配列
00074         float array[4];
00075     };
00076 
00077     //--------------------------------------------------------------------------
00078     // 定数
00079     //--------------------------------------------------------------------------
00080     /// 白
00081     static const Color4f white;
00082 
00083     /// 灰色
00084     static const Color4f gray;
00085 
00086     /// 黒
00087     static const Color4f black;
00088 
00089     /// 赤
00090     static const Color4f red;
00091 
00092     /// 緑
00093     static const Color4f green;
00094 
00095     /// 青
00096     static const Color4f blue;
00097 
00098     /// 黄
00099     static const Color4f yellow;
00100 
00101     /// 青緑
00102     static const Color4f cyan;
00103 
00104     /// 赤紫
00105     static const Color4f magenta;
00106 
00107     //--------------------------------------------------------------------------
00108     // コンストラクタ
00109     //--------------------------------------------------------------------------
00110     /**
00111      * コンストラクタ
00112      *
00113      * このコンストラクタは初期値の設定を行わないため値は不定です。
00114      */
00115     Color4f(){}
00116 
00117     /**
00118      * コンストラクタ
00119      * @param sourceR 赤の初期値
00120      * @param sourceG 緑の初期値
00121      * @param sourceB 青の初期値
00122      * @param sourceA アルファの初期値
00123      */
00124     inline Color4f(float sourceR, float sourceG, float sourceB,
00125         float sourceA = 1.f) :
00126         r(sourceR), g(sourceG), b(sourceB), a(sourceA){
00127     }
00128 
00129     /**
00130      * コンストラクタ
00131      * @param source 設定する色
00132      */
00133     explicit Color4f(const Color3c& source);
00134 
00135     /**
00136      * コンストラクタ
00137      * @param source 設定する色
00138      */
00139     explicit Color4f(const Color4c& source);
00140 
00141     /**
00142      * コンストラクタ
00143      * @param source 設定する色
00144      */
00145     explicit Color4f(const Color3f& source);
00146 
00147     //--------------------------------------------------------------------------
00148     // 値の設定
00149     //--------------------------------------------------------------------------
00150     /**
00151      * 値の設定
00152      * @param sourceR 赤の設定値
00153      * @param sourceG 緑の設定値
00154      * @param sourceB 青の設定値
00155      * @param sourceA アルファの設定値
00156      */
00157     inline void set(float sourceR, float sourceG, float sourceB,
00158         float sourceA = 1.f){
00159         r = sourceR;
00160         g = sourceG;
00161         b = sourceB;
00162         a = sourceA;
00163     }
00164 
00165     /**
00166      * 三要素キャラクタカラーの設定
00167      * @param source 設定する色
00168      */
00169     void set(const Color3c& source);
00170 
00171     /**
00172      * 四要素キャラクタカラーの設定
00173      * @param source 設定する色
00174      */
00175     void set(const Color4c& source);
00176 
00177     /**
00178      * 三要素実数カラーの設定
00179      * @param source 設定する色
00180      */
00181     void set(const Color3f& source);
00182 
00183     //--------------------------------------------------------------------------
00184     // 演算
00185     //--------------------------------------------------------------------------
00186     /**
00187      * 加算
00188      * @param addColor 加算する色
00189      * @return 加算された色
00190      */
00191     inline Color4f operator +(const Color4f& addColor) const{
00192         return Color4f(
00193             r + addColor.r, g + addColor.g, b + addColor.b, a + addColor.a);
00194     }
00195 
00196     /**
00197      * 減算
00198      * @param subColor 減算する色
00199      * @return 減算された色
00200      */
00201     inline Color4f operator -(const Color4f& subColor) const{
00202         return Color4f(
00203             r - subColor.r, g - subColor.g, b - subColor.b, a - subColor.a);
00204     }
00205 
00206     /**
00207      * 乗算
00208      * @param mulColor 乗算する色
00209      * @return 乗算された色
00210      */
00211     inline Color4f operator *(const Color4f& mulColor) const{
00212         return Color4f(
00213             r * mulColor.r, g * mulColor.g, b * mulColor.b, a * mulColor.a);
00214     }
00215 
00216     /**
00217      * 乗算
00218      * @param mulValue 乗算する値
00219      * @return 乗算された色
00220      */
00221     inline Color4f operator *(float mulValue) const{
00222         return Color4f(
00223             r * mulValue, g * mulValue, b * mulValue, a * mulValue);
00224     }
00225 
00226     /**
00227      * 乗算
00228      * @param mulValue 乗算する値
00229      * @param mulColor 乗算される色
00230      * @return 乗算された色
00231      */
00232     inline friend Color4f operator *(float mulValue, const Color4f& mulColor){
00233         return Color4f(
00234             mulColor.r * mulValue, mulColor.g * mulValue,
00235             mulColor.b * mulValue, mulColor.a * mulValue);
00236     }
00237 
00238     /**
00239      * +演算子
00240      * @return 色のコピー
00241      */
00242     inline Color4f operator +() const{ return *this; }
00243 
00244     /**
00245      * -演算子
00246      * @return 値の符号が反転した色
00247      */
00248     inline Color4f operator -() const{ return Color4f(-r, -g, -b, -a); }
00249 
00250     //--------------------------------------------------------------------------
00251     // 代入演算
00252     //--------------------------------------------------------------------------
00253     /**
00254      * 代入加算
00255      * @param addColor 加算する色
00256      * @return 加算された色
00257      */
00258     inline Color4f& operator +=(const Color4f& addColor){
00259         r += addColor.r;
00260         g += addColor.g;
00261         b += addColor.b;
00262         a += addColor.a;
00263         return (*this);
00264     }
00265 
00266     /**
00267      * 代入減算
00268      * @param subColor 減算する色
00269      * @return 減算された色
00270      */
00271     inline Color4f& operator -=(const Color4f& subColor){
00272         r -= subColor.r;
00273         g -= subColor.g;
00274         b -= subColor.b;
00275         a -= subColor.a;
00276         return (*this);
00277     }
00278 
00279     /**
00280      * 代入乗算
00281      * @param mulColor 乗算する色
00282      * @return 乗算された色
00283      */
00284     inline Color4f& operator *=(const Color4f& mulColor){
00285         r *= mulColor.r;
00286         g *= mulColor.g;
00287         b *= mulColor.b;
00288         a *= mulColor.a;
00289         return (*this);
00290     }
00291 
00292     /**
00293      * 代入乗算
00294      * @param mulValue 乗算する値
00295      * @return 乗算された色
00296      */
00297     inline Color4f& operator *=(float mulValue){
00298         r *= mulValue;
00299         g *= mulValue;
00300         b *= mulValue;
00301         a *= mulValue;
00302         return (*this);
00303     }
00304 
00305     //--------------------------------------------------------------------------
00306     // 色演算
00307     //--------------------------------------------------------------------------
00308     /**
00309      * クランプ
00310      * @param lower クランプ下限値
00311      * @param upper クランプ上限値
00312      * @return クランプされた色
00313      */
00314     inline Color4f& clamp(float lower = 0.f, float upper = 1.f){
00315         Assert(upper > lower);
00316         if(r > upper){ r = upper; }
00317         else if(r < lower){ r = lower; }
00318         if(g > upper){ g = upper; }
00319         else if(g < lower){ g = lower; }
00320         if(b > upper){ b = upper; }
00321         else if(b < lower){ b = lower; }
00322         if(a > upper){ a = upper; }
00323         else if(a < lower){ a = lower; }
00324         return (*this);
00325     }
00326 
00327     /**
00328      * 下限クランプ
00329      * @param lower クランプ下限値
00330      * @return クランプされた色
00331      */
00332     inline Color4f& lowerClamp(float lower = 0.f){
00333         if(r < lower){ r = lower; }
00334         if(g < lower){ g = lower; }
00335         if(b < lower){ b = lower; }
00336         if(a < lower){ a = lower; }
00337         return (*this);
00338     }
00339 
00340     /**
00341      * 上限クランプ
00342      * @param upper クランプ上限値
00343      * @return クランプされた色
00344      */
00345     inline Color4f& upperClamp(float upper = 1.f){
00346         if(r > upper){ r = upper; }
00347         if(g > upper){ g = upper; }
00348         if(b > upper){ b = upper; }
00349         if(a > upper){ a = upper; }
00350         return (*this);
00351     }
00352 
00353     /**
00354      * 反対色
00355      *
00356      * アルファ値は変化しません。
00357      * @return 反転された色
00358      */
00359     inline Color4f& negative(){
00360         set(1.f - r, 1.f - g, 1.f - b, a);
00361         return (*this);
00362     }
00363 
00364     //--------------------------------------------------------------------------
00365     /**
00366      * HSVの設定
00367      * @param hsv HSVカラー
00368      */
00369     inline void setHSV(const Color4f& hsv){
00370         float alpha = hsv.a;
00371         float value = hsv.v;
00372         if(hsv.s <= Math::epsilon){
00373             set(value, value, value, alpha);
00374             return;
00375         }
00376         float hue = hsv.h * 6.f;
00377         float integer = Math::floor(hue);
00378         float decimal = hue - integer;
00379         float temp0 = value * (1.f - hsv.s);
00380         float temp1 = value * (1.f - (hsv.s * decimal));
00381         float temp2 = value * (1.f - (hsv.s * (1.f - decimal)));
00382         if(integer < 1.f){
00383             set(value, temp2, temp0, alpha);
00384         }else if(integer < 2.f){
00385             set(temp1, value, temp0, alpha);
00386         }else if(integer < 3.f){
00387             set(temp0, value, temp2, alpha);
00388         }else if(integer < 4.f){
00389             set(temp0, temp1, value, alpha);
00390         }else if(integer < 5.f){
00391             set(temp2, temp0, value, alpha);
00392         }else{
00393             set(value, temp0, temp1, alpha);
00394         }
00395     }
00396 
00397     /**
00398      * HSVの取得
00399      * @return HSVカラー
00400      */
00401     inline Color4f getHSV() const{
00402         Color4f hsv;
00403         hsv.a = a;
00404         // 明度の算出
00405         float maximum = Math::maximum(r, Math::maximum(g, b));
00406         hsv.v = maximum;
00407         // 彩度の算出
00408         float minimum = Math::minimum(r, Math::minimum(g, b));
00409         float chroma = maximum - minimum;
00410         if(maximum <= Math::epsilon){
00411             hsv.s = 0.f;
00412             hsv.h = 0.f;
00413             return hsv;
00414         }else{
00415             hsv.s = chroma / maximum;
00416         }
00417         if(chroma <= Math::epsilon){
00418             hsv.h = 0.f;
00419             return hsv;
00420         }
00421         float hueScale = (1 / chroma) * 0.1666667f;
00422         if(r == maximum){
00423             hsv.h = (g - b) * hueScale;
00424         }else if(g == maximum){
00425             hsv.h = (b - r) * hueScale + 0.3333333f;
00426         }else{
00427             hsv.h = (r - g) * hueScale + 0.6666667f;
00428         }
00429         if(hsv.h < 0.f){ hsv.h += 1.f; }
00430         return hsv;
00431     }
00432 
00433     //--------------------------------------------------------------------------
00434     /**
00435      * 色相の取得
00436      * @return 色相
00437      */
00438     inline float getHue() const{
00439         float maximum = Math::maximum(r, Math::maximum(g, b));
00440         if(maximum <= Math::epsilon){ return 0.f; }
00441         float minimum = Math::minimum(r, Math::minimum(g, b));
00442         float chroma = maximum - minimum;
00443         if(chroma <= Math::epsilon){ return 0.f; }
00444         float hueScale = (1 / chroma) * 0.16666667f;
00445         float hue;
00446         if(r == maximum){
00447             hue = (g - b) * hueScale;
00448         }else if(g == maximum){
00449             hue = (b - r) * hueScale + 0.33333333f;
00450         }else{
00451             hue = (r - g) * hueScale + 0.66666667f;
00452         }
00453         if(hue < 0.f){ hue += 1.f; }
00454     }
00455 
00456     /**
00457      * 彩度の取得
00458      * @return 彩度
00459      */
00460     inline float getSaturation() const{
00461         float maximum = Math::maximum(r, Math::maximum(g, b));
00462         if(maximum <= Math::epsilon){ return 0.f; }
00463         float minimum = Math::minimum(r, Math::minimum(g, b));
00464         float chroma = maximum - minimum;
00465         return chroma / maximum;
00466     }
00467 
00468     /**
00469      * 明度の取得
00470      * @return 明度
00471      */
00472     inline float getValue() const{
00473         return Math::maximum(r, Math::maximum(g, b));
00474     }
00475 
00476     /**
00477      * 輝度の取得
00478      * @return 輝度
00479      */
00480     inline float getLuminance() const{
00481         return (r * 0.298912f + g * 0.586611f + b * 0.114477f);
00482     }
00483 
00484     //--------------------------------------------------------------------------
00485     /**
00486      * 色の線形補間
00487      * @param source 開始色
00488      * @param target 対象色
00489      * @param alpha ブレンド係数
00490      * @return 線形補間された色
00491      */
00492     inline static Color4f lerp(
00493         const Color4f& source, const Color4f& target, float alpha){
00494         float beta = 1.f - alpha;
00495         Color4f result;
00496         result.r = source.r * beta + target.r * alpha;
00497         result.g = source.g * beta + target.g * alpha;
00498         result.b = source.b * beta + target.b * alpha;
00499         result.a = source.a * beta + target.a * alpha;
00500         return result;
00501     }
00502 
00503     //--------------------------------------------------------------------------
00504     // 論理演算
00505     //--------------------------------------------------------------------------
00506     /**
00507      * 同じ値かどうか
00508      * @param target 比較するカラー
00509      * @return 同じ値であればtrueを返す
00510      */
00511     inline bool operator ==(const Color4f& target) const{
00512         return ((r == target.r) && (g == target.g) &&
00513             (b == target.b) && (a == target.a));
00514     }
00515 
00516     /**
00517      * 同じ値かどうか
00518      * @param target 比較するカラー
00519      * @param epsilon 誤差
00520      * @return 誤差の範囲内で同じ値であればtrueを返す
00521      */
00522     inline bool epsilonEquals(const Color4f& target, float epsilon) const{
00523         Assert(epsilon >= 0.f);
00524         return (
00525             (Math::abs(r - target.r) <= epsilon) &&
00526             (Math::abs(g - target.g) <= epsilon) &&
00527             (Math::abs(b - target.b) <= epsilon) &&
00528             (Math::abs(a - target.a) <= epsilon));
00529     }
00530 
00531     /**
00532      * 同じ値でないかどうか
00533      * @param target 比較するカラー
00534      * @return 同じ値でなければtrueを返す
00535      */
00536     inline bool operator !=(const Color4f& target) const{
00537         return ((r != target.r) || (g != target.g) ||
00538             (b != target.b) || (a != target.a));
00539     }
00540 
00541     /**
00542      * 同じ値でないかどうか
00543      * @param target 比較するカラー
00544      * @param epsilon 誤差
00545      * @return 誤差の範囲内で同じでない値であればtrueを返す
00546      */
00547     inline bool notEpsilonEquals(const Color4f& target, float epsilon) const{
00548         Assert(epsilon >= 0.f);
00549         return (
00550             (Math::abs(r - target.r) > epsilon) ||
00551             (Math::abs(g - target.g) > epsilon) ||
00552             (Math::abs(b - target.b) > epsilon) ||
00553             (Math::abs(a - target.a) > epsilon));
00554     }
00555 
00556     //--------------------------------------------------------------------------
00557     // その他
00558     //--------------------------------------------------------------------------
00559     /**
00560      * 文字列化
00561      * @return カラーの文字列表記
00562      */
00563     inline String toString() const{
00564         String returnString;
00565         returnString.format("( %.8f, %.8f, %.8f, %.8f )", r, g, b, a);
00566         return returnString;
00567     }
00568 
00569     //--------------------------------------------------------------------------
00570 private:
00571 
00572 };
00573 
00574 //------------------------------------------------------------------------------
00575 } // End of namespace Lamp
00576 #endif // End of COLOR_4F_H_
00577 //------------------------------------------------------------------------------

Generated on Wed Mar 16 10:29:29 2005 for Lamp by doxygen 1.3.2