Arc maximum angle?
in
Programming Questions
•
1 year ago
Paste the following code into Processing (no libraries are required, it should compile just fine for everyone on 1.5.1 except for the font). Move your mouse around and click and drag to draw a red arc. If you drag it past 9 o'clock, you'll see that it flips to the opposite side, and inverts the arc. How do I prevent the arc from inverting like this? I want it to move smoothly past 9 o'clock. Thanks!
- PFont font;
- String[] days = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
- String[] months = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
- float diameter = min(width, height) * 0.75;
- int[] angles = {30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30};
- int[] diameters = {300,350,400,300,350,400,300,350,400,300,350,400};
- String[] times = {"4pm", "5pm", "6pm", "7pm", "8pm", "9pm", "10am", "11am", "12pm", "1pm", "2pm","3pm"};
- int startMouseX, startMouseY;
- float startAngle, startDepth;
- void setup() {
- size(1000,800);
- frameRate(30);
- //font = loadFont("OfficinaSerifStd-Book-48.vlw");
- font = createFont("Arial",32);
- smooth();
- }
- void draw() {
- //if(pmouseX != mouseX && pmouseY != mouseY) {
- update();
- //}
- }
- void mousePressed() {
- startMouseX = mouseX;
- startMouseY = mouseY;
- startAngle = atan2(mouseY-height/2, mouseX-width/2);
- //snap the startAngle to nearest 7.5 degrees.
- if(degrees(startAngle) % 7.5 <= 3.75) {
- startAngle = radians(degrees(startAngle) - degrees(startAngle) % 7.5);
- } else if(degrees(startAngle) % 7.5 > 3.75) {
- startAngle = radians(degrees(startAngle) + (7.5 - degrees(startAngle) % 7.5));
- }
- startDepth = dist(width/2, height/2, mouseX, mouseY);
- }
- void update() {
- background(255);
- //Grid
- stroke(245);
- strokeWeight(1);
- for(int i = 0; i < height; i = i + 20) {
- line(0,i,width,i);
- }
- for(int j = 0; j < width; j = j + 20) {
- line(j,0,j,height);
- }
- stroke(0);
- strokeWeight(2);
- fill(255);
- float lastAng = 0;
- for (int i = 0; i < angles.length; i++){
- arc(width/2, height/2, diameters[i], diameters[i], lastAng, lastAng+radians(angles[i]));
- line(width/2, height/2, width/2 + diameters[i]/2 * cos(lastAng), height/2 + diameters[i]/2 * sin(lastAng));
- line(width/2, height/2, width/2 + diameters[i]/2 * cos(lastAng+radians(angles[i])), height/2 + diameters[i]/2 * sin(lastAng+radians(angles[i])));
- //quarter tick marks
- line(width/2 + diameters[i]/2 * cos(lastAng+radians(7.5)), height/2 + diameters[i]/2 * sin(lastAng+radians(7.5)), width/2 + (diameters[i]-10)/2 * cos(lastAng+radians(7.5)), height/2 + (diameters[i]-10)/2 * sin(lastAng+radians(7.5)));
- line(width/2 + diameters[i]/2 * cos(lastAng+radians(15)), height/2 + diameters[i]/2 * sin(lastAng+radians(15)), width/2 + (diameters[i]-15)/2 * cos(lastAng+radians(15)), height/2 + (diameters[i]-15)/2 * sin(lastAng+radians(15)));
- line(width/2 + diameters[i]/2 * cos(lastAng+radians(22.5)), height/2 + diameters[i]/2 * sin(lastAng+radians(22.5)), width/2 + (diameters[i]-10)/2 * cos(lastAng+radians(22.5)), height/2 + (diameters[i]-10)/2 * sin(lastAng+radians(22.5)));
- //gray arc
- noFill();
- stroke(200,200,200,25);
- strokeWeight(2);
- strokeCap(ROUND);
- arc(width/2, height/2, 425, 425, radians(180), radians(270));
- //quadrant circles
- if(diameters[i] == max(diameters)) {
- noFill();
- stroke(0);
- ellipse(width/2 + diameters[i]/2 * cos(lastAng+radians(angles[i])), height/2 + diameters[i]/2 * sin(lastAng+radians(angles[i])), 25, 25);
- fill(255);
- }
- //times
- fill(0);
- noStroke();
- textAlign(CENTER);
- textFont(font, 12);
- text(times[i], width/2 + (460)/2 * cos(lastAng+radians(angles[i])), height/2 + (460)/2 * sin(lastAng+radians(angles[i])));
- //reset
- fill(255);
- stroke(0);
- lastAng += radians(angles[i]);
- }
- //Red selection
- if(mousePressed) {
- fill(200,0,0,150);
- noStroke();
- //swap startAngle and current angle so that arc draws correctly
- if(atan2(mouseY-height/2, mouseX-width/2) >= startAngle) {
- arc(width/2, height/2, startDepth*2, startDepth*2, startAngle, atan2(mouseY-height/2, mouseX-width/2));
- } else if(atan2(mouseY-height/2, mouseX-width/2) < startAngle) {
- arc(width/2, height/2, startDepth*2, startDepth*2, atan2(mouseY-height/2, mouseX-width/2), startAngle);
- }
- println(startAngle);
- } else {
- stroke(200,0,0,100);
- strokeWeight(1.5);
- line(width/2,height/2,mouseX,mouseY);
- }
- //Center circle
- fill(255);
- stroke(0);
- strokeWeight(2);
- ellipse(width/2, height/2, 175, 175);
- //center text
- fill(0);
- noStroke();
- textAlign(CENTER);
- textFont(font, 48);
- text(day(), width/2, height/2 + 18);
- textFont(font, 24);
- text(days[dayOfWeek(day(),month(),year())],width/2, height/2 - 24);
- text(months[month()-1],width/2, height/2 + 40);
- //selection time
- fill(200,0,0,150);
- noStroke();
- textFont(font, 24);
- text(map(startAngle, -PI, PI, 1, 12), width/2 + startDepth, height/2 + startDepth);
- }
- int dayOfWeek(int _day, int _month, int _year) {
- int a = floor((14 - _month)/12);
- int y = _year - a;
- int m = _month + (12 * a) - 2;
- int d = (_day + y + floor(y / 4) - floor(y / 100) + floor(y / 400) + floor((31*m)/12)) % 7;
- return d;
- }
1