2013-06-27 3 views
0

Я пытаюсь написать функцию «применить градиент», которая берет кучу точек и линейный градиент и вычисляет цвет для каждой точки. У меня есть что-то вроде этого (данный массив points и градиент определяется двумя точками start и end):Вычислить цвета для точек вдоль произвольного градиента

struct Colour { 
    float red; float green; float blue; 
}; 

struct Point { 
    int x; int y; 
    Colour colour; 
}; 

Point points[total_points] = { ... };  
Point start = { ... }; 
Point end = { ... }; 

for (int i=0; i<total_points; i++) { 

    // Get normalised position along x and y 

    float scale_x = end.x-start.x; 
    float pos_x = (scale_x == 0) ? 0 : (points[i].x-start.x)/scale_x; 

    float scale_y = end.y-start.y; 
    float pos_y = (scale_y == 0) ? 0 : (points[i].y-start.y)/scale_y; 

    // Average the positions   
    float pos = .5 * (pos_x + pos_y); 

    // Blend colours 
    points[i].colour = blend_colour(start.colour, end.colour, pos); 

} 

Моя функция смешения цветов что-то простое, как это:

static Colour blend_colour(Colour start, Colour end, float position) { 

    Colour blend; 

    blend.red = (start.red * (1-position)) + (end.red * position); 
    blend.green = (start.green * (1-position)) + (end.green * position); 
    blend.blue = (start.blue * (1-position)) + (end.blue * position); 

    return blend; 

} 

Мои математики в цикл for определенно не совсем прав - мне нужно рассчитать цвет, используя тригонометрию?

+1

Вы ищете [линейная интерполяция] (http://en.wikpedia.org/wiki/Linear_interpolation)? –

ответ

2

Вместо

// Average the positions   
float pos = .5 * (pos_x + pos_y); 

Попробуйте

// Get scaled distance to point by calculating hypotenuse 
float dist = sqrt(pos_x*pos_x + pos_y*pos_y); 

Кроме того, в то время как компилятор сделает это за вас, вы должны поднять свои масштабные коэффициенты из петли. На самом деле, было бы лучше, чтобы вычислить коэффициент масштабирования для расстояния:

Point start = { ... }; 
Point end = { ... }; 

float xdelta = end.x - start.x; 
float ydelta = end.y - start.y; 
float hypot = sqrt(xdelta*xdelta + ydelta*ydelta); 

for (int i=0; i<total_points; i++) { 

    // Get normalised distance to points[i] 

    xdelta = points[i].x - start.x; 
    ydelta = points[i].y - start.y; 
    float dist = sqrt(xdelta*xdelta + ydelta*ydelta); 
    if (hypot) dist /= hypot; 

    // Blend colours 
    points[i].colour = blend_colour(start.colour, end.colour, dist); 
} 
+0

Спасибо, это было именно это и хороший момент, чтобы переупорядочить вычисления. Я все еще не совсем правильно рисовал рисунок, но это связано с макетом точек моей фигуры и тем, как OpenGL смешивает вершины. –

+0

Сделано еще несколько тестов - как есть, это на самом деле дает мне радиальный градиент. –

+0

Извините, это правда. Итак, что ваш исходный код дал вам? –

Смежные вопросы