What is the problem with my midpoint algorithm?

Viewed 112

I just started to learn processing and I have a few problems that I couldn't solve. I hope someone could help me. This should draw lines where i could choose the starting and finishing points with mousePressed(), but I failed before trying implementing that.

//int x1, x2, y1, y2;

void setup() {
  size(640, 480);
}
void draw() {
  midpoint(0, 0, 100, 100);
}

//void mousePressed() {
//  pmouseX =x1;
//  pmouseY =y1;
//  mouseX =x2;
//  mouseY =y2;
//}

void midpoint(int x1, int y1, int x2, int y2) {
  int dx, dy, d, x, y;
  dx = x2-x1;
  dy = y2-y1;
  d = 2*dy-dx;
  x = x1;
  y = y1;
  for (int i = 1; i <dx; i++) {
    point(x, y);
    if (d>0) {
      y++;
      d+=2*(dy-dx);
    } else {
      d+=2*dy;
    }
    x++;
  }
}

My problem is that it will not always draw the line. e.g.

midpoint(0,0,100,100);

it will draw it

midpoint(100,100,0,0);

it draws nothing.

It should draw the same line if I exchange the points coordinates, or draw a single point if the coordinates are the same.

1 Answers

In Bresenham's midpoint line algorithm you have to be careful with the gradient of the line drawn, the base algorithm you described only works for gradients between 0 and 1. In order to deal with gradients that are steeper (m > 1 or m < -1), you have to switch the roles of the x and y values, therefore you have to step in y and then calculate x. Also to deal with negative steps just switch the point order.

void midpoint(int x1, int y1, int x2, int y2) {
  // Is gradient of line greater than 1
  boolean steep = abs(y2-y1) > abs(x2-x1);
  int temp;

  if (steep) {   // If gradient > 1
    // Swap roles of x and y components to step in y instead
    temp = y1;
    y1 = x1;
    x1 = temp;

    temp = y2;
    y2 = x2;
    x2 = temp;
  }

  if (x2 < x1) {  
    // Swap points such that step in x is positive
    temp = x1;
    x1 = x2;
    x2 = temp;

    temp = y1;
    y1 = y2;
    y2 = temp;
  }

  // Change in x and y which are now both positive
  int dx = x2 - x1;
  int dy = abs(y2 - y1);

  // Step in y
  int sy = y2 > y1 ? 1 : -1;
  int y = y1;

  // Decision variable
  int d = 2*dy-dx;

  // Small step in x
  for (int x=x1; x<=x2; x++) {
    // Depending on gradient plot x and y
    if (steep) {
      point(y, x);
    } else {
      point(x, y);
    }

    // Update decision parameter
    if (d>0) {
      y += sy;
      d+=2*(dy-dx);
    }else{
      d+=2*dy;
    }
  }
}
Related