# Script for drawing a line
disp("Running linedraw...")

function h1 = plotPixelGrid()    
  h1 = axes;
  plot(h1, 100, 100, '+');
  
  ylim([85 115]);
  xlim([85 115]);
  axis equal;
  set(h1, 'Ydir', 'reverse');
  set(h1, 'XTick', [85.5:1:115.5]);
  set(h1, 'YTick', [85.5:1:115.5]);
  grid on;
  hold on;
endfunction

function plotLine(p1, p2) 
  x1 = p1(1);
  y1 = p1(2);
  x2 = p2(1);
  y2 = p2(2);
  plot([x1,x2], [y1,y2], "-", x1,y1, "ob", x2,y2, "or");  
endfunction

function plotPixel(x, y)
  r=0.5;
  v = [x+r y+r; x+r y-r; x-r y-r; x-r y+r];
  fill(v(:,1), v(:,2), 'y');
endfunction

function lineDraw0(p1, p2)
  x1 = p1(1);
  y1 = p1(2);
  x2 = p2(1);
  y2 = p2(2);
  
  dx = x2 - x1;
  dy = y2 - y1;
  
  a = dy / dx;
  
  plotPixel(x1, y1);  
  
  fraction = 0.5 + a;
  
  while (x1 < x2)    
    x1 = x1 + 1;
    if fraction < 1
      fraction = fraction + a;
    else
      y1 = y1 + 1;
      fraction = fraction + a - 1;
    endif
    plotPixel(x1, y1);    
  endwhile
endfunction

function lineDraw1(p1, p2)
  x1 = p1(1);
  y1 = p1(2);
  x2 = p2(1);
  y2 = p2(2);
  
  dx = x2 - x1;
  dy = y2 - y1;
  
  plotPixel(x1, y1);  
  
  fraction = bitshift(dy, 1) - dx;  
  while (x1 < x2)    
    x1 = x1 + 1;
    if fraction < 0
      fraction = fraction + bitshift(dy, 1);
    else
      y1 = y1 + 1;
      fraction = fraction + bitshift(dy - dx, 1);  
    endif
    plotPixel(x1, y1);    
  endwhile
endfunction


function octantLineDraw1(p1, p2)
  x1 = p1(1);
  y1 = p1(2);
  x2 = p2(1);
  y2 = p2(2);
  
  dx = x2 - x1;
  dy = y2 - y1;
  
  a = dy / dx;
  
  plotPixel(x1, y1);  
  
  if abs(dy) <= abs(dx)
    if dx < 0
      if dy < 0
        #octant 3
        fraction = 0.5 + a;  
        while (x1 > x2)    
          x1 = x1 - 1;
          if fraction < 1
            fraction = fraction + a;
          else
            y1 = y1 - 1;
            fraction = fraction + a - 1;
          endif
          plotPixel(x1, y1);    
        endwhile  
      else
        # dy >= 0
        # octant 4
        fraction = 0.5 + (-a);  
        while (x1 > x2)    
          x1 = x1 - 1;
          if fraction < 1
            fraction = fraction + (-a);
          else
            y1 = y1 + 1;
            fraction = fraction + (-a) - 1;
          endif
          plotPixel(x1, y1);    
        endwhile  
      endif
    else
      # dx >= 0
      if dy < 0
        # octant 0
        fraction = 0.5 + (-a);  
        while (x1 < x2)    
          x1 = x1 + 1;
          if fraction < 1
            fraction = fraction + (-a);
          else
            y1 = y1 - 1;
            fraction = fraction + (-a) - 1;
          endif
          plotPixel(x1, y1);    
        endwhile  
      else
        # dy >= 0
        # octant 7
        fraction = 0.5 + a;  
        while (x1 < x2)    
          x1 = x1 + 1;
          if fraction < 1
            fraction = fraction + a;
          else
            y1 = y1 + 1;
            fraction = fraction + a - 1;
          endif
          plotPixel(x1, y1);    
        endwhile  
      endif
    endif 
  else 
    # abs(dy) > abs(dx)
    if dx < 0
      if dy < 0
        #octant 2
        fraction = 0.5 + (1/a);  
        while (y1 > y2)    
          y1 = y1 - 1;
          if fraction < 1
            fraction = fraction + (1/a);
          else
            x1 = x1 - 1;
            fraction = fraction + (1/a) - 1;
          endif
          plotPixel(x1, y1);    
        endwhile  
      else
        # dy >= 0
        # octant 5
        fraction = 0.5 + (-1/a);  
        while (y1 < y2)    
          y1 = y1 + 1;
          if fraction < 1
            fraction = fraction + (-1/a);
          else
            x1 = x1 - 1;
            fraction = fraction + (-1/a) - 1;
          endif
          plotPixel(x1, y1);    
        endwhile  
      endif
    else
      # dx >= 0
      if dy < 0
        # octant 1
        fraction = 0.5 + (-1/a);  
        while (y1 > y2)    
          y1 = y1 - 1;
          if fraction < 1
            fraction = fraction + (-1/a);
          else
            x1 = x1 + 1;
            fraction = fraction + (-1/a) - 1;
          endif
          plotPixel(x1, y1);    
        endwhile  
      else
        # dy >= 0
        # octant 6        
        fraction = 0.5 + 1/a;  
        while (y1 < y2)    
          y1 = y1 + 1;
          if fraction < 1
            fraction = fraction + 1/a;
          else
            x1 = x1 + 1;
            fraction = fraction + 1/a - 1;
          endif
          plotPixel(x1, y1);    
        endwhile  
      endif
    endif 
  endif 
