# Check direction of the mouse compared to a point in space

Hi, i wonder how to check and know the directions (left,right,up and down) of the mouse compared to a point in space.

``````void setup(){
size(300,300);
}

void draw(){
background(255);
PVector dotPos = new PVector(150,150);
fill(255,0,0);
ellipse(dotPos.x, dotPos.y, 10, 10);

PVector mousePos = new PVector(mouseX,mouseY);
line(dotPos.x, dotPos.y,mousePos.x,mousePos.y);

if(mousePos.y < dotPos.y){
text("up",10,10);
}
if(mousePos.y > dotPos.y){
text("down",10,10);
}
if(mousePos.x < dotPos.x){
text("left",10,10);
}
if(mousePos.x > dotPos.x){
text("right",10,10);
}

}
``````

I know its the wrong way to do it, but I have difficulties with the Switch Statements ( i think this is the good way to do it but i donāt know how)

thanks for your help and time.

just a rewrite with some code styling ideas

``````PVector dotPos = new PVector(150, 150);
PVector mousePos = new PVector(mouseX, mouseY);
String sDir1,sDir2;

void setup() {
size(300, 300);
}

void draw() {
background(255);
draw_mousepos();
}

void draw_mousepos() {
noStroke();
mousePos.set(mouseX, mouseY);
fill(200, 0, 0);
circle(dotPos.x, dotPos.y, 10);
fill(0, 0, 200);
circle(mousePos.x, mousePos.y, 10);
stroke(0,200,0);
line(dotPos.x, dotPos.y, mousePos.x, mousePos.y);

if (mousePos.y < dotPos.y) sDir1 = "up";
else                       sDir1 = "down";

if (mousePos.x < dotPos.x) sDir2 = "left";
else                       sDir2 = "right";
text(sDir1+" "+sDir2, 10, 10);
}

``````
1 Like

Thanks, I did not think about that, i will try it on my code

its solve one of my future problem (checking to have up left/right and down left/right), but i need to have a way to check when its up,down,left and right only too.

? not understand the question,
you do ( needed to ) have 2 separate variables
well you not need to use string variables at first, but the KNOWLEDGE is stored?
while your above code not stored anything AND even overwrite text at same positionā¦

sorry if my question was not clear, what i looking for is a way to check when the mouse is up,down,left and right of the point. I know my first code is wrong and it overwrite text, it was to point my problem and my bad code

Remark

It would be very hard to move the mouse y for example exactly to the y position of the point

Instead you should check for example

• if mouse X is smaller than your point X and
• the distance of your mouse Y from the point Y is smaller than a threshold of letās say 30

`.....dist(0,mouseY, 0, dotPos.y) < 30.....`

then youāre LEFT

Chrisir

ok, i start to understand how to solve my problem. i need to have four āareaā one for each directions and when the mouse is in one of these area my text say the correct direction (area).

something like that

am i right ?

1 Like
``````

PVector dotPos = new PVector(150, 150);
PVector mousePos = new PVector();
String sDir1;

void setup() {
size(300, 300);
background(255);
}

void draw() {
background(255);
draw_mousepos();
}

// -------------------------------------------------------------

void draw_mousepos() {

mousePos.set(mouseX, mouseY);

noStroke();
fill(200, 0, 0);
ellipse(dotPos.x, dotPos.y, 10, 10);
fill(0, 0, 200);
ellipse(mousePos.x, mousePos.y, 10, 10);

stroke(0, 200, 0);
line(dotPos.x, dotPos.y,
mousePos.x, mousePos.y);

sDir1 = "";

if (mousePos.y < dotPos.y-3      && near( mouseX, dotPos.x ) )  sDir1 = "up";
else if (mousePos.y > dotPos.y+3 && near( mouseX, dotPos.x ) )  sDir1 = "down";
else if (mousePos.x < dotPos.x-3 && near( mouseY, dotPos.y ) )  sDir1 = "left";
else if (mousePos.x > dotPos.x+3 && near( mouseY, dotPos.y ) )  sDir1 = "right";

fill(0);
text(sDir1, 10, 10);
}

boolean near( float a, float b) {
return
dist(0, a, 0, b) < 30;
}
//
``````
1 Like

