# Mouse Gesture Recognition

This topic is 4267 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi, I'm writing a program to read in mouse gestures and record the direction they are being made in (same idea as 'drawing' spells in black and white). having a few problems with the geometary though. have some code:

void CheckForNewGesture(Mouse* mouse, Gesture* lastGesture)
{
int lastPoint[2];		//Last recorded gesture coordinate
int mousePosition[2];	//Current mouse cursor position
int commonPoint[2];		//Common point between the previous 2 vectors
int sideLengths[2];		//Lengths of the vectors between the two previous points
int hypotenuse;			//Length of the hypotenuse
int i = 0;					//Counter
long float sineFactor;		//value that b/SinB will equal, using the sine rule
float sineB, b, B;			//Used to find angle of line
char buffer[100];
bool done = false;
ofstream myfile;		//For debug

//////
//Find coordinates of last point
//////

//Itterate to end of list
if(lastGesture->next != 0)
{
while(lastGesture->next != 0)
{
lastGesture = lastGesture->next;
}
}

//Find where the begin point of the last line is (we have no end point yet remember)
lastPoint[0] = lastGesture->beginPoint[0];
lastPoint[1] = lastGesture->beginPoint[1];

//Find coordinates of current point
mousePosition[0] = mouse->x;
mousePosition[1] = mouse->y;

//Use triangle to assertain length of vector.  We have 2 points so use them to find
//A point common to both vectors, then use pythagoras to find the length of the vector
//that passes through both mouse pos and last point

//Take horizontal component of mouse
commonPoint[0] = mousePosition[0];

//Take vertical component of last gesture
commonPoint[1] = lastPoint[1];

//Use these 3 coordinates to find the lengths of the sides that aren't the
//Hypotenuse and therefore, find the length of the hypotenuse

sideLengths[0] = commonPoint[0] - lastPoint[0];
if(sideLengths[0] < 0)	//correct for negative length
{
sideLengths[0] *= -1;
}

sideLengths[1] = commonPoint[1] - mousePosition[1];
if(sideLengths[1] < 0)	//correct for negative length
{
sideLengths[1] *= -1;
}

/*Using these lengths, which we know to be posative, we can find the length of
the hypotenuse*/

//hypotenuse = sum of the other two sides
hypotenuse = sideLengths[0] + sideLengths[1];

/*  a       b        c
---  =  ----  =  ---
sinA    sinB     sinC

we know a b c and sinC, so if we find c/sinC  and we know b, we can find sin B

*/

sineFactor = hypotenuse;  //(sine 90 is 1, so just don't
//bother to avoid rounding issues)

b = sideLengths[1];	//length of side b

sineB = b/sineFactor;

B = asinf(sineB);	//To give us inverse sine, and the final angle

if(hypotenuse>=NODE_DISTANCE)
{
myfile.open ("example.txt");
//Complete the gesture we entered the function with
lastGesture->endPoint[0] = mousePosition[0];
lastGesture->endPoint[1] = mousePosition[1];
lastGesture->angle = sineB;
Gesture* nextGesture = new Gesture;
lastGesture->next = nextGesture;
//Initialise our new gesture
nextGesture->previous = lastGesture;
nextGesture->next = NULL;
nextGesture->beginPoint[0] = lastGesture->endPoint[0];
nextGesture->beginPoint[1] = lastGesture->endPoint[1];
nextGesture->invAngle = B;
nextGesture->angle = sineB;

//myfile << "Mouse node position records \n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n"
//	<<"SineB " << sineB << "\nB " << B;

Gesture* listStart = First_Gesture;
while(!done)
{

myfile
<<"\nNode " << i << "\nAngle:" << listStart->angle
<<"\nInverse of Angle:" << listStart->invAngle
<< "\nStart Points:\n X: " << listStart->beginPoint[0] << "  Y: "
<< listStart->beginPoint[1] << "\n End Points:\n X: "
<< listStart->endPoint[0] << " Y: " << listStart->endPoint[1] << "\n";

if(listStart->next == NULL)		//If we're at the end of the list
{
done = true;				//Done
}

else
{
listStart = listStart->next;
i++;
}
}

myfile.close();

//	MessageBox(NULL, NULL, NULL, MB_OK);
}

}


the function takes the start point of the node, and the mouse coordinates and checks the distance between them. if its >100 then it creates a new line. it then uses the sine rule to find the angle the line makes with the vertical. this doesn't work. the gesture class:
class Gesture
{
public:
Gesture* next;			//List pointers
Gesture* previous;
int beginPoint[2];		//Start and end coordinates of line
int endPoint[2];
int direction;			//direction of line
double angle;			//Angle of gesture
double invAngle;			//Inverse sine of angle

};


here's a sample of the output to the text file:
Node 0
Angle:0.514286
Inverse of Angle:-6.27744e+066
Start Points:
X: 221  Y: 444
End Points:
X: 272 Y: 390

Node 1
Angle:0.437956
Inverse of Angle:0.540175
Start Points:
X: 272  Y: 390
End Points:
X: 349 Y: 330

Node 2
Angle:0.403226
Inverse of Angle:0.453324
Start Points:
X: 349  Y: 330
End Points:
X: 423 Y: 280


the problem seems to be when i try to find the inverse sine of the angle. an angle of, say 0.043226 should give 2.4 degrees, but i can't see whats went wrong, unless im missusing the function

##### Share on other sites
Quote:
 Original post by Winegums//hypotenuse = sum of the other two sides

Hypotenuse != sum of the other two sides. Time to brush up on your trigonometry.

Σnigma

##### Share on other sites
Quote:
Original post by Enigma
Quote:
 Original post by Winegums//hypotenuse = sum of the other two sides

Hypotenuse != sum of the other two sides. Time to brush up on your trigonometry.

Σnigma

no? Square of the hypotenuse equals the sum of the squares of the other two sides?

##### Share on other sites
Quote:
Original post by Winegums
Quote:
Original post by Enigma
Quote:
 Original post by Winegums//hypotenuse = sum of the other two sides

Hypotenuse != sum of the other two sides. Time to brush up on your trigonometry.

Σnigma

no? Square of the hypotenuse equals the sum of the squares of the other two sides?

You are correct. However, there seems to be a problem with your algebra. Taking the square root of both sides, you'll end up with:

c = sqrt(a * a + b * b)

Obviously, this is not the same as:

c = a + b

##### Share on other sites
Quote:
Original post by derickdong
Quote:
Original post by Winegums
Quote:
Original post by Enigma
Quote:
 Original post by Winegums//hypotenuse = sum of the other two sides

Hypotenuse != sum of the other two sides. Time to brush up on your trigonometry.

Σnigma

no? Square of the hypotenuse equals the sum of the squares of the other two sides?

You are correct. However, there seems to be a problem with your algebra. Taking the square root of both sides, you'll end up with:

c = sqrt(a * a + b * b)

Obviously, this is not the same as:

c = a + b

yeah but im multiplying a and b by -1 if they are <0 in order to avoid square rooting, wont this work the same?

##### Share on other sites
No. √(a + b) != √a + √b. Try it:
√(9 + 16) = √25 = 5
√9 + √16 = 3 + 4 = 7

Σnigma

##### Share on other sites
	//hypotenuse squared = sum of the squares other two sides	hypotenuse = (sideLengths[0] * sideLengths[0]) + (sideLengths[1] * sideLengths[1]);	//square root hypotenuse	hypotenuse = sqrt((float)hypotenuse);

that look right? i think its right, though my initial problem remains the same (though having this outa the way will sort invariable bugs later).

##### Share on other sites

for right triangles

c^2 = a^2 + b^2 ... c = sqrt(a^2 + b^2)

fot non-right triangles

c^2 = a^2 + b^2 - 2ab cos(C) ... c = sqrt(a^2 + b^2 - 2ab cos(C))

http://mathforum.org/~sarah/hamilton/ham.hypotenuse.html

##### Share on other sites
yeah i know pythagoras theorem, i just didn't use it correctly :P

##### Share on other sites
well thats that bit fixed, but im still having the main problem itself, i assumed inverse sine would give an angle as its output, and i cant quite figure out if i have the right result but have to use it with something, or if the program is indeed just not working.

##### Share on other sites
Google helped me find this golden oldy. That should give you a half-decent platform to work from.

##### Share on other sites
after getting back to pen and paper maths, i've found that it must be some problem with the asinf() function.

takeing two arbitrary points
A (138, 429)
B (214, 362)

and creating a point C (138, 362) by finding the point where those two intersect on the vertical and horizontal, i try to find the angle between side c and side b (angle B).

i can get the angle as SinB = 0.661297, which i believe is correct (both the program and I come up with the same answer. even if its wrong its stil a valid number to use for finding an angle), but when i use asinf of the angle i get another number that is also a decimal. multiplying it by 180 (dont know why i did this, i was vaguley thinking that it may fix the problem with the radians) gives 185.468.

am i using asinf() incorrectly?

##### Share on other sites
its certainly interesting, and presents a new approach to the problem. i'll give using dot products a shot.

##### Share on other sites
still stuck with a very simmilar problem.

float cosTHETA = -0.616093
float theta = acos(cosTHETA) = 2.23457

what am i doing wrong?