var triangle = (function(){
  var tmp = new Point(),
    swap = function(p1, p2){
      tmp.borrow(p1);
      p1.borrow(p2);
      p2.borrow(tmp);
    },
    invslope1,
    invslope2,
    curx1,
    curx2,
    scanLineY,
    scanLineTo,

    p1 = new Point(), p2 = new Point(), p3 = new Point(),

    fillLine, tmpNum;
  var scanline = function (x1, x2, y, arr) {
      if(x2<x1){
        tmpNum = x1; x1 = x2; x2 = tmpNum;
      }
      for(;x1<=x2;x1++)
        arr.push([x1|0, y]);
    };

  var flatBottom = function(p1, p2, p3, arr){
      invslope1 = (p2.x - p1.x) / (p2.y - p1.y),
        invslope2 = (p3.x - p1.x) / (p3.y - p1.y),
        curx1 = p1.x,
        curx2 = p1.x,
        scanLineY = p1.y,
        scanLineTo = p2.y;

      for (; scanLineY <= scanLineTo; scanLineY++){
        scanline(curx1|0,curx2|0, scanLineY|0, arr);
        curx1 += invslope1;
        curx2 += invslope2;
      }
    },

    flatTop = function(p1, p2, p3, arr){
      invslope1 = (p3.x - p1.x) / (p3.y - p1.y),
        invslope2 = (p3.x - p2.x) / (p3.y - p2.y),
        curx1 = p3.x,
        curx2 = p3.x,
        scanLineY = p3.y,
        scanLineTo = p1.y;

      for (; scanLineY > scanLineTo; scanLineY--){
        scanline(curx1|0,curx2|0, scanLineY|0, arr);
        curx1 -= invslope1;
        curx2 -= invslope2;
      }
    };
  var p4 = new Point();
  var triangle = function triangle(_p1, _p2, _p3){
    var arr = [];
    p1.borrow(_p1); p2.borrow(_p2); p3.borrow(_p3);

    if (p1.y > p2.y) swap(p1, p2);
    if (p2.y > p3.y) swap(p2, p3);
    if (p1.y > p2.y) swap(p1, p2);

    if (p2.y === p3.y) {
      flatBottom(p1, p2, p3, arr);
    } else if (p1.y === p2.y) {
      flatTop(p1, p2, p3, arr);
    } else {
      p4.x = p1.x + (p2.y - p1.y)/(p3.y - p1.y)*(p3.x - p1.x);
      p4.y = p2.y;
      flatBottom(p1, p2, p4, arr);
      flatTop(p2, p4, p3, arr);
    }
    return arr;
  };
  return triangle;
})();