ok so in theory i was right
thanks i gonna test that

1 Like

ok so in theory i was right

No, the checked areas are not round but rectangles in my version:

there are overlapping areas, here the order of the if-else-clauses decidesā¦

``````
PVector dotPos = new PVector(150, 150);
PVector mousePos = new PVector();
String sDir1;

void setup() {
size(300, 300);
background(255);
}

void draw() {
background(255);
draw_mousepos();
}

// -------------------------------------------------------------

void draw_mousepos() {

mousePos.set(mouseX, mouseY);

noStroke();
fill(200, 0, 0);
ellipse(dotPos.x, dotPos.y, 10, 10);
fill(0, 0, 200);
ellipse(mousePos.x, mousePos.y, 10, 10);

stroke(0, 200, 0);
// top
fill(255, 0, 0, 10); // red
rect(dotPos.x-30, 0,
60, dotPos.y - 3);
// bottom
fill(0, 255, 0, 10); //green
rect(dotPos.x-30, dotPos.y + 3,
60, 300);

// right
fill(0, 0, 255, 10); // blue
rect(dotPos.x+3, dotPos.y - 30,
660, 60);
// left
fill(255, 255, 0, 10);
rect(0, dotPos.y - 30,
dotPos.x-3, 60);

stroke(0, 200, 0);
line(dotPos.x, dotPos.y,
mousePos.x, mousePos.y);

sDir1 = "";

if (mousePos.y < dotPos.y-3      && near( mouseX, dotPos.x ) )  sDir1 = "up";
else if (mousePos.y > dotPos.y+3 && near( mouseX, dotPos.x ) )  sDir1 = "down";
else if (mousePos.x < dotPos.x-3 && near( mouseY, dotPos.y ) )  sDir1 = "left";
else if (mousePos.x > dotPos.x+3 && near( mouseY, dotPos.y ) )  sDir1 = "right";

fill(0);
text(sDir1, 10, 10);
}

boolean near( float a, float b) {
return
dist(0, a, 0, b) < 30;
}
//
``````

ok wow so my problem is harder that i imagined

itās not hard at all.

What do you mean?

1 Like

well it create a lot of void between each rectangle, im sure i can modify it by making them wider.

thanks to you, now i can clearly display what im looking for.

this is what im looking for:
4 directions:

8 directions:

iām deeply sorry for wasting yours times by not express myself correctly.

1 Like

in this version we also check if the mouse is near (100) the reference point in the first place, before checking the areas

``````
PVector dotPos = new PVector(150, 150);
PVector mousePos = new PVector();
String sDir1;

void setup() {
size(300, 300);
background(255);
}

void draw() {
background(255);
draw_mousepos();
}

// -------------------------------------------------------------

void draw_mousepos() {

mousePos.set(mouseX, mouseY);

noStroke();
fill(200, 0, 0);
ellipse(dotPos.x, dotPos.y, 10, 10);
fill(0, 0, 200);
ellipse(mousePos.x, mousePos.y, 10, 10);

showFourRects();

stroke(0, 200, 0);
line(dotPos.x, dotPos.y,
mousePos.x, mousePos.y);

sDir1 = "";

if (mousePos.dist(dotPos) < 100) {
if      (mousePos.y < dotPos.y-3 && near( mouseX, dotPos.x ) )  sDir1 = "up";
else if (mousePos.y > dotPos.y+3 && near( mouseX, dotPos.x ) )  sDir1 = "down";
else if (mousePos.x < dotPos.x-3 && near( mouseY, dotPos.y ) )  sDir1 = "left";
else if (mousePos.x > dotPos.x+3 && near( mouseY, dotPos.y ) )  sDir1 = "right";
else { //ignore
}
}//if

fill(0);
text(sDir1, 10, 10);
}

boolean near( float a, float b) {
return
dist(0, a, 0, b) < 30;
}

