Midpoint Circle Algorithm, Modifying it to use arcs

Hello, I have been having quite an annoying problem figuring out how to convert Processing's use of rotations into standard 0-360 degree counter-clockwise unit circle. \ I have JUST about figured it out however once the rotation goes from -180 (standard 180 degrees) abruptly to 180 degrees (standard 181 degrees) the > algorithm doesn't fulfill the condition and creates a dot at 180 degrees, however it is supposed to create an arc that extends 90 degrees. Every other octant performs perfectly except for the 135-180 degree octant. I'm using the code of "Midpoint Circle Algorithm" on the Wikipedia page. code as follows.

the added code for arcs is below

`// Calculate the angle the current point makes with the circle center int angle = (int) degrees(atan2(y, x)); //int(degrees(atan2(mouseY-(height/2),mouseX-(width/2))));

// draw the circle points as long as they lie in the range specified if (x < y) {

// draw point in range 0 to 45 degrees
if ( -90 + angle >= startAngle &&  -90 + angle <= endAngle) {
  point(centerX + y, centerY - x);
}

//// draw point in range 45 to 90 degrees
if (-angle >= startAngle && -angle <= endAngle) {
  point(centerX + x, centerY - y);
}

//// draw point in range 90 to 135 degrees
if (-180 + angle >= startAngle && -180 + angle <= endAngle) {
  point(centerX - x, centerY - y);
}

//// draw point in range 135 to 180 degrees
if ((-90 + -angle >= (startAngle) && -90 + -angle <= (endAngle))) {
  point(centerX - y, centerY - x);
}

// draw point in range 180 to 225 degrees
if (90 + (angle) >= (startAngle) && 90 + (angle) <= (endAngle)) {
  point(centerX - y, centerY + x);

  System.out.println("angle " + (90 + (angle)));
}

// draw point in range 225 to 270 degrees
if (180 + -angle >= startAngle && 180 + -angle <= endAngle) {
  point(centerX - x, centerY + y);
}

// draw point in range 270 to 315 degrees
if (angle >= startAngle && angle <= endAngle) {
  point(centerX + x, centerY + y);
}

// draw point in range 315 to 360 degrees
if (-angle + 90 >= startAngle && -angle + 90 <= endAngle) {
  point(centerX + y, centerY + x);
}

} } `

