drawing line by tracking finger in opencv - opencv

I am new to opencv, I want to detect if one finger is up it will draw a line on screen, I read some tutorials, I am tracking the finger Point successfully and it is being updated continuously.I do something like below. when I move the finger it does draw a short red line but it is transient and be disappeared right after. I need the drawing line to stay there but I have no idea how to do it and I can not find solution,I am really Hoping to hear from you, thank you very much.
int lastx = -1;
int lasty = -1;
void trackingfinger(....)
{
.........
if(drawing == true)
draw(BGR_frame,Point finger)
}
void draw(BGR_frame, Point finger)
{
int x = finger.x;
int y = finger.y;
if (lastx > 0 && lasty > 0 && x > 0 && y > 0)
{
line(BGR_frame, Point(x, y), Point(lastx, lasty), Scalar(0, 0, 255), 2);
}
lastx = x;
lasty = y;
}
int main (void)
{
while(true)
{
..... the function is called here.
}
}

If I understood the presented part of code correctly, you cannot do it this way. How do you decide when the drawing should begin and when it should end? The line function needs one starting point and one ending point.
Either "draw" pixel by pixel, all the coordinates where the finger is moving, if you want it to follow the finger => in the end, it will not be one line
Or implement some action, that will tell "now the finger points to starting point" and "now it points to ending point"

Related

What to do to improve this jumping code?

I have this iOS game where the frog jumps from lily pad to lily pad. The game is in the vertical orientation, and the perspective I'm trying to achieve is an aerial view, where the user looks at the frog and scenery from the top. The frog jumps from lily pad to lily pad and the code is the following:
Bounce Method:
-(void)bounce {
[self jumpSound];
if (frog.center.y > 450) {
upMovement = 2;
}
else if (frog.center.y > 350) {
upMovement = 1.5;
}
else if (frog.center.y > 250) {
upMovement = 0.5;
}
}
and the lilypad movement:
-(void)lilyPadMovement {
if (CGRectIntersectsRect(frog.frame, lily.frame) && (upMovement <=-1)){
[self bounce];
[self lilyPadFall];
if (lilyPadUsed == NO) {
addedScore = 1;
lilyPadUsed = YES;
}
}
}
Essentially what I'm trying to fix is the frogs bouncing movement. When the frog lands in the middle of a lily pad and bounces it doesn't look bad, but at times the frog will simply touch the sides of the lil pad and the bounce method will be called because the rectangles intersected. I tried CGRectContainsRect but it made the game to hard, because it delayed the speed of the game. So I'm not sure how to fix it. Any suggestions?
You really want to know if there's a sufficient overlap to enable the frog to push off, rather than fall in the water. So maybe the distance between the centers has to be less than X, where you tune X based on what looks good.
For example ( using the Pythagorean formula) :
//having defined this function:
inline float square (float a) { return a*a; }
//change intersect test to:
if (((square(frog.center.x-lily.center.x) + square(frog.center.y-lily.center.y)) < 10000) &&
(upMovement <= -1)) { ...

CCMoveTo causing jumps

I am making a game using Cocos2D and Kobold2D. In my game, I have a ship that I want to move to where the player taps, using this code:
KKInput * input = [KKInput sharedInput];
CGPoint tap = [input locationOfAnyTouchInPhase:KKTouchPhaseBegan];
if (tap.x != 0 && tap.y != 0)
{
[ship stopAllActions]; // Nullifies previous actions
int addedx = tap.x - ship.position.x;
int addedy = tap.y - ship.position.y;
int squaredx = pow(addedx, 2);
int squaredy = pow(addedy, 2);
int addedSquares = squaredx + squaredy;
int distance = pow(addedSquares, 0.5);
[ship runAction: [CCMoveTo actionWithDuration:distance/100 position:tap]];//makes ship move at a constant speed
}
The ship generally moves as I expect it to. However, if I tap near the ship, instead of smoothly moving to the tap location, it jumps to that location. How do I fix this?
Your logic is right but your calculation is lack precision.
Especially when you calc the fly time as distance/100. That means when distance < 100 the result is 0, so the ship is jumping to the destination.
Basically, you should use float instead of int when dealing with positions in cocos2d. And there are couple functions can do the work nicely.
You may change your code to this:
[ship stopAllActions]; // Nullifies previous actions
float distance = ccpDistance(tap, ship.position);
[ship runAction: [CCMoveTo actionWithDuration:distance/100.0f position:tap]];
First of All you can use the ccpDistance function of cocos2d to calculate distance between two point.
And it jumps because if u tap too near the distance is too small suppose 2 or 10 ... the you are dividing it on 100
e.g 5/100 = 0.05 which is too low that's why it jumps.
You need to handle it manually i think some thing like if(speed<1) speed++; adding 1 to speed. shortcut solution :)

