We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpPrograms › cheking if mouse is inside an arc
Page Index Toggle Pages: 1
cheking if mouse is inside an arc? (Read 1312 times)
cheking if mouse is inside an arc?
May 28th, 2008, 9:27pm
 
Hi! Thank you for having a look at my problems!
I´d like to define the space inside an arc.
In order to be able to check if the mouseXY is inside of that arc.
It´s obvious that I need some mathematical formula that describes the space. A = PI* r^2 * angle/360 .... ok now I know the space in between the arc (how big it is) but I just don´t get it how to combine that with the mouse coordinates or Coordinates in General ? I mean by calculating that formula I have only a number in the end. So I guess I maybe need some variables? I don´t know I´m just stuck and don´t get any further here...

thanks for the any help!
Re: cheking if mouse is inside an arc?
Reply #1 - May 29th, 2008, 2:35am
 
A circle mathematic modelation is the following:

(x - a)^2 + (y - b)^2 = R^2, where (a,b) is the center of the circle and R is the radius, and is valid in the domain [a-R,a+R], for the variable x.

An arc can be modeled as the circle, but the domain will be different, you'll need to calculate the coordinates of the extremes of the arc (maybe you'll also have restrictions in y).

For example:
An arc of 180º, the extreme coordinates would be (a-R,b) and (a+R,b), and the variable y would be always >= b. The result would be different if diameter wasn't parallel with the x axis.

In the example, considering by arc the circular sector between the arc and the line that goes from (a-R,b) to (a+R,b), the mouse would be inside the arc if mouseY >= b, a-R <= mouseX <= a+R and (x-a)^2 + (y-b)^2 <= R^2

If u didn't understand anything, search the Internet for Analytic Geometry (circle), and u may find something

Guess I was sufficient clear...
Re: cheking if mouse is inside an arc?
Reply #2 - May 29th, 2008, 9:04am
 
Oh, I wrote a sketch some time ago to check for arc-collision. I can't find it... If I do, I'll upload it here. But here's how I did :

Your arc is defined by :
- a center point (x, y)
- a radius (r)
- two angles (start and end) between 0 and 2*PI or -PI and PI.

So first, check if the mouse pointer is not so far from the center : if (sq(mouseX - x) + sq(mouseY - y) <= sq(r)).

Then, use atan2(mouseY - y, mouseX - x) and check if the angle returned is between the 2 angles that define your arc.
Re: cheking if mouse is inside an arc?
Reply #3 - May 29th, 2008, 1:55pm
 
thank you both for your responses!
I tried with the solution of antiplastik.
Seems to work almost fine for me but my if clause is true for the whole angle of the arc, not only inside the arc.

So thats my code:

int x =100;
int y =100;
int r =200;
boolean nearCenter = false;

void setup(){
background(0);
size(400,400);
}

void draw(){
 
arc(x, y, r, r, 0, PI/4);
//arc(x, y, width(r), height(r), start, stop)
if ((sq(mouseX - x) + sq(mouseY - y)) <= sq(r)){
nearCenter = true;
 }
float a = atan2(mouseY - y, mouseX - x);  
if ((nearCenter == true)&&(a>0)&&(a<PI/4)){
  println("YO");
  }
println(a);
}

has anyone a clue on that?
thanks!
Re: cheking if mouse is inside an arc?
Reply #4 - May 29th, 2008, 3:03pm
 
I guess it should be
Code:
if ((sq(mouseX - x) + sq(mouseY - y)) <= sq(r)){
nearCenter = true;
} else {
nearCenter = false;
}

or declare the nearCentre variable local to the method. Now once the mouse has been "inside the arc" nearCentre is always true.
Re: cheking if mouse is inside an arc?
Reply #5 - May 29th, 2008, 7:14pm
 
Thanks but that´s not the Problem.