Answers

  • It would be better if you posted a working sketch so that forum members can experiment with the code and hopefully find the mistake.

  • Yes of course! Sorry, I will post that once I can. I had no idea someone would actually want to troubleshoot this with me.

  • Did you post the full sketch? It doesn't look like that.

  • Since the OP won't provide his code here is my take on the problem.

    The angle of arc (0° - 45°) drawn for each octant is determined by the mouse X position.

    // Modified from the C language example from
    // https:// en.wikipedia.org/wiki/Midpoint_circle_algorithm
    int mangle;
    
    void setup() {
      size(400, 400);
    }
    
    void draw() {
      background(0);
      drawAxis();
      drawCircle(width/2, height/2, 180, mangle);
    }
    
    void drawAxis() {
      stroke(160);
      strokeWeight(1.1);
      line(0, 0, width, height);
      line(0, height, width, 0);
      line(0, height/2, width, height/2);
      line(width/2, 0, width/2, height);
    }
    
    void mouseMoved(){
      // Map the mouse X position to an integer angle in the
      // range 0 - 45 degrees
      mangle = int(map(mouseX, 0, width, 0, 46));
    }
    
    void drawCircle(int x0, int y0, int radius, int angle) {
      int circCol = color(0, 255, 0);
      float limit = radians(angle);
      int x = radius;
      int y = 0;
      int err = 0;
    
      while (x >= y && atan2(y, x) < limit) {
        set(x0 + x, y0 + y, circCol);
        set(x0 + y, y0 + x, circCol);
        set(x0 - y, y0 + x, circCol);
        set(x0 - x, y0 + y, circCol);
        set(x0 - x, y0 - y, circCol);
        set(x0 - y, y0 - x, circCol);
        set(x0 + y, y0 - x, circCol);
        set(x0 + x, y0 - y, circCol);
    
        y += 1;
        if (err <= 0) {
          err += 2*y + 1;
        }
        if (err > 0) {
          x -= 1;
          err -= 2*x + 1;
        }
      }
    }
    
  • edited May 2017

    Here is the code for my current project. Sorry I was working late tonight. EDIT I cannot for the life of me format this code correctly...

    void setup() { //fullscreen(); size(800, 600); background(31);

    noFill(); } void draw() { strokeWeight(1); background(40); stroke(0, 200, 0, 10); for (float i = 0; i < 100; i+= 1.0) for (float j = 0; j < 100; j += 1.0) { rect(i20, j20, 20, 20); } stroke(200, 0, 0, 100); strokeWeight(4); text(degrees(atan2(mouseY-(height/2), mouseX-(width/2))), 20, 50); // line(mouseX,mouseY,width/2,height/2); drawMidpointCircle(); }

    public void drawMidpointCircle() { // Settings int startAngle = int(degrees((atan2(mouseY-(height/2), mouseX-(width/2))))); int endangle = 45 + int(degrees((atan2(mouseY-(height/2), mouseX-(width/2))))); int cx = width/2; // x axis value for the center of the circle int cy = height/2; // x axis value for the center of the circle int radius = 200;//floor(dist(mouseX,mouseY,width/2,height/2)); // Standard Midpoint Circle algorithm int p = (5 - radius * 4) / 4; int x = 0; int y = radius; text(startAngle + "= S", 20, 80); drawCirclePoints(cx, cy, x, y, startAngle, endangle); while (x <= y) { x+=10; if (p < 0) { p += 2 * x + 1; } else { y-=10; p += 2 * (x - y) + 1; } drawCirclePoints(cx, cy, x, y, startAngle, endangle); } } private void drawCirclePoints(int centerX, int centerY, int x, int y, int startAngle, int endAngle) {

    // Calculate the angle the current point makes with the circle center int angle = (int) degrees(atan2(y, x));

    if (x < y) {

    // draw point in range 0 to 45 degrees
    if ( -90 + angle >= startAngle &&  -90 + angle <= endAngle) {
      point(centerX + y, centerY - x);
      line(width/2,height/2,centerX + y,centerY - x);
    }
    
    //// draw point in range 45 to 90 degrees
    if (-angle >= startAngle && -angle <= endAngle) {
      point(centerX + x, centerY - y);
      line(width/2,height/2,centerX + x,centerY - y);
    }
    
    //// draw point in range 90 to 135 degrees
    if (-180 + angle >= startAngle && -180 + angle <= endAngle) {
      point(centerX - x, centerY - y);
      line(width/2,height/2,centerX - x,centerY - y);
    }
    
    //// draw point in range 135 to 180 degrees
    if ((-90 + -angle >= (startAngle) && -90 + -angle <= (endAngle))) {
      point(centerX - y, centerY - x);
      line(width/2,height/2,centerX - y,centerY - x);
    }
    
    // draw point in range 180 to 225 degrees
    if (90 + (angle) >= (startAngle) && 90 + (angle) <= (endAngle)) {
      point(centerX - y, centerY + x);
      line(width/2,height/2,centerX - y,centerY + x);
    
      System.out.println("angle " + (90 + (angle)));
    }
    
    // draw point in range 225 to 270 degrees
    if (180 + -angle >= startAngle && 180 + -angle <= endAngle) {
      point(centerX - x, centerY + y);
      line(width/2,height/2,centerX - x,centerY + y);
    }
    
    // draw point in range 270 to 315 degrees
    if (angle >= startAngle && angle <= endAngle) {
      point(centerX + x, centerY + y);
      line(width/2,height/2,centerX + x,centerY + y);
    }
    
    // draw point in range 315 to 360 degrees
    if (-angle + 90 >= startAngle && -angle + 90 <= endAngle) {
      point(centerX + y, centerY + x);
      line(width/2,height/2,centerX + y,centerY + x);
    }
    

    } }

  • edited May 2017

    @EvanJbesser -- for formatting:

    Edit your post using the gear icon. Highlight your code. Press Ctrl+o. Make sure there is a blank line above and below the code.

  • Answer ✓

    however it is supposed to create an arc that extends 90 degrees

    This code draws a 45 degree arc centred on the angle made by the mouse and the circle centre. The only octant that varies is for 135 - 180 degrees.

    Do you have a reason for using the Midpoint Circle Algorithm?

    There are much easier alternatives that give the same effect. Like this.

    int col0, col1;
    float arc0, arc1;
    
    void setup() {
      size(300, 300);
      col0 = color(230, 0, 0);
      col1 = color(64, 32, 255);
      arc0 = radians(45); // octant
      arc1 = radians(90); // quadrant
    }
    
    void draw() {
      background(0);
      drawArc(80, 80, 70, arc0, 9, col0);
      drawArc(160, 200, 90, arc1, 21, col1);
    }
    
    // Spoked arc centerd at [cx, cy] with radius r and arc angle arcLength (radians)
    // Number of spokes n of colour col
    void drawArc(float cx, float cy, float r, float arcLength, int n, int col) {
      float ang = atan2(mouseY - cy, mouseX - cx);
      // convert to 0 to TWO_PI (0 to 360 degrees)
      if (ang < 0) ang += TWO_PI; 
      float lowAng = ang - arcLength/2;
      float highAng = ang + arcLength/2;
      float deltaAng = arcLength / (n - 1);
      stroke(col);
      fill(col);
      for (float a = lowAng; a <= highAng; a += deltaAng) {
        float ex = cx + r * cos(a);
        float ey = cy + r * sin(a);
        ellipse(ex, ey, 3, 3);
        line(cx, cy, ex, ey);
      }
    }
    
  • Yes sir, this works great. I was using the Midpoint algorithm because I thought it would be a good place to start learning Bersenhams line algorithm, which I need in order to find the tiles that lie within the lines that create the starting and end angles.

Sign In or Register to comment.