在cocos2d中,渐变是使用四边形实现的,颜色是由opengl插值的,但是有一个额外的参数可以控制渐变的方向,所以算法如何工作。
//_alongVector is the gradient's direction
float h = _alongVector.getLength();
if (h == 0)
return;
// why a sqrt(2.0) ???
float c = sqrtf(2.0f);
Vec2 u(_alongVector.x / h, _alongVector.y / h);
// and what does this mean
if (_compressedInterpolation)
{
float h2 = 1 / ( fabsf(u.x) + fabsf(u.y) );
u = u * (h2 * (float)c);
}
float opacityf = (float)_displayedOpacity / 255.0f;
Color4F S(
_displayedColor.r / 255.0f,
_displayedColor.g / 255.0f,
_displayedColor.b / 255.0f,
_startOpacity * opacityf / 255.0f
);
Color4F E(
_endColor.r / 255.0f,
_endColor.g / 255.0f,
_endColor.b / 255.0f,
_endOpacity * opacityf / 255.0f
);
// what are these magic ??????
// (-1, -1)
_squareColors[0].r = E.r + (S.r - E.r) * ((c + u.x + u.y) / (2.0f * c));
_squareColors[0].g = E.g + (S.g - E.g) * ((c + u.x + u.y) / (2.0f * c));
_squareColors[0].b = E.b + (S.b - E.b) * ((c + u.x + u.y) / (2.0f * c));
_squareColors[0].a = E.a + (S.a - E.a) * ((c + u.x + u.y) / (2.0f * c));
// (1, -1)
_squareColors[1].r = E.r + (S.r - E.r) * ((c - u.x + u.y) / (2.0f * c));
_squareColors[1].g = E.g + (S.g - E.g) * ((c - u.x + u.y) / (2.0f * c));
_squareColors[1].b = E.b + (S.b - E.b) * ((c - u.x + u.y) / (2.0f * c));
_squareColors[1].a = E.a + (S.a - E.a) * ((c - u.x + u.y) / (2.0f * c));
// (-1, 1)
_squareColors[2].r = E.r + (S.r - E.r) * ((c + u.x - u.y) / (2.0f * c));
_squareColors[2].g = E.g + (S.g - E.g) * ((c + u.x - u.y) / (2.0f * c));
_squareColors[2].b = E.b + (S.b - E.b) * ((c + u.x - u.y) / (2.0f * c));
_squareColors[2].a = E.a + (S.a - E.a) * ((c + u.x - u.y) / (2.0f * c));
// (1, 1)
_squareColors[3].r = E.r + (S.r - E.r) * ((c - u.x - u.y) / (2.0f * c));
_squareColors[3].g = E.g + (S.g - E.g) * ((c - u.x - u.y) / (2.0f * c));
_squareColors[3].b = E.b + (S.b - E.b) * ((c - u.x - u.y) / (2.0f * c));
_squareColors[3].a = E.a + (S.a - E.a) * ((c - u.x - u.y) / (2.0f * c));
这是cocos2d-objc
中的另一个实现// _vector apparently points towards the first color.
float g0 = 0.0f; // (0, 0) dot _vector
float g1 = -_vector.x; // (0, 1) dot _vector
float g2 = -_vector.x - _vector.y; // (1, 1) dot _vector
float g3 = -_vector.y; // (1, 0) dot _vector
float gmin = MIN(MIN(g0, g1), MIN(g2, g3));
float gmax = MAX(MAX(g0, g1), MAX(g2, g3));
GLKVector4 a = GLKVector4Make(_color.r*_color.a*_displayColor.a, _color.g*_color.a*_displayColor.a, _color.b*_color.a*_displayColor.a, _color.a*_displayColor.a);
GLKVector4 b = GLKVector4Make(_endColor.r*_endColor.a*_displayColor.a, _endColor.g*_endColor.a*_displayColor.a, _endColor.b*_endColor.a*_displayColor.a, _endColor.a*_displayColor.a);
_colors[0] = GLKVector4Lerp(a, b, (g0 - gmin)/(gmax - gmin));
_colors[1] = GLKVector4Lerp(a, b, (g1 - gmin)/(gmax - gmin));
_colors[2] = GLKVector4Lerp(a, b, (g2 - gmin)/(gmax - gmin));
_colors[3] = GLKVector4Lerp(a, b, (g3 - gmin)/(gmax - gmin));
这些算法是否相同?
我真的想知道这些魔术操作背后的数学或算法