endfunction




# simplify algorithm
function octantLineDraw1(p1, p2)
  x1 = p1(1);
  y1 = p1(2);
  x2 = p2(1);
  y2 = p2(2);

  dx = x2 - x1;
  dy = y2 - y1;
    
  a = dy / dx;

  if abs(dy) > abs(dx) 
    a = 1/a;
  endif
  
  if a < 0
    a = -a;
  endif
 
  plotPixel(x1, y1);  
 
  fraction = 0.5 + a;  
   
  while ((dx < 0) && (x1 > x2) || (dx >= 0) && (x1 < x2) || (dy < 0) && (y1 > y2) || (dy >= 0) && (y1 < y2))        
    
    if !(fraction < 1)
      if abs(dy) <= abs(dx)            
        if (dy < 0)
          y1 = y1 - 1;
        else
          y1 = y1 + 1;
        endif      
      else      
        if dx < 0
          x1 = x1 - 1;
        else
          x1 = x1 + 1;
        endif         
      endif
    endif

    if abs(dy) <= abs(dx)      
      if dx < 0
        #octant 3 and 4        
        x1 = x1 - 1;
      else
        # octant 0 and 7        
        x1 = x1 + 1;          
      endif 
    else 
      if dy < 0
        # octant 1 and 2        
        y1 = y1 - 1;
      else
        # octant 5 and 6        
        y1 = y1 + 1;
      endif
    endif
    
    if fraction < 1
      fraction = fraction + a;
    else        
      fraction = fraction + a - 1;
    endif
    plotPixel(x1, y1);    
  endwhile              
endfunction


# simplify algorithm - manipulate dx and dy
function octantLineDraw0(p1, p2)
  x1 = p1(1);
  y1 = p1(2);
  x2 = p2(1);
  y2 = p2(2);

  dx = x2 - x1;
  dy = y2 - y1;
  
  abs_dy_less_than_abs_dx = false;
  dx_negative = false;
  dy_negative = false;
  
  if abs(dy) <= abs(dx)            
    abs_dy_less_than_abs_dx = true;
  endif
  
  if dx < 0
    dx_negative = true;
    dx = -dx;
  endif
  
  if dy < 0
    dy_negative = true;
    dy = -dy;
  endif
  
  if !abs_dy_less_than_abs_dx
    tmp = dy;
    dy = dx;
    dx = tmp;    
  endif

  
  a = dy / dx;
    
  plotPixel(x1, y1);  
 
  fraction = 0.5 + a;
  disp(fraction);  
   
  while (dx_negative && (x1 > x2) || !dx_negative && (x1 < x2) || dy_negative && (y1 > y2) || !dy_negative && (y1 < y2))        
    
    if !(fraction < 1)
      if abs_dy_less_than_abs_dx            
        if dy_negative
          y1 = y1 - 1;
        else
          y1 = y1 + 1;
        endif      
      else      
        if dx_negative
          x1 = x1 - 1;
        else
          x1 = x1 + 1;
        endif         
      endif
    endif

    if abs_dy_less_than_abs_dx      
      if dx_negative
        #octant 3 and 4        
        x1 = x1 - 1;
      else
        # octant 0 and 7        
        x1 = x1 + 1;          
      endif 
    else 
      if dy_negative
        # octant 1 and 2        
        y1 = y1 - 1;
      else
        # octant 5 and 6        
        y1 = y1 + 1;
      endif
    endif
    
    if fraction < 1
      fraction = fraction + a;
    else        
      fraction = fraction + a - 1;
    endif
    plotPixel(x1, y1);    
  endwhile              
endfunction

x1 = 100;
y1 = 100;
x_offset = 0;
y_offset = 0;
dx = 10;
dy = 5;

# octant 7
p1 = [x1+x_offset,y1+y_offset];
p2 = [p1(1)+dx, p1(2)+dy];

h1 = plotPixelGrid();
#lineDraw0(p1, p2);
octantLineDraw0(p1, p2);
plotLine(p1, p2);

# octant 0
p3 = [x1+x_offset,y1-y_offset];
p4 = [p3(1)+dx, p3(2)-dy];
#octantLineDraw0(p3, p4);
plotLine(p3, p4);

# octant 4
p5 = [x1-x_offset,y1+y_offset];;
p6 = [p5(1)-dx, p5(2)+dy];
#octantLineDraw0(p5, p6);
plotLine(p5, p6);

# octant 3
p7 = [x1-x_offset,y1-y_offset];;
p8 = [p7(1)-dx, p7(2)-dy];
#octantLineDraw0(p7, p8);
plotLine(p7, p8);

# octant 6
p9 = [x1+x_offset,y1+y_offset];;
p10 = [p9(1)+dy, p9(2)+dx];
#octantLineDraw0(p9, p10);
plotLine(p9, p10);

# octant 1
p11 = [x1+x_offset,y1-y_offset];;
p12 = [p11(1)+dy, p11(2)-dx];
#octantLineDraw0(p11, p12);
plotLine(p11, p12);

# octant 2
p13 = [x1-x_offset,y1-y_offset];;
p14 = [p13(1)-dy, p13(2)-dx];
#octantLineDraw0(p13, p14);
plotLine(p13, p14);

# octant 5
p15 = [x1-x_offset,y1+y_offset];;
p16 = [p15(1)-dy, p15(2)+dx];
#octantLineDraw0(p15, p16);
plotLine(p15, p16);


