title: what's the math behind cocos's gradient layer
body: <p>In cocos2d the gradient is implemented using a quad, and the color is interpolated by opengl, but there is an extra parameter which controls the gradient's direction, so how does the algorithm to work.</p>
  
  <pre><code>//_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));
  </code></pre>
  
  <p>and here is another implementation in cocos2d-objc</p>
  
  <pre><code>// _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));
  </code></pre>
  
  <p>are these algorithms the same?<br>
  I really want to know the math or algorithm behind those magic operations</p>