Wu's Lineアルゴリズム

DDAで線をひきつつ透明度をY軸の小数部分から直接求める。


http://en.wikipedia.org/wiki/Xiaolin_Wu%27s_line_algorithm
http://freespace.virgin.net/hugo.elias/graphics/x_wuline.htm


unsigned longをオーバーフローさせる実装
http://www.reportbase.com/isa-gil.html


固定小数で実装するのがスタンダード?のようだが
とりあえず普通にfloatでやってみた。
高速なアルゴリズムらしいが太さは1限定ぽい。


リンク先では、両端が半端になるので別処理にしていたが端折った。

int ipart(float num)
{
  return static_cast<int>(floor(num));
}

float frac(float num)
{
  return num-floor(num);
}

float invFrac(float num)
{
  return 1.0f-frac(num);
}

// only abs(dx)>abs(dy) && dx>0 && dy>0
void WuLine0(Image &image, const Vector2 &from, const Vector2 &to
    , int dx, int dy)
{
  float gradient=static_cast<float>(dy)/static_cast<float>(dx);
  float yf=static_cast<float>(from.y);
  for(int x=from.x; x<=to.x; ++x, yf+=gradient)
  {
    int y=ipart(yf);
    image.setPixel(Vector2(x, y), 
        0xFF000000 
        | 0x00010101 * static_cast<unsigned char>(invFrac(yf) * 255.0f));
    image.setPixel(Vector2(x, y+1),
        0xFF000000 
        | 0x00010101 * static_cast<unsigned char>(frac(yf) * 255.0f));
  }
}

void WuLine(Image &image, const Vector2 &from, const Vector2 &to)
{
  float dx=static_cast<float>(to.x-from.x);
  float dy=static_cast<float>(to.y-from.y);

  if(abs(dx)>abs(dy)){
    if(dx>0){
      if(dy>0){
        WuLine0(image, from, to, dx, dy);
      }
    }
  }
}

void drawLine(Image &image , const Vector2 &from , const Vector2 &to)
{
  WuLine(image, from, to);
}