void showFourRects() {

stroke(0, 200, 0);
// top
fill(255, 0, 0, 10); // red
rect(dotPos.x-30, dotPos.y - 100,
60, 100 - 3);

// bottom
fill(0, 255, 0, 10); //green
rect(dotPos.x-30, dotPos.y + 3,
60, 100-3 );

// right
fill(0, 0, 255, 10); // blue
rect(dotPos.x+3, dotPos.y - 30,
100-3, 60);

// left
fill(255, 255, 0, 10); // other color
rect(dotPos.x-100, dotPos.y - 30,
100-3, 60);

// show circle to symbolie:   if (mousePos.dist(dotPos) < 100) {
stroke(0);
noFill();
ellipse( dotPos.x, dotPos.y, 200, 200);
}
//
``````
2 Likes

totally new approach

uses the angle between mouse and center point

(angle 0 is on the right side, not on the top in processing)

(also remember, itās in radians mostly, not degrees )

``````

// https : // forum.processing.org/two/discussion/10474/find-angle-between-2-points

PVector centerPoint; // the fixed red point

// make an int a String
String[] textFromDir = {
"Right",
"Right,down",
"down",
"down, left",
"left",
"left up",
"up",
"up right",
};

void setup() {
size(1200, 600);
centerPoint = new PVector(width/2, height/2);
}

void draw() {
background(0);

// draw arc
fill(255);
//arc( centerPoint.x, centerPoint.y,
//  430, 430,

// draw a simple cross at centerPoint
crossAtPV(centerPoint);

// show centerPoint in red
ellipsePV(centerPoint);

// get angle
float angle = angleBetweenPV_PV(centerPoint, new PVector(mouseX, mouseY));

angle=fixAngle(angle);

// check Area !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
int dir=0;
float angleInDegrees=degrees(angle);
float scliceDegree = 360/8 ;

dir = 0;

if       ( isBetween (angleInDegrees, 0*scliceDegree, 1*scliceDegree) )  dir = 0;
else  if ( isBetween (angleInDegrees, 1*scliceDegree, 2*scliceDegree) )  dir = 1;
else  if ( isBetween (angleInDegrees, 2*scliceDegree, 3*scliceDegree) )  dir = 2;

else if  ( isBetween (angleInDegrees, 3*scliceDegree, 4*scliceDegree) )  dir = 3;
else  if ( isBetween (angleInDegrees, 4*scliceDegree, 5*scliceDegree) )  dir = 4;
else  if ( isBetween (angleInDegrees, 5*scliceDegree, 6*scliceDegree) )  dir = 5;

else  if ( isBetween (angleInDegrees, 6*scliceDegree, 7*scliceDegree) )  dir = 6;
else  if ( isBetween (angleInDegrees, 7*scliceDegree, 8*scliceDegree) )  dir = 7;

// show the found angle
fill(255, 0, 0); // red
triangleMy(angle);
fill(255); // white

text(angle
+"\n"
+degrees(angle) + "\n" + dir + ": " + textFromDir[ dir ], 23, 23);
}

// --------------------------------------------------------------------

boolean isBetween(float inputValue, float down, float up) {
return
inputValue>down- 360/16 &&
inputValue<up- 360/16;
}
// --------------------------------------------------------------------

float angleBetweenPV_PV(PVector centerPV, PVector movingPV) {

// calc angle : the core of the sketch

PVector d = new PVector();

// calc angle

// delta
d.x = movingPV.x - centerPV.x;
d.y = movingPV.y - centerPV.y;
// angle
float angle1 = atan2(d.y, d.x);

return angle1;
}

void triangleMy(float ang) {

pushMatrix();

translate(centerPoint.x, centerPoint.y);

rotate(ang);

// fill(255); // white shield
triangle(60, 0,
80, -30,
80, 30);

popMatrix();
}

void ellipsePV(PVector pv) {
fill(255, 0, 0); // red
ellipse(pv.x, pv.y, 10, 10);
}

void crossAtPV(PVector pv) {
stroke(255);
line(pv.x, 0, pv.x, height);
line(0, pv.y, width, pv.y);
}
//
float fixAngle(float angle1) {
// if > 2xPI
if (angle1>TWO_PI)
angle1-=TWO_PI;
if (angle1>TWO_PI)
angle1-=TWO_PI;

// if < 0 (negative angles like -40 should be expressed as positive angles like 320)
if (angle1<0.0) {
angle1 = TWO_PI + angle1;
}
if (angle1<0.0)
angle1 = TWO_PI + angle1;

return angle1;
}
//
``````
1 Like

