Calculate colours for points along an arbitrary gradient
I'm trying to write an 'apply gradient' function, which takes a bunch of points and a linear gradient and calculates the colour for each point. I have something like this (given an array of points
and a gradient defined by two points start
and 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);
}
My colour blending function is something simple like this:
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;
}
My maths in the for loop is definitely not quite right — do I need to calculate the colour using trigonometry?
Instead of
// Average the positions
float pos = .5 * (pos_x + pos_y);
Try
// Get scaled distance to point by calculating hypotenuse
float dist = sqrt(pos_x*pos_x + pos_y*pos_y);
Also, while the compiler will do it for you, you ought to hoist your scale factors out of the loop. In fact, it might be better to calculate the scale factor for the distance:
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);
}
链接地址: http://www.djcxy.com/p/71076.html
上一篇: Swift:沿着贝塞尔路径渐变(使用CALayers)
下一篇: 计算沿任意渐变的点的颜色