我目前正在嘗試爲我的Mandelbrot Set瀏覽器創建顏色漸變類。線性顏色漸變不起作用
它從文本文件讀取顏色約束(RGBA8888
顏色和0到1之間的位置),並將它們添加到矢量中,該矢量稍後用於確定某個位置的顏色。
爲了計算顏色,算法從給定位置搜索下一個約束條件,將顏色分成四個單獨的通道,然後對每個通道搜索兩者中較低的一個,並添加一部分差值等於(x-lpos)/(upos-lpos)
與較低顏色的比率。之後,通道被移位並進行或運算,然後返回爲RGBA8888
的無符號整數。 (請參見下面的代碼)。
編輯:我完全重寫了梯度級,修復了一些問題,並使其成爲調試的緣故更具可讀性(它變得慢如地獄,雖然,但-Os
或多或少的需要照顧)。但是,它仍然不像它應該的那樣。
class Gradient { //remade, Some irrelevant methods and de-/constructors removed
private:
map<double, unsigned int> constraints;
public:
unsigned int operator[](double value) {
//Forbid out-of-range values, return black
if (value < 0 || value > 1+1E-10) return 0xff;
//Find upper and lower constraint
auto upperC = constraints.lower_bound(value);
if (upperC == constraints.end()) upperC = constraints.begin();
auto lowerC = upperC == constraints.begin() ? prev(constraints.end(), 1) : prev(upperC, 1);
if (value == lowerC->first) return lowerC->second;
double lpos = lowerC->first;
double upos = upperC->first;
if (upos < lpos) upos += 1;
//lower color channels
unsigned char lred = (lowerC->second >> 24) & 0xff;
unsigned char lgreen = (lowerC->second >> 16) & 0xff;
unsigned char lblue = (lowerC->second >> 8) & 0xff;
unsigned char lalpha = lowerC->second & 0xff;
//upper color channels
unsigned char ured = (upperC->second >> 24) & 0xff;
unsigned char ugreen = (upperC->second >> 16) & 0xff;
unsigned char ublue = (upperC->second >> 8) & 0xff;
unsigned char ualpha = upperC->second & 0xff;
unsigned char red = 0, green = 0, blue = 0, alpha = 0xff;
//Compute each channel using
// lower color + dist(lower, x)/dist(lower, upper) * diff(lower color, upper color)
if (lred < ured)
red = lred + (value - lpos)/(upos - lpos) * (ured - lred);
else red = ured + (upos - value)/(upos - lpos) * (ured - lred);
if (lgreen < ugreen)
green = lgreen + (value - lpos)/(upos - lpos) * (ugreen - green);
else green = ugreen + (upos - value)/(upos - lpos) * (ugreen - lgreen);
if (lblue < ublue)
blue = lblue + (value - lpos)/(upos - lpos) * (ublue - lblue);
else blue = ublue + (upos - value)/(upos - lpos) * (ublue - lblue);
if (lalpha < ualpha)
alpha = lalpha + (value - lpos)/(upos - lpos) * (ualpha - lalpha);
else alpha = ualpha + (upos - value)/(upos - lpos) * (ualpha - lalpha);
//Merge channels together and return
return (red << 24) | (green << 16) | (blue << 8) | alpha;
}
void addConstraint(unsigned int color, double position) {
constraints[position] = color;
}
};
使用的更新方法:
image[r + rres*i] = grd[ratio];
//With image being a vector<unsigned int>, which is then used as data source for a `SDL_Texture` using `SDL_UpdateTexture`
它只能部分地,雖然。當我只使用一個黑/白梯度,所得到的圖像作爲意圖:
梯度文件:
2
0 000000ff
1 ffffffff
然而,當我使用更加豐富多彩的梯度(的線性版本下面Ultra Fractal gradient,輸入文件),
圖像遠離預期的結果
圖像仍然不顯示所期望的着色:
梯度文件:
5
0 000764ff
.16 206bcbff
.42 edffffff
.6425 ffaa00ff
0.8575 000200ff
我在做什麼錯?我多次改寫了operator[]
方法,沒有任何改變。
對我的代碼的澄清或一般評論的問題是受歡迎的。
您確實應該將大量代碼從'operator []'中移出,並移入讀取約束的方法中。使用排序的'vector'而不是'map'來保存約束條件,並儘早將這些約束條件解析爲單獨的RGBA組件。 – Alnitak 2015-04-01 16:16:47
哦,如果你將你的RGBA組件存儲在它自己的類中,那麼你應該把這個基本數學運算方法放在這個類中的那些顏色上。 – Alnitak 2015-04-01 16:19:31
地圖爲什麼要成爲問題?實際上我之前使用過一個矢量,但隨後切換到了一張地圖,因爲地圖**中的值是按鍵升序排序的,這在初始化時給出了對數訪問時間。 – s3lph 2015-04-01 16:19:39