Creating sectors in a rotating circular image

Hi, I have a circular image that rotates on mouseDragged and the image has various letters around the circle, when I drag the image to a certain position, one of the letters goes on top of a box indicating i want to write that letter, but I’m having problems coding this last part. I don’t know how to create and identify each sector of the image when in rotation. Any ideas?

(I am sorry for the confusion- I don’t know why I had a hard time explaining this.)You could check to what degree the circle is rotated, and every ‘section’(i.e. rotated between 120 to 150 degrees, or 1-2 radians, or whatever)would have a letter assigned to it(not necessarily visible as shown in the picture). So, say the circle is rotated to anywhere between X and Y degrees. What now? You could arrange something like

if((degreesRotated > 120) && (degreesRotated < 150)) { ///between X and Y, chose 120 and 150 as an example
letterChosen="A";}

I’ve included an image if you didn’t understand the cancer that I wrote as an explanation :woozy_face: procex2

1 Like

I understood what you explained perfectly, thank you so much, I was trying to do something like that but the problem I couldn’t figure out was the angles. This is (part of) the code I had for the rotation originally:

float rotAngle = 0;
void draw(){ 
    pushMatrix();
    translate(width/2, height/2);
    rotate(rotAngle);
    imageMode(CENTER);
    image(abc, 0, 0, ABC_SIZE, ABC_SIZE);  //abc is the image and ABC_SIZE the size of the image
    popMatrix();  
}

void mouseDragged(){
    rotAngle = atan2(mouseY - height/2, mouseX - width/2);
}

But then I had do change it because like this it wasn’t able to continue dragging where it was left off if I stopped dragging and started again from a different position. So now I have this code:

float rotAngle, originalRotAng, newRot, originalTouchAng = 0;
void draw() { 
    if (mousePressed == true) {
          originalTouchAng = atan2(mouseY - height/2, mouseX - width/2); //original angle at which the keyboard was tapped
    }
    pushMatrix();
    translate(width/2, height/2);
    rotate(rotAngle);
    imageMode(CENTER);
    image(abc, 0, 0, ABC_SIZE, ABC_SIZE);  //abc is the image and ABC_SIZE the size of the image
    popMatrix();  
}

void mouseDragged() {
    originalRotAng = rotAngle;                              // original angle of the keyboard
    newRot = atan2(mouseY - height/2, mouseX - width/2);    // 
    rotAngle = originalRotAng + newRot - originalTouchAng;  // new angle for the rotation of the letters
}

And it kinda works how I want it but when I get the rotAngle to know which section is at the box it’s all over the place, because when I drag the image mutiple times around it doesn’t give consistant rotAngles. Maybe the code I have now isn’t the best but it was the only one that kind of continues the drag from where it’s left off

I took some of that code and adapted it to make a rudimentary version- only look at the code if you have to, I did not make it neat :joy:. I checked what values of rotAngle would pertain to each line and added if() statements validating whether or not rotAngle is of a certain value, instead of checking line positions relative to the angles. However, it is very finnicky- I included this as a starting point for you to work on(it’s a bit of a cancerous sketch, like my explanation earlier).

float rotAngle, originalRotAng, newRot, originalTouchAng = 0;
PVector line = new PVector(70,70);
PVector bl1, bl2;
void setup() {
  size(600,600);
  bl1 = new PVector(70,-70);
  bl2 = new PVector(-70,-70);
}
void draw(){ 
  background(170);
 if (mousePressed == true)
    {
      originalTouchAng = atan2(mouseY - height/2, mouseX - width/2); //original angle at which the keyboard was tapped
    }
    pushMatrix();
    translate(width/2, height/2);
    rotate(rotAngle);
    circle(0,0,100);
    stroke(255,0,0);
    line(0,0,line.x,line.y);
    stroke(0,0,255);
    line(0,0,-line.x,-line.y);
    stroke(0);
    rotate(-rotAngle);
    line(0,0,bl1.x,bl1.y);
    line(0,0,bl2.x,bl2.y);
    imageMode(CENTER);
   // image(abc, 0, 0, ABC_SIZE, ABC_SIZE);  //abc is the image and ABC_SIZE the size of the image
    popMatrix(); 
    if((rotAngle>3.15) && (rotAngle<4.71)) {
  textSize(30);
  text("Selected; red line",75,75);
  }
  else if((rotAngle>0.023) && (rotAngle<1.56)) {
    textSize(30);
    text("Selected; blue line",75,75);
  }
  if(keyPressed){
  print("Angle;",rotAngle);}
}

void mouseDragged(){
    originalRotAng = rotAngle;                              // original angle of the keyboard
    newRot = atan2(mouseY - height/2, mouseX - width/2);    // 
    rotAngle = originalRotAng + newRot - originalTouchAng;  // new angle for the rotation of the letters
}
1 Like

This only work on the first rotation, I wanted it to work, in the code you wrote, every time the blue or red line went in that section you know?

Thank you so much btw, do you also know why when you drag it closer to the center the speed is the same as your mouse but the farther you go from the center the faster the drag is from your mouse drag? For example, in your code, if I start dragging by the red line away from the center, after a while the blue line passes the mouse instead of keeping it dragged by the red line. I’m sure it’s something to do with the new angles but I can’t find another solution to continue dragging from the position it was left off.

almost…


float rotAngle, originalRotAng, newRot, originalTouchAng = 0;

PVector line = new PVector(70, 70);
PVector bl1, bl2;