How to simulate Gravity in z-axis in a 2D game with Sprite Kit

I'm writing a 2D ball game with sprite kit on iOS 7 and currently struggling on one physic simulation.
To explain the expected behavior: if a ball is dropped into a tea cup, it will circle around, loosing speed and finally stand still in the center of the cup.
I've tried to archive this with gravity, but gravity in sprite kit only applies to vertical X and Y axis, not Z-axis. I also tried to use level gravity by switching gravity values with small physic bodies on beginContact depending on the current ball position in the tea cup. But some contacts are dropped and the result is far away to look realistic.
I think I need to solve this in the update: method, but I have no idea which way to go.
Any advice greatly welcome and I need to mention that I'm not an expert on math, please explain your path to go. :-)
Since there's no built-in support for this kind of behavior in SpriteKit, rather than trying to hack existing functions to get what you want, you're probably better off integrating some published 2D physics formulas in your x,y 2D world. I would think that something like simulating magnetic or a homing behavior might be right for this.
A simple example would be something like (in the scene's -update: method):
CGFloat strength = 0.5; //(some scaling value)
CGPoint ballLocation = ball.position;
CGPoint cupLocation = cup.position;
[ball.physicsBody applyForce:CGVectorMake((cupLocation.x - ballLocation.x) * strength,
(cupLocation.y - ballLocation.y) * strength)];
following Joshd great idea, I have created an NSArray with like explained in my comment above. Hope this snippets does help some others...
The result could be found on youtube: http://youtu.be/Uephg94UH30
Sorry for the bad Airplay frame rate, it runs perfectly smooth on my iPad
The -update: functions does the work but only triggered if _meditationIsActive. This bool is set in -didBeginContact: when any ball gets in contact with a hole.
if (_lastCheck > 0.005)
{
if (_meditationIsActive)
{
CGFloat strength = 0.1; //(some scaling value)
CGPoint ballLocation;
CGPoint holeLocation;
for (MeditationHole * holeObj in _meditationHoles)
{
if (holeObj.connectedMeditationBall != nil)
{
ballLocation = holeObj.connectedMeditationBall.position;
holeLocation = holeObj.position;
[holeObj.connectedMeditationBall.physicsBody applyForce:CGVectorMake(
(holeLocation.x - ballLocation.x) * strength, (holeLocation.y - ballLocation.y) * strength)];
}
}
_meditationIsActive = [self doesMeditationApplies];
}
_lastCheck = 0;
}
At the end I'm checking if there is a valid ball out of the array in contact with a hole to avoid checking during every update. This is done with the following function where position check +/- 48 detects a ball close to a hole and +/-1 ball stands still
- (bool)doesMeditationApplies
{
bool isInArea = NO;
int perfectMatchCount = 0;
for (MeditationHole * holeObj in _meditationHoles)
{
if (holeObj)
{
if (holeObj.connectedMeditationBall != nil)
{
MeditationBall * ballObj = holeObj.connectedMeditationBall;
if ((ballObj.position.x >= holeObj.position.x - 48) &&
(ballObj.position.x <= holeObj.position.x + 48) &&
(ballObj.position.y >= holeObj.position.y - 48) &&
(ballObj.position.y <= holeObj.position.y + 48))
{
isInArea = YES;
}
else
{
holeObj.connectedMeditationBall = nil;
}
if ((ballObj.position.x >= holeObj.position.x - 1) &&
(ballObj.position.x <= holeObj.position.x + 1) &&
(ballObj.position.y >= holeObj.position.y - 1) &&
(ballObj.position.y <= holeObj.position.y + 1))
{
perfectMatchCount++;
isInArea = YES;
}
}
}
}
if (perfectMatchCount == _oxydStonesMax)
{
if (_sound)
{
self.pauseMusicPlaybackBlock(YES);
NSLog(#"PlaySound Meditation");
[OxydScene PlaySystemSound:#"Win2"];
}
isInArea = NO;
[self showPauseScreenWithWin:YES andPauseOnly:NO];
}
return isInArea;
}

Keep Rotating sprite from going off screen, but bounce back.

Im using a technique to control a sprite by rotating left/right and then accelerating forward. I have 2 questions regarding it. (The code it pasted together from different classes due to polymorphism. If it doesn't make sense, let me know. The movement works well and the off screen detection as well.)
When player moves off screen i call the Bounce method. I want the player not to be able to move off screen but to change direction and go back. This works on top and bottom but left and right edge very seldom. Mostly it does a wierd bounce and leaves the screen.
I would like to modify the accelerate algorithm so that i can set a max speed AND a acceleration speed. Atm the TangentalVelocity does both.
float TangentalVelocity = 8f;
//Called when up arrow is down
private void Accelerate()
{
Velocity.X = (float)Math.Cos(Rotation) * TangentalVelocity;
Velocity.Y = (float)Math.Sin(Rotation) * TangentalVelocity;
}
//Called once per update
private void Deccelerate()
{
Velocity.X = Velocity.X -= Friction * Velocity.X;
Velocity.Y = Velocity.Y -= Friction * Velocity.Y;
}
// Called when player hits screen edge
private void Bounce()
{
Rotation = Rotation * -1;
Velocity = Velocity * -1;
SoundManager.Vulture.Play();
}
//screen edge detection
public void CheckForOutOfScreen()
{
//Check if ABOVE screen
if (Position.Y - Origin.Y / 2 < GameEngine.Viewport.Y) { OnExitScreen(); }
else
//Check if BELOW screen
if (Position.Y + Origin.Y / 2 > GameEngine.Viewport.Height) { OnExitScreen(); }
else
//Check if RIGHT of screen
if (this.Position.X + Origin.X / 2 > GameEngine.Viewport.Width) { OnExitScreen(); }
else
//Check if LEFT of screen
if (this.Position.X - Origin.X / 2 < GameEngine.Viewport.X) { OnExitScreen(); }
else
{
if (OnScreen == false)
OnScreen = true;
}
}
virtual public void OnExitScreen()
{
OnScreen = false;
Bounce();
}
Let's see if I understood correctly. First, you rotate your sprite. After that, you accelerate it forward. In that case:
// Called when player hits screen edge
private void Bounce()
{
Rotation = Rotation * -1;
Velocity = Velocity * -1; //I THINK THIS IS THE PROBLEM
SoundManager.Vulture.Play();
}
Let's suposse your sprite has no rotation when it looks up. In that case, if it's looking right it has rotated 90º, and its speed is v = (x, 0), with x > 0. When it goes out of the screen, its rotation becomes -90º and the speed v = (-x, 0). BUT you're pressing the up key and Accelerate method is called so immediately the speed becomes v = (x, 0) again. The sprite goes out of the screen again, changes its velocity to v = (-x, 0), etc. That produces the weird bounce.
I would try doing this:
private void Bounce()
{
Rotation = Rotation * -1;
SoundManager.Vulture.Play();
}
and check if it works also up and bottom. I think it will work. If not, use two different Bounce methods, one for top/bottom and another one for left/right.
Your second question... It's a bit difficult. In Physics, things reach a max speed because air friction force (or another force) is speed-dependent. So if you increase your speed, the force also increases... at the end, that force will balance the other and the speed will be constant. I think the best way to simulate a terminal speed is using this concept. If you want to read more about terminal velocity, take a look on Wikipedia: http://en.wikipedia.org/wiki/Terminal_velocity
private void Accelerate()
{
Acceleration.X = Math.abs(MotorForce - airFriction.X);
Acceleration.Y = Math.abs(MotorForce - airFriction.Y);
if (Acceleration.X < 0)
{
Acceleration.X = 0;
}
if (Acceleration.Y < 0)
{
Acceleration.Y = 0;
}
Velocity.X += (float)Math.Cos(Rotation) * Acceleration.X
Velocity.Y += (float)Math.Sin(Rotation) * Acceleration.Y
airFriction.X = Math.abs(airFrictionConstant * Velocity.X);
airFriction.Y = Math.abs(airFrictionConstant * Velocity.Y);
}
First, we calculate the accelartion using a "MotorForce" and the air friction. The MotorForce is the force we make to move our sprite. The air friction always tries to "eliminate" the movement, so is always postive. We finally take absolute values because the rotation give us the direction of the vector. If the acceleration is lower than 0, that means that the air friction is greater than our MotorForce. It's a friction, so it can't do that: if acceleration < 0, we make it 0 -the air force reached our motor force and the speed becomes constant.
After that, the velocity will increase using the acceleration. Finally, we update the air friction value.
One thing more: you may update also the value of airFriction in the Deccelarate method, even if you don't consider it in that method.
If you have any problem with this, or you don't understand something (sometimes my English is not very good ^^"), say it =)

XNA 2D camera with horizontal scrolling boxes and collisions

I've got and XNA 2D game which I've been making, but I'm having problems with it.
I've got boxes scrolling across the screen which my sprite is jumping over. The sprite is being followed by a 2D camera, and I fear that the camera is causing issues, as it's causing the scrolling boxes to stop half way across the screen instead of continuing, and also the number of lives are decreasing rapidly rather than one life when one collision occurs.
This is the code in which my sprite collides with the moving boxes
Rectangle fairyRectangle = new Rectangle((int)position.X, (int)position.Y, texture.Width, texture.Height);
hit = false;
for (int i = 0; i < GameConstants.TotalBoxes; i++)
{
if (scrollingBlocks.boxArray[i].alive)
{
Rectangle blockRectangle = new Rectangle((int)scrollingBlocks.boxArray[i].position.X, (int)scrollingBlocks.boxArray[i].position.Y, scrollingBlocks.boxArray[i].texture.Width, scrollingBlocks.boxArray[i].texture.Height);
if (IntersectPixels(fairyRectangle, fairyTextureData, blockRectangle, blockTextureData))
{
scrollingBlocks.boxArray[i].alive = false;
hit = true;
lives--;
scrollingBlocks.boxArray[i].alive = true;
scrollingBlocks.boxArray[i].position.X = random.Next(GameConstants.ScreenWidth);
scrollingBlocks.boxArray[i].position.Y = 570;
}
}
}
And this is the update function in the scrolling boxes
public void Update(GameTime gameTime)
{
for (int i = 0; i < GameConstants.TotalBoxes; i++)
{
boxArray[i].position.X = boxArray[i].position.X - 5;
boxArray[i].position.Y = boxArray[i].position.Y;
if (boxArray[i].position.X < 0)
{
boxArray[i].position.X = randomno.Next(GameConstants.ScreenWidth) + 700;
boxArray[i].position.Y = 570;
}
Helper.WrapScreenPosition(ref boxArray[i].position);
}
}
I want them to start at the right hand screen and move all the way across to x = 0, but they're currently stopping around halfway at x = 400.
And finally this is where I'm drawing it all, with the sprite and the block
if (gameState == GameState.PLAYINGLEVEL3)
{
graphics.GraphicsDevice.Clear(Color.Aquamarine);
spriteBatch.Begin(SpriteBlendMode.AlphaBlend);
backgroundManager.Draw(spriteBatch);
//scrollingBlocks.Draw(spriteBatch);
spriteBatch.DrawString(lucidaConsole, "Score: " + score + " Level: " + level + " Time Remaining: " + ((int)timer / 1000).ToString() + " Lives Remaining: " + lives, scorePosition, Color.DarkOrchid);
spriteBatch.End();
spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Deferred, SaveStateMode.None, camera.transform);
scrollingBlocks.Draw(spriteBatch);
fairyL3.Draw(spriteBatch);
spriteBatch.End();
}
Thanks for any help!
From the code provided I can't tell much about how your camera works but my guess is that when you start the level your camera picks a new center point(rather than the original xna screen location)
In other words, the center of the camera may have pushed it back a bit, so what you think is position 0 of the screen may have been pushed forward to the middle of the screen making the boxes stop. I'd suggest looking at these camera tutorials http://www.david-amador.com/2009/10/xna-camera-2d-with-zoom-and-rotation/ or http://www.youtube.com/watch?v=pin8_ZfBgq0
Cameras can be tricky so I'd suggest looking at a few tutorials to get the hang out matrices and view ports.
As for the lives taking away more than one, It's because your saying "If this box is colliding with my player, take away lives." the computer doesn't know that you only want one taken away as long as it's colliding with the player its taking away lives, it will keep decrementing.
Hopefully this will give you some ideas :D

Resources