amazing just amazing, i will try it on my code. Many thanks for your patience and answers.
i will check the link too.

2 Likes

new version

``````// https : // forum.processing.org/two/discussion/10474/find-angle-between-2-points
// https://discourse.processing.org/t/check-direction-of-the-mouse-compared-to-a-point-in-space/12883/16

final int UNDEFINED = -1;

PVector centerPoint; // the fixed red point

// make an int dir a String dir
String[] textFromDir = {
"NONE",
"Right",
"Right, down",
"down",
"down, left",
"left",
"left, up",
"up",
"up, right",
};

String text1="";
int dirFromMouse=0;

//---------------------------------------------------------------------------------------

void setup() {
size(1200, 600);
centerPoint = new PVector(width/2, height/2);
}

void draw() {
background(0);

// draw a simple cross at centerPoint
crossAtPV(centerPoint);

// show centerPoint in red
ellipsePV(centerPoint);

//get mouse pvector
PVector mousePV=new PVector(mouseX, mouseY);

// get angle
float angle = angleBetweenPV_PV(centerPoint, mousePV);

angle=fixAngle(angle);

// check Area !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
float angleInDegrees=degrees(angle);
float scliceDegree = 360/8 ;

dirFromMouse = UNDEFINED;

// dist mouse center must be < 240
if (centerPoint.dist(mousePV)<200) {

if       ( isBetween (angleInDegrees, 0*scliceDegree, 1*scliceDegree) )  dirFromMouse = 0;
else  if ( isBetween (angleInDegrees, 1*scliceDegree, 2*scliceDegree) )  dirFromMouse = 1;
else  if ( isBetween (angleInDegrees, 2*scliceDegree, 3*scliceDegree) )  dirFromMouse = 2;

else if  ( isBetween (angleInDegrees, 3*scliceDegree, 4*scliceDegree) )  dirFromMouse = 3;
else  if ( isBetween (angleInDegrees, 4*scliceDegree, 5*scliceDegree) )  dirFromMouse = 4;
else  if ( isBetween (angleInDegrees, 5*scliceDegree, 6*scliceDegree) )  dirFromMouse = 5;

else  if ( isBetween (angleInDegrees, 6*scliceDegree, 7*scliceDegree) )  dirFromMouse = 6;
else  if ( isBetween (angleInDegrees, 7*scliceDegree, 8*scliceDegree) )  dirFromMouse = 7;
else {
// ignore
}
}//if

// show red lines
for (int i = 0; i < 9; i++) {
stroke(255, 2, 2); // RED
line(centerPoint.x, centerPoint.y,
}

if (dirFromMouse>UNDEFINED) {
// show yellow triangle (when mouse on)
stroke(255, 2, 2);
int i2 = dirFromMouse+1;
fill(240, 255, 44); // YELLOW
stroke(255, 2, 2); // RED
trianglePV ( centerPoint,
getPointOnCircle ( centerPoint, radians(dirFromMouse*scliceDegree- 360/16), 90 ),
getPointOnCircle ( centerPoint, radians(i2          *scliceDegree- 360/16), 90 ) );
}

// show the red triangle
fill(255, 0, 0); // red
triangleMy(angle);
fill(255); // white

// upper left corner
text(angle
+"\n"
+degrees(angle)
+ "\n"
+ dirFromMouse
+ ": "
+ textFromDir[ dirFromMouse+1 ],
23, 23);

// upper right corner: on mousePressed()
fill(255);
text(text1,
width-210, 23);
}

// ------------------------------------------------------------------------------------------------

void mousePressed() {
switch(dirFromMouse) {

case UNDEFINED:
text1="";
break;

default:
text1 = "We got "
+textFromDir[ dirFromMouse+1 ];
break;
}//switch
}//func

// --------------------------------------------------------------------

boolean isBetween(float inputValue, float down, float up) {
return
inputValue>down- 360/16 &&
inputValue<up- 360/16;
}

// --------------------------------------------------------------------

float angleBetweenPV_PV(PVector centerPV, PVector movingPV) {

// calc angle : the core of the sketch

PVector d = new PVector();

// calc angle

// delta
d.x = movingPV.x - centerPV.x;
d.y = movingPV.y - centerPV.y;
// angle
float angle1 = atan2(d.y, d.x);

return angle1;
}

void triangleMy(float ang) {
pushMatrix();
translate(centerPoint.x, centerPoint.y);
rotate(ang);
fill(255); // white
triangle(60, 0,
80, -30,
80, 30);
popMatrix();
}

void ellipsePV(PVector pv) {
fill(255, 0, 0); // red
ellipse(pv.x, pv.y, 10, 10);
}

void trianglePV(PVector pv1, PVector pv2, PVector pv3) {
triangle (pv1.x, pv1.y,
pv2.x, pv2.y,
pv3.x, pv3.y);
}

void crossAtPV(PVector pv) {
stroke(255);
line(pv.x, 0, pv.x, height);
line(0, pv.y, width, pv.y);
}

PVector getPointOnCircle ( PVector center, float angle, float radius ) {
// calcs a point on a circle from some data
return
new PVector(
}

float fixAngle(float angle1) {
// repairs / beautify angle

// if > 2xPI
if (angle1>TWO_PI)
angle1-=TWO_PI;
if (angle1>TWO_PI)
angle1-=TWO_PI;

// if < 0 (negative angles like -40 should be expressed as positive angles like 320)
if (angle1<0.0) {
angle1 = TWO_PI + angle1;
}
if (angle1<0.0)
angle1 = TWO_PI + angle1;

return angle1;
}
//
``````
4 Likes

There is a way to get rid of those if-else statements for checking the directions to shrinkify the codes and makes life easier.

I came with this.

``````
final int DIRS = 16;
//final int DIRS = 8;
//final int DIRS = 4;

// IF 16 DIRECTIONS ARE NEEDED
String[] dirName ={
"W",
"WNW",
"NW",
"NNW",
"N",
"NNE",
"NE",
"ENE",
"E",
"ESE",
"SE",
"SSE",
"S",
"SSW",
"SW",
"WSW",
"W"
};

// IF 8 DIRECTIONS ARE NEEDED
String[] dirName2 ={
"W",
"NW",
"N",
"NE",
"E",
"SE",
"S",
"SW",
"W"
};

// IF 4 DIRECTIONS ARE NEEDED
String[] dirName3 ={
"W",
"N",
"E",
"S",
"W"
};

PVector origin;
void setup() {
stroke(255);
fullScreen();
fill(255);
origin = new PVector(width/2, height/2);
textSize(30);
}

void draw() {
background(51);
fill(255);
text(DIRS + " DIRECTIONS", 100, 60);
int dirId = pointToward(mouseX, mouseY);
text(dirName[dirId], 100, 100); // 16 directions
}

float r = 300; // FIELD RADIUS
int pointToward(float x, float y) {
PVector point = new PVector(x, y);
PVector dir = PVector.sub(point, origin);
dir.normalize();
// Get the nearest direction
int angleMultiplier = round((DIRS) * theta/TWO_PI);
theta = angleMultiplier * TWO_PI/(DIRS);

// Get direction ID
int dirId = angleMultiplier + (DIRS)/2;

//drawing
float triggerR = 3*r/DIRS; //TRIGGER RADIUS
noFill();
for (int i = -DIRS/2; i < DIRS/2; i++) {
float cx = cos(i * TWO_PI/DIRS) * r + origin.x;
float cy = sin(i * TWO_PI/DIRS) * r + origin.y;
line(origin.x, origin.y, cx, cy);
ellipse(cx, cy, triggerR*2, triggerR*2);
}

// check if it triggers the checking radius
float tx = cos(theta) * r + origin.x;
float ty = sin(theta) * r + origin.y;
float d = dist(tx, ty, point.x, point.y);
if (d < triggerR) {
fill(255);
ellipse(tx, ty, triggerR*2, triggerR*2);
fill(0, 255, 100);
text("TRIGGERED", 100, 150);
//-----------------------------------DO SOMETHING HERE-----------------------------
//text(dirName2[dirId], 100, 100); // 8 directions
//text(dirName3[dirId], 100, 100); // 4 directions
}
return dirId;
}

``````
3 Likes

Thanks for all the versions, i use the first 8 direction option, its perfect.

Thank you all