String alphabet="ABCDEFGHIJKLMNOPQRSTUVWXYZ";

void setup() {
  size(600, 600);
  bl1 = new PVector(70, -70);
  bl2 = new PVector(-70, -70);
}

void draw() { 
  background(170);
  if (mousePressed == true)
  {
    originalTouchAng = atan2(mouseY - height/2, mouseX - width/2); //original angle at which the keyboard was tapped
  }
  pushMatrix();
  translate(width/2, height/2);
  rotate(rotAngle);
  ellipse(0, 0, 100, 100);
  stroke(255, 0, 0);
  line(0, 0, line.x, line.y);
  stroke(0, 0, 255);
  line(0, 0, -line.x, -line.y);
  stroke(0);
  rotate(-rotAngle);
  line(0, 0, bl1.x, bl1.y);
  line(0, 0, bl2.x, bl2.y);
  imageMode(CENTER);
  // image(abc, 0, 0, ABC_SIZE, ABC_SIZE);  //abc is the image and ABC_SIZE the size of the image
  popMatrix(); 

  if ((rotAngle>3.15) && (rotAngle<4.71)) {
    textSize(30);
    text("Selected; red line", 75, 75);
  } else if ((rotAngle>0.023) && (rotAngle<1.56)) {
    textSize(30);
    text("Selected; blue line", 75, 75);
  }

  textSize(16);
  text( "Angle: " 
    + rotAngle +" "
    +angleAsInt()
    +"\n"
    +alphabet.charAt(angleAsInt()), 19, 19);

  if (keyPressed) {
    print("Angle: ", rotAngle, int(rotAngle) );
  }
}

int angleAsInt() {
  return
    int(map(rotAngle, -TWO_PI, TWO_PI, 0, 26));
}

void mouseDragged() {
  originalRotAng = rotAngle;                              // original angle of the keyboard
  newRot = atan2(mouseY - height/2, mouseX - width/2);    // 
  rotAngle = originalRotAng + newRot - originalTouchAng;  // new angle for the rotation of the letters
}
1 Like

I don’t think this works either for what I want because I need to be able to rotate, in this case, the lines as many times as I want over and over again back and forth.
This is my circular image that rotates, and depending on the letter that I want to write, I drag the image wherever I want to, to get that specific letter at the top. Nothing seems to work though.
G14
Maybe the problem is the second code I wrote for the rotation that doesn’t return a rotAngle in between 0 and 2pi. If you could help me rewrite the original code for the rotation to be able to continue rotating from the position the image is left off, when I stop dragging in a certain position and start dragging again in a differente one, it’ll make things easier, because this second code I wrote isn’t really doing what I want 100% correctly either, as I said earlier. Thank you so much!

There are a number of subtle issues here.

One is to constrain your dragging so that it always results in an angle from 0-TWO_PI.

There are many ways to do that. Here is one approach:

float angle;

void mouseDragged() {
  // rotate left or right, slow or fast
  angle += (pmouseX-mouseX)*0.003;
  // constrain
  if(angle<0) angle = angle%TWO_PI+TWO_PI;
  if(angle>TWO_PI) angle = angle%TWO_PI;
}

also, if you are using angleAsInt, offset your ring display by a half letter width – this will visually align it correctly with A centered.

rotate(-angle + PI/26.0);

1 Like

Thank you so much, this helped a lot and it really solved the problem I had to be able to continue the rotation from where I leave it. I integrated this in my code but when I do the movement in red starting at S and finishing at F it rotates well untill the orange line then it goes in the oposite direction and when I reach the green line it goes back to the right direction.

1 Like

Note that only the x variable of the mouse is being checked.

As the mouse drags right --> , the wheel turns clockwise.
As the mouse drags left <-- , the wheel turns counter-clockwise.

1 Like

Thank you so much, this helped tremendously and I was able to adapt my project and finish it with your help. Just out of curiosity do you know how I can make the circle rotate with both the mouse’s variables being checked, so that I can rotate it correctly all around?

1 Like

Supposing you only know three coordinates:

  1. the center of your wheel, wx, wy
  2. the mouse, x, y
  3. the previous mouse position, px, py

Could you compute whether the mouse was traveling clockwise or counterclockwise around the wheel, and how fast?

There are several ways to solve this. Look at functions like atan2(), and PVector methods like heading().

A warning – this has an edge case where the angle of the mouse positions crosses the 0 radians line. So if your px, py is at 359 degrees and your x, y is at 1 degree, it could be interpreted as violently moving one way around the circle, when actually you moved a tiny bit the other way around the circle. There are ways to solve that – but start by finding the angles and comparing them first.

…ah – see also the built-in: PVector.angleBetween();

1 Like

Thanks, I will look into it.

Hi again, I was wondering if there’s a value so that the circle rotates exacly at the speed of the mouse, to be able to have more control over the rotation?

Yes – is this for moving the mouse left-right, or moving it in a circle?

The mouse moves a certain absolute distance – say 3 pixels, or 10 pixels.

Now you need to change the angle of rotation so that your letters move the same amount.

In order to do that, you need to calculate the circumference of the circle going through the letters (the distance of one full rotation), and then see how many radians (or degrees) it would take to achieve a fraction of that. If the mouse moved 3, and your circumference was 100, then the mouse moved 3/100, or 3% of the distance around the circle. How much should you rotate the circle in radians to make the circle rotate by 3% of its circumference – the same amount that the mouse moved?