Highlighting an arc in P5

Hello to you all :slight_smile: . I am trying to develop a pizza-like graph. Each “slice” of the full circle represents an element that will have some data attached to it. I am having trouble to acess each slice “individualy”. I’ve used a for loop to check if the distance of the mouse pointer is equal to the sum of the distance of the mouse pointer to the two edges of the “slice”, so i can keep track if the mouse pointer is inside the “slice”. It works but it is looking kind of glitchy, since the for loop keeps running an retrieves a false value more often than a true. Can somebody please help me by looking at the code or recommending any good resources can help me with the pizza-graph approach in P5 or Processing.

Thank you very much. I can make the issue more clear please tell me. And sorry for the bad english, it is not my native language.

here is the code. Basically I am just using one object of this class and using both functions I wrote.

class globalGraph {

  constructor() {
    this.angleinc = 2 * PI / 120;
    this.radius = 300;
    this.check = false;
    this.toggle = true;
    this.alpha = 0;
    this.smoothedReceiving = 0;

  }

  display() {
    fill(30, 50);
    stroke(255);
    for (var i = 1; i <= 120; i++) {
      arc(width / 2, height / 2, this.radius * 2, this.radius * 2, (i - 1) * this.angleinc, i * this.angleinc, PIE);
    }

  }

  highlight() {
    var angleinit = PI / 60;
    var angleend = 2 * (PI / 60);
    var hover;
    var hover2;
    var hoverdist;
    var v;
    var teste;
    var v2;
    var distance = [];
    var vec2 = [];
    var vec1 = [];



    for (var i = 0; i <= this.radius; i++) {
      v = createVector(cos(angleinit) * i + width / 2, sin(angleinit) * i + height / 2);
      vec1.push(v);
      v2 = createVector(cos(angleend) * i + width / 2, sin(angleend) * i + height / 2);
      vec2.push(v2);

    }

    for (var j = 0; j < vec1.length; j++) {
      hoverdist = dist(vec1[j].x, vec1[j].y, vec2[j].x, vec2[j].y);
      distance.push(hoverdist);
    }

    for (var w = 0; w < distance.length; w++) {
      hover = floor(dist(mouseX, mouseY, vec1[w].x, vec1[w].y));
      hover2 = floor(dist(mouseX, mouseY, vec2[w].x, vec2[w].y));

      if (floor(distance[w]) == hover + hover2) {
        this.check = true;
        this.alpha = 100;
      } 
    }
    
    if (this.check == true) {    
    noStroke();
    fill(255,0,0,this.alpha);
    arc(width / 2, height / 2, this.radius * 2, this.radius * 2, angleinit, angleend);
      this.check = false;
   
    }
   
    print(this.check);

  }

}
1 Like

Hi,

Welcome to the forum ! :slight_smile:

Can you please format your code by pressing Ctrl+T in the Processing IDE the use the </> button the the message editor on the forum. Then we can start to look at your code :wink:

Here is my solution with comments :

var angles;
var colors;

function setup() {
  createCanvas(400, 400);
  
  // Angles of the slices
  angles = [HALF_PI, PI, QUARTER_PI, QUARTER_PI];
  
  // Colors of the slices
  colors = [color(255, 0, 0), color(0, 255, 0), color(0, 0, 255), color(255, 255, 0)];
}

function draw() {
  background(255);
  
  draw_arcs(width/2, height/2, width/2, angles, colors);
}

// Function to draw the pie
function draw_arcs(x, y, diameter, angles, colors){
  // Starting angle
  let start = 0;
  
  // Loop through the angles
  for(let i=0; i<angles.length; i++){
    // Compute the distance from the center to the mouse
    let distance = dist(mouseX, mouseY, x, y);
    
    // If the mouse is in the pie
    if(distance < diameter/2){
      // Compute the angle
      let angle = acos((mouseX - x) / (distance));
      
      // If the mouse is on the upper part of the pie, inverse it
      if(mouseY < y){
        angle = TWO_PI - angle;
      }
      
      // If the angle is between the current angle + the angle of the next slice
      if(angle >= start && angle <= start + angles[i]){
        strokeWeight(5);
      }else{
        strokeWeight(1);
      }
    }
    
    // Draw the arc
    fill(colors[i]);
    stroke(0);
    arc(x, y, diameter, diameter, start, start + angles[i], PIE);
    
    // Add the area to the starting angle
    start += angles[i];
  }
}

And here, the way you compute the angle between the center of the pie and the mouse.

When the mouse is in the down part of the pie, it’s just basic trigonometry with the acos function.
Then if the mouse is in the upper part of the pie (mouseY < y), the angle is the inverse so TWO_PI - angle.

The last step is to check whether the angle is between a certain range (a slice of the pie).

Hope it helps! :wink:

3 Likes

Hey @josephh !
Thank you very much for the information concerning the code format in the forum. Indeed I am new here. And thank you so much for the high quality aswer. I will check out your suggestions as soon as I can and reply if it works (or if it doesn’t lol) :grinning:

1 Like

@josephh thanks very much man. It works perfectly for my purpose. You helped a lot !

1 Like