In the following code I´m checking if the mouse is inside the arc. The last time I tried it with...
if ((sq(mouseX - x) + sq(mouseY - y)) <= sq(r)){

but with that the mouse was in the arc even it was just in the right angle. So I tried adding some numbers and now it works...
if ((sq(mouseX - x+96) + sq(mouseY - y+40)) <= sq(r)){

.. but its not very exact. And I have like 80 arcs! I dont want to trie out that shit every time. There has to be a clean solution for that problem.

Please can anyone tell me how to do this?

Ah almost forgotten...
here´s the modified code

int x =100;
int y =100;
int r =200;
boolean nearCenter = false;
int yo = 0;

void setup(){
background(155);
size(400,400);
}

void draw(){
fill(yo);  
arc(x, y, r, r, 0, PI/4);
//arc(x, y, width(r), height(r), start, stop)
if ((sq(mouseX - x+96) + sq(mouseY - y+40)) <= sq(r)){
nearCenter = true;
 }else{
    nearCenter = false;}
float a = atan2(mouseY - y, mouseX - x);  
if ((nearCenter == true)&&(a>0)&&(a<PI/4)){
  println("YO");
yo = 190;  
}else {
  yo =0;
  }
println(a);
//println(nearCenter);
}


Thanks for the help!
Re: cheking if mouse is inside an arc?
Reply #6 - May 29th, 2008, 9:19pm
 
The base was good, but the so called r is actually a diameter...
Here is my version of your code:
Code:
int x = 100;
int y = 100;
int d = 200;
float a1 = 0, a2 = PI/4;

void setup()
{
background(0);
size(400, 400);
}

void draw()
{
fill(#00FF00); ellipse(x, y, d, d);
boolean nearCenter = sqrt(sq(mouseX - x) + sq(mouseY - y)) <= d /2;
float a = atan2(mouseY - y, mouseX - x);
if (nearCenter && a >= a1 && a <= a2)
{
fill(#FF0000);
}
else
{
fill(#0000FF);
}
arc(x, y, d, d, a1, a2);
}

To be generic, it needs finer tests on angles.
Re: cheking if mouse is inside an arc?
Reply #7 - May 29th, 2008, 10:27pm
 
With angle normalization:
Code:
int x = 100;
int y = 100;
int d = 200;
float a1 = 0, a2 = 0;
float na1, na2;

// Get any angle, between -infinite and +infinite, and clamp it between 0 and 2*PI
float normalizeAngle(float angle)
{
// First, limit it between -2*PI and 2*PI, using modulo operator
float na = angle % (2 * PI);
// If the result is negative, bring it back to 0, 2*PI interval
if (na < 0) na = 2*PI + na;
return na;
}

void setup()
{
background(0);
size(400, 400);
}

void draw()
{
if (frameCount % 20 == 0)
{
// Every 20 frames, change the angles in opposite directions with different speeds,
// to make interesting range of angles
a1 += PI/11;
a2 -= PI/7;
}
// Normalize angles
na1 = normalizeAngle(a1);
na2 = normalizeAngle(a2);
// Draw the circle base of the arc
fill(#00FF00); ellipse(x, y, d, d);
// Find the angle between the mouse position and the x axis from the center of the circle
float a = normalizeAngle(atan2(mouseY - y, mouseX - x));
// Find if the mouse is close enough of center
boolean nearCenter = sqrt(sq(mouseX - x) + sq(mouseY - y)) <= d /2;
boolean between;
// First case: small arc, below half of circle
if (na1 < na2)
{
// Just check we are between these two angles
between = na1 <= a && a <= na2;
}
else // Second case: wide arc, more than half of circle
{
// Check we are NOT in the remaining (empty) area...
between = !(na2 <= a && a <= na1);
}
if (nearCenter && between)
{
// Both conditions (distance and angle) fulfilled: show arc in red
fill(#FF0000);
}
else
{
// Not in arc: show it in blue
fill(#0000FF);
}
// Just draw the wanted arc: I use the original angles to ensure the algorithm is sound
arc(x, y, d, d, a1, a2);
}

[EDIT] Added comments to help understand the algorithm.
Re: cheking if mouse is inside an arc?
Reply #8 - May 29th, 2008, 11:32pm
 
OOOOOhhhh my god !

...

I really don´t know how much time went into this but I would have needed like a week or I don´t know.

I´m totally confused at the moment...
I just didnt expect a answer on my question that generous.


Thanks so much mate!
You are my hero.
Re: cheking if mouse is inside an arc?
Reply #9 - May 30th, 2008, 1:10am
 
Apparently it took me an hour to handle angle normalization.
It is my pleasure, I learn stuff along the process... Wink
Re: cheking if mouse is inside an arc?
Reply #10 - Jun 4th, 2008, 5:07pm
 
Just modularized it a bit to ease reuse.
Code:
// Data of arc
int x = 100;
int y = 100;
int d = 200;
float a1 = 0, a2 = 0;

void setup()
{
background(0);
size(400, 400);
}

void draw()
{
if (frameCount % 20 == 0)
{
// Every 20 frames, change the angles in opposite directions with different speeds,
// to make interesting range of angles
a1 += PI/11;
a2 -= PI/7;
}
// Draw the circle base of the arc
fill(#00FF00); ellipse(x, y, d, d);
if (IsPointInsideArc(mouseX, mouseY, x, y, d, a1, a2))
{
// Both conditions (distance and angle) fulfilled: show arc in red
fill(#FF0000);
}
else
{
// Not in arc: show it in blue
fill(#0000FF);
}
// Just draw the wanted arc: I use the original angles to ensure the algorithm is sound
arc(x, y, d, d, a1, a2);
}

// Get any angle, between -infinite and +infinite, and clamp it between 0 and 2*PI
float normalizeAngle(float angle)
{
// First, limit it between -2*PI and 2*PI, using modulo operator
float na = angle % (2 * PI);
// If the result is negative, bring it back to 0, 2*PI interval
if (na < 0) na = 2*PI + na;
return na;
}

// Return true if the given point is inside an arc of circle.
// Doesn't work with arc of ellipse...
boolean IsPointInsideArc(float pointX, float pointY,
float centerX, float centerY, float diameter, float angle1, float angle2)
{
// Find if the mouse is close enough of center
boolean nearCenter = sqrt(sq(pointX - centerX) + sq(pointY - centerY)) <= d /2;
if (!nearCenter)
return false; // Quick exit...

// Normalize angles
float na1 = normalizeAngle(angle1);
float na2 = normalizeAngle(angle2);
// Find the angle between the point and the x axis from the center of the circle
float a = normalizeAngle(atan2(pointY - centerY, pointX - centerX));

boolean between;
// First case: small arc, below half of circle
if (na1 < na2)
{
// Just check we are between these two angles
between = na1 <= a && a <= na2;
}
else // Second case: wide arc, more than half of circle
{
// Check we are NOT in the remaining (empty) area...
between = !(na2 <= a && a <= na1);
}
return between;
}
Re: cheking if mouse is inside an arc?
Reply #11 - Jun 4th, 2008, 9:51pm
 
The java.awt.geom package contains an Arc2D class with a helpful contains() method.

Here is a sketch I made some time ago, using this method (press a key to rotate the shape) :

Quote:


PArc2D range;

void setup() {
 size(320, 240);
 smooth();
 range = new PArc2D(width/2, height/2, 100, 0, PI/4);
}

void draw() {
 background(255);
 noStroke(); fill(200, 200, 200);
 if (range.contains(mouseX, mouseY)) fill(255, 200, 50);
 range.display();
}

void keyPressed() {
 range.turn(-PI/12);
}

class PArc2D {
 java.awt.geom.Arc2D arc2D;
 PArc2D(float x, float y, float w, float a, float e) {
   // x, y : center
   // w : width
   // a : direction (point at)
   // e : extent angle
   arc2D = new java.awt.geom.Arc2D.Float(x-w/2, y-w/2, w, w, degrees(-a-e), degrees(e*2), java.awt.geom.Arc2D.PIE);
 }
 void setXY(float x, float y) {
   arc2D.setArcByCenter((double)x, (double)y, arc2D.getWidth()/2, arc2D.getAngleStart(), arc2D.getAngleExtent(), java.awt.geom.Arc2D.PIE);
 }
 void turn(float ra) {
   arc2D.setAngleStart(arc2D.getAngleStart() - degrees(ra));
 }
 void display() {
   float x = (float)arc2D.getX();
   float y = (float)arc2D.getY();
   float w = (float)arc2D.getWidth();
   float as = -radians((float)arc2D.getAngleStart());
   float ae = radians((float)arc2D.getAngleExtent());
   arc(x + w/2, y + w/2, w, w, as - ae, as);
 }
 boolean contains(float x, float y) {
   return arc2D.contains(x, y);
 }
}


Re: cheking if mouse is inside an arc?
Reply #12 - Jun 4th, 2008, 10:55pm
 
thanks PhiLho! I really apprechiate that you explained it so well. Really nice of you!

Also thanks to Antiplastik (but i think I don´t really understand the code but maybe I will )
Re: cheking if mouse is inside an arc?
Reply #13 - Jun 5th, 2008, 1:53pm
 
Cool antiplastik, I didn't know such class existed...
It has the advantage of working for ellipse based arcs, unlike my code which works only for circle based arcs.
Re: cheking if mouse is inside an arc?
Reply #14 - Jun 5th, 2008, 4:52pm
 
yes, java.awt.geom is awesome ^^

it was just a bit tricky to set up the class, since Processing arc() method doesn't deal with angles as java.awt.geom.Arc2D does, but once created, it is very easy to reuse.
Page Index Toggle Pages: 1