Mouse Gesture Recognition

Started by
13 comments, last by Winegums 17 years, 10 months ago
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
Advertisement
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

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?
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
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?
No. √(a + b) != √a + √b. Try it:
√(9 + 16) = √25 = 5
√9 + √16 = 3 + 4 = 7

Σnigma
	//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).



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))



Google/Yahoo is your friend.....

http://search.yahoo.com/search?_adv_prop=web&x=op&ei=UTF-8&fr=op&va=Hypotenuse&va_vt=any&vp=non+right+triangle&vp_vt=any&vo_vt=any&ve_vt=any&vd=all&vf=all&vm=i&fl=0&n=10


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

http://answers.yahoo.com/question/?qid=1006041307108


yeah i know pythagoras theorem, i just didn't use it correctly :P
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.

This topic is closed to new replies.

Advertisement