插值算法?

概述

如何给一条线均匀上色实现那种均匀变化的渐变效果?插值算法就是实现这个需求的一种算法。

图-1

定义

weight = d1/d; 这是权重的计算方式,表达了某个位置与起点之间的线段占据整个直线的多少;rt=r2·weight+(1-weight)·r1;其中rt就是某个位置的颜色取值,r2是直线终点的颜色值,r1是起点的颜色值;可以观察到,从起点到终点颜色值会逐渐接近终点颜色,这就是颜色渐变的效果。

图-2

计算

为了方便计算,计算权重weight可以通过纵坐标获取也可以通过横坐标获取,从图2可看出他们是全等的关系。

插值算法代码实现

void Raster::interpolantLine(const Point& v0, const Point& v1, Point& target) {
float weight = 1.0f;
if (v1.x != v0.x) {
//用x做比例
weight = (float)(target.x - v0.x) / (float)(v1.x - v0.x);
}else if (v1.y != v0.y) {
//用y做比例
weight = (float)(target.y - v0.y) / (float)(v1.y - v0.y);
}

RGBA result;
result.mR = static_cast<byte>(static_cast<float>(v1.color.mR) * weight + (1.0f - weight) * static_cast<float>(v0.color.mR));
result.mG = static_cast<byte>(static_cast<float>(v1.color.mG) * weight + (1.0f - weight) * static_cast<float>(v0.color.mG));
result.mB = static_cast<byte>(static_cast<float>(v1.color.mB) * weight + (1.0f - weight) * static_cast<float>(v0.color.mB));
result.mA = static_cast<byte>(static_cast<float>(v1.color.mA) * weight + (1.0f - weight) * static_cast<float>(v0.color.mA));

target.color = result;
}