determine finger rotation direction - ios

I'm trying to determine which way a user is rotating their finger around the screen in a circular motion. I'm currently trying to use the cross product and using the z component to determine which way the user is rotating. This is producing results which are working for the bottom half of the and are reversed on the top half of the rotation.
Can anyone shed some light on what I'm doing incorrectly?
if ( ( Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Moved && GameStateManager.CurrentGameState == GameState.Minigame) )
{
Vector3 touchPos = Vector3.zero;
if( Camera.mainCamera != null )
{
touchPos = Camera.mainCamera.ScreenToWorldPoint( new Vector3( Input.GetTouch(0).position.x, Input.GetTouch(0).position.y, Camera.mainCamera.nearClipPlane ));
}
if( prevTouchPos == Vector2.zero )
{
prevTouchPos = new Vector2( touchPos.x, touchPos.y );
return;
}
//need angle between last finger position and this finger position
Vector2 prevVec = new Vector2( prevTouchPos.x - transform.position.x, prevTouchPos.y - transform.position.y );
Vector2 currVec = new Vector2( touchPos.x - transform.position.x, touchPos.y - transform.position.y );
float ang = Vector2.Angle(prevVec, currVec);
Vector3 cross = Vector3.Cross( new Vector3(prevVec.x, prevVec.y, 0), new Vector3(currVec.x, currVec.y, 0));
Debug.Log(cross.normalized);
if (cross.z < 0)
{
Debug.Log("Prev Vec: " + prevVec);
Debug.Log("Curr Vec: " + currVec);
Debug.Log("ROTATE RIGHT");
transform.Rotate( 0, 0, ang);
}
else
{
Debug.Log("Prev Vec: " + prevVec);
Debug.Log("Curr Vec: " + currVec);
Debug.Log("ROTATE LEFT");
transform.Rotate( 0, 0, -ang);
}
//Debug.Log(ang);
//Debug.Log( "TouchPos: " + touchPos );
prevTouchPos = new Vector2( touchPos.x, touchPos.y);
}

I've done stuff similar to this in the past, it looks like your pretty close, here is the code that i've used, which determines if a user has done a full 360 in one direction or another. Note this is in C++, but the idea should help.
thumbDir.Cross( thumbCur, thumbPrev );
float z = clamp( thumbDir.z, -1.0f, 1.0f );
float theta = asin( z );
if ( z > 0.0f )
{
// clockwise
if ( fDegrees > 0.0f )
fDegrees = -theta; // Reset angle if changed
else
fDegrees -= theta;
}
else if ( z < 0.0f )
{
// counter-clockwise
if ( fDegrees < 0.0f )
fDegrees = -theta; //Reset angle if changed
else
fDegrees -= theta;
}

Related

Calculate distance between parameters and target image

How can I calculate distance between a fixed parameter and a target image/pixel?
The following code does color recognition, finds the average position, and draws circle on it. It is able to find if the target (averageX and averageY) is close to leftPd, centerPd, or rightPd. I want to change this code as lane tracking which is at least able to find distance value between leftPd parameter variable and left lane or rightPd parameter variable and right lane.
import processing.video.*;
Capture video;
float threshold = 210;
color trackColor;
PVector leftP, centerP, rightP, target;
void setup() {
leftP = new PVector (80,420);
centerP = new PVector (width/2, 380);
rightP = new PVector (560,420);
size(640, 480);
video = new Capture(this, width, height);
video.start();
trackColor = color(160,0,0); // Start off tracking for red
}
void captureEvent(Capture video) {
// Read image from the camera
video.read();
}
void draw() {
loadPixels();
video.loadPixels();
image(video, 0, 0);
float avgX = 0;
float avgY = 0;
int count = 0;
for (int x = 0; x < video.width; x ++ ) {
for (int y = 0; y < video.height; y ++ ) {
int loc = x + y*video.width;
color currentColor = video.pixels[loc];
float r1 = red(currentColor);
float g1 = green(currentColor);
float b1 = blue(currentColor);
float r2 = red(trackColor);
float g2 = green(trackColor);
float b2 = blue(trackColor);
// Using euclidean distance to compare colors
float d = distSq(r1, g1, b1, r2, g2, b2);
if (d < threshold) {
stroke(255);
strokeWeight(1);
point(x,y);
avgX += x;
avgY += y;
count++;
}
}
}
if (count > 0) {
avgX = avgX / count;
avgY = avgY / count;
// Draw a circle at the tracked pixel
fill(trackColor);
strokeWeight(4.0);
stroke(0);
ellipse(avgX, avgY, 20, 20);
text("brightnesslevel: " + trackColor, 20, 60);
text("FPS: " + frameRate, 20, 80);
}
target = new PVector (avgX, avgY);
color c = color(255, 204, 0);
fill(c);
noStroke();
ellipse(leftP.x,leftP.y,16,16); // left param
ellipse(centerP.x,centerP.y,16,16); // center param
ellipse(rightP.x,rightP.y,16,16); // right param
float leftPd = leftP.dist(target);
float centerPd = centerP.dist(target);
float rightPd = rightP.dist(target);
if ( leftPd <= 85 ){
text("To Close left " , 20, 250);
}
if ( centerPd <= 85 ){
text("To Close turn center " , 20, 275);
}
if ( rightPd <= 85 ){
text("To Close turn right " , 20, 300);
}
}
float distSq(float x1,float y1, float z1, float x2, float y2, float z2){
float d = (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1) + (z2-z1)*(z2-z1);
return d;
}
void mousePressed() {
// Save color where the mouse is clicked in trackColor variable
int loc = mouseX + mouseY*video.width;
trackColor = video.pixels[loc];
}

Change mouse position when I move my player

I've set my camera following my player, but I have a problem.
When my player moves, the vector changes obviously but not my mouse position.
I have to calculate the mouse angles of where I shoot my bullets and directions so it becomes very weird if my mouse position does not change but my vector does.
Really have no idea what to do, even after searching all over the internet.
Code for when I shoot:
v.X = (float)Math.Sqrt((5 * 5) / (1 + ((dy * dy) / (dx * dx))));
v.Y = (float)Math.Sqrt(5 * 5 - v.X * v.X);
if(Mouse.GetState().X > vector.X && Mouse.GetState().Y > vector.Y )
{
bullets.Add(new Bullet(bulletTexture, vector.X, vector.Y, v.X, v.Y, 1));
}
if (Mouse.GetState().X < vector.X && Mouse.GetState().Y > vector.Y)
{
bullets.Add(new Bullet(bulletTexture, vector.X, vector.Y, -v.X, v.Y, 1));
}
if (Mouse.GetState().X > vector.X && Mouse.GetState().Y < vector.Y)
{
bullets.Add(new Bullet(bulletTexture, vector.X, vector.Y, v.X, -v.Y, 1));
}
if (Mouse.GetState().X < vector.X && Mouse.GetState().Y < vector.Y)
{
bullets.Add(new Bullet(bulletTexture, vector.X, vector.Y, -v.X, -v.Y, 1));
}
Player facing where the mouse shoots:
mosAngle = (float)Math.Atan((Mouse.GetState().Y - vector.Y ) / (Mouse.GetState().X - vector.X));
if(Mouse.GetState().LeftButton == ButtonState.Pressed)
{
if (Mouse.GetState().Y < vector.Y && Math.Abs(mosAngle) > Math.PI / 4)
{
texture = backAnim;
}
else if (Mouse.GetState().Y > vector.Y && Math.Abs(mosAngle) > Math.PI / 4)
{
texture = frontAnim;
}
else if (Mouse.GetState().X > vector.X)
{
texture = rightAnim;
}
else
{
texture = leftAnim;
}
Camera class:
class Camera
{
private Matrix transform;
private Viewport view;
private Vector2 centre, camPos;
public Matrix Transform
{
get { return transform; }
}
public Camera(Viewport view)
{
this.view = view;
}
public void Update(GameTime gameTime)
{
KeyboardState keyboardState = Keyboard.GetState();
if (keyboardState.IsKeyDown(Keys.D))
{
camPos.X += 2f;
}
if (keyboardState.IsKeyDown(Keys.A))
{
camPos.X -= 2f;
}
if (keyboardState.IsKeyDown(Keys.W))
{
camPos.Y -= 4f;
}
if (keyboardState.IsKeyDown(Keys.S))
{
camPos.Y += 4f;
}
centre = new Vector2(camPos.X, camPos.Y);
transform = Matrix.CreateScale(new Vector3(1, 1, 0)) * Matrix.CreateTranslation(new Vector3(-centre.X, -centre.Y, 0));
}
I'm not sure what I should do in order for the code for shooting and facing the same direction where player shoots to work.
When my player moves, the vector changes obviously but not my mouse position.
That is because the mouse position is always the position within the window and not - like your player - in the game world.
So you need to deal with two different positions like mouseWindowPosition (which you get from your mouseState and mouseWorldPosition which you get by adding the mouseWindowPosition and your camera position.

How can I implement Shadow Volumes in WebGL

I have some questions about drawing shadows of a .obj in a scene of WebGL.
For example, if I want to draw shadows with Shadow Volumes Method, how should I develop this ? I'm trying to implement this but I have failed. Are there more efficient methods to do this (writing less code) ?
Below is the the code:
function createShadowBuilder(item) {
var that = function() {};
that.init = function(item) {
this.item = item;
this.glPositionBuffer = null;
this.glVertexIndexBuffer = null;
};
that.setupData = function() {
if (this.glPositionBuffer !== null) {
gl.deleteBuffer(this.glPositionBuffer);
}
if (this.glVertexIndexBuffer !== null) {
gl.deleteBuffer(this.glVertexIndexBuffer);
}
this.glVertices = [];
this.glIndices = [];
};
that.addGLVertex = function(vector) {
this.glVertices.push(vector[0]);
this.glVertices.push(vector[1]);
this.glVertices.push(vector[2]);
this.glIndices.push(this.glIndices.length);
};
that.addShadowSide = function(vector1, vector2, vector3, vector4) {
this.addGLVertex(vector1);
this.addGLVertex(vector2);
this.addGLVertex(vector3);
this.addGLVertex(vector4);
this.addGLVertex(vector3);
this.addGLVertex(vector2);
};
/**
* Check which triangles face the light source...
**/
that.checkDirection = function(lightLocation) {
var triangles = this.item.triangles,
triangle,
vector,
i = triangles.length;
while (i) {
i--;
// Create a normalized vector based on the vector from
// the center of the triangle to the lights position...
triangle = triangles[i];
vector = vec3.create(triangle.center);
vector = vec3.normalize(vec3.subtract(vector, lightLocation));
// Compare the vector with the normal of the triangle...
triangle.visible = (vec3.dot(vector, triangle.normal) < 0);
}
}
/**
* Find the edge of the object...
**/
that.findEdge = function() {
var triangles = this.item.triangles,
triangle,
a, b,
lines = this.item.lines,
line,
lineSidesHash = {},
i, j, k;
this.lineSides = [];
i = triangles.length;
while (i) {
i--;
triangle = triangles[i];
if (triangle.visible) {
j = 3;
while (j) {
j--;
// Check if the side...
k = triangle.lines[j];
line = lines[k];
a = line.v1 + '_' + line.v2;
b = line.v2 + '_' + line.v1;
if (lineSidesHash[a] !== undefined) { // Check the v1 -> v2 direction...
// The side already exists, remove it...
delete(lineSidesHash[a]);
}
else if (lineSidesHash[b] !== undefined) { // Check the v2 -> v1 direction...
// The side already exists, remove it...
delete(lineSidesHash[b]);
}
else {
// It's a new side, add it to the list...
lineSidesHash[a] = k;
}
}
}
}
// Convert the hash map to an array...
for (i in lineSidesHash) {
line = lines[lineSidesHash[i]];
this.lineSides.push(line);
}
};
that.rotateVectorX = function(vector, angle) {
var x, y,
sin, cos;
if (angle === 0) {
return;
}
y = vector[1];
z = vector[2];
sin = Math.sin(angle);
cos = Math.cos(angle);
vector[1] = y * cos - z * sin;
vector[2] = y * sin + z * cos;
};
that.rotateVectorY = function(vector, angle) {
var x, z,
sin, cos;
if (angle === 0) {
return;
}
x = vector[0];
z = vector[2];
sin = Math.sin(angle);
cos = Math.cos(angle);
vector[0] = z * sin + x * cos;
vector[2] = z * cos - x * sin;
};
that.rotateVectorZ = function(vector, angle) {
var x, y,
sin, cos;
if (angle === 0) {
return;
}
x = vector[0];
y = vector[1];
sin = Math.sin(angle);
cos = Math.cos(angle);
vector[0] = x * cos - y * sin;
vector[1] = x * sin + y * cos;
};
/**
* Update the shadow...
**/
that.update = function(lightLocation, lightAngle, matrix, zoom) {
// Get the position of the light from the matrix, remove the zoom value...
var vector = vec3.subtract(vec3.create(lightLocation), [matrix[12], matrix[13], matrix[14] + zoom]),
sin, cos,
x, y, z;
// Instead of rotating the object to face the light at the
// right angle it's a lot faster to rotate the light in the
// reverse direction...
this.rotateVectorX(vector, -lightAngle[0]);
this.rotateVectorY(vector, -lightAngle[1]);
this.rotateVectorZ(vector, -lightAngle[2]);
// Store the location for later use...
this.lightLocation = vector;
this.setupData(); // Reset all lists and buffers...
this.checkDirection(vector); // Check which triangles face the light source...
this.findEdge(); // Find the edge...
};
/**
* Create the buffers for the shadow volume...
**/
that.createVolume = function(lightLocation) {
var vertices = this.item.vertices,
triangles = this.item.triangles,
triangle,
lineSides = this.lineSides,
line,
vector1, vector2, vector3, vector4,
i = lineSides.length,
j;
while (i) { // For all edge lines...
i--;
line = lineSides[i];
vector1 = vertices[line.v1];
vector2 = vertices[line.v2];
// Extrude the line away from the light...
// Get the vector from the light position to the vertex...
vector3 = vec3.subtract(vector1, lightLocation, vec3.create());
// Add the normalized vector scaled with the volume
// depth to the vertex which gives a point on the other
// side of the object than the light source...
vector3 = vec3.add(vec3.scale(vec3.normalize(vector3), 30), vector1);
// And again for the second point on the line...
vector4 = vec3.subtract(vector2, lightLocation, vec3.create());
vector4 = vec3.add(vec3.scale(vec3.normalize(vector4), 30), vector2);
this.addShadowSide(vector1, vector2, vector3, vector4);
}
// Add the end caps to the volume...
i = triangles.length;
while (i) {
i--;
triangle = triangles[i];
if (triangle.visible) { // Only add polygons facing the light...
// Add the top...
j = 3;
while (j) {
j--;
this.addGLVertex(vertices[triangle.vertices[j]]);
}
// Add the bottom...
j = 0;
while (j < 3) {
vector1 = vertices[triangle.vertices[j]];
vector2 = vec3.subtract(vector1, lightLocation, vec3.create());
this.addGLVertex(vec3.add(vec3.scale(vec3.normalize(vector2), 30), vector1));
j++;
}
}
}
// Create the vertex position buffer...
this.glPositionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, this.glPositionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(this.glVertices), gl.STATIC_DRAW);
this.glPositionBuffer.itemSize = 3;
// Create the vertex index buffer...
this.glVertexIndexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.glVertexIndexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(this.glIndices), gl.STATIC_DRAW);
this.glVertexIndexBuffer.numItems = this.glIndices.length;
};
that.render = function() {
// Create the volume for the light...
this.createVolume(this.lightLocation);
gl.bindBuffer(gl.ARRAY_BUFFER, this.glPositionBuffer);
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, this.glPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.glVertexIndexBuffer);
setMatrixUniforms();
// Disable the texture coord attribute...
gl.disableVertexAttribArray(shaderProgram.textureCoordAttribute);
// Disable the normal attribute...
gl.disableVertexAttribArray(shaderProgram.vertexNormalAttribute);
// Disable the color attribute...
gl.disableVertexAttribArray(shaderProgram.vertexColorAttribute);
// Render both front and back facing polygons with different stencil operations...
gl.disable(gl.CULL_FACE);
gl.enable(gl.STENCIL_TEST);
gl.depthFunc(gl.LESS);
// Disable rendering to the color buffer...
gl.colorMask(false, false, false, false);
// Disable z buffer updating...
gl.depthMask(false);
// Allow all bits in the stencil buffer...
gl.stencilMask(255);
// Increase the stencil buffer for back facing polygons, set the z pass opperator
gl.stencilOpSeparate(gl.BACK, gl.KEEP, gl.KEEP, gl.INCR);
// Decrease the stencil buffer for front facing polygons, set the z pass opperator
gl.stencilOpSeparate(gl.FRONT, gl.KEEP, gl.KEEP, gl.DECR);
// Always pass...
gl.stencilFunc(gl.ALWAYS, 0, 255);
gl.drawElements(gl.TRIANGLES, this.glVertexIndexBuffer.numItems, gl.UNSIGNED_SHORT, 0);
// Enable rendering the the color and depth buffer again...
gl.colorMask(true, true, true, true);
gl.depthMask(true);
gl.disable(gl.STENCIL_TEST);
};
that.init(item);
return that;
}
this code is taken from an example on the Web, I'm trying to adapt this.

Understaing V&J (Haar.cpp) sliding window

I'm going over the code of haar.cpp to understand the sliding window approach. Here is the code:
for( factor = 1; ; factor *= scaleFactor )
{
CvSize winSize = { cvRound(winSize0.width*factor),
cvRound(winSize0.height*factor) };
CvSize sz = { cvRound( img->cols/factor ), cvRound( img->rows/factor ) };
CvSize sz1 = { sz.width - winSize0.width + 1, sz.height - winSize0.height + 1 };
CvRect equRect = { icv_object_win_border, icv_object_win_border,
winSize0.width - icv_object_win_border*2,
winSize0.height - icv_object_win_border*2 };
CvMat img1, sum1, sqsum1, norm1, tilted1, mask1;
CvMat* _tilted = 0;
if( sz1.width <= 0 || sz1.height <= 0 )
break;
if( winSize.width > maxSize.width || winSize.height > maxSize.height )
break;
if( winSize.width < minSize.width || winSize.height < minSize.height )
continue;
img1 = cvMat( sz.height, sz.width, CV_8UC1, imgSmall->data.ptr );
sum1 = cvMat( sz.height+1, sz.width+1, CV_32SC1, sum->data.ptr );
sqsum1 = cvMat( sz.height+1, sz.width+1, CV_64FC1, sqsum->data.ptr );
if( tilted )
{
tilted1 = cvMat( sz.height+1, sz.width+1, CV_32SC1, tilted->data.ptr );
_tilted = &tilted1;
}
norm1 = cvMat( sz1.height, sz1.width, CV_32FC1, normImg ? normImg->data.ptr : 0 );
mask1 = cvMat( sz1.height, sz1.width, CV_8UC1, temp->data.ptr );
cvResize( img, &img1, CV_INTER_LINEAR );
cvIntegral( &img1, &sum1, &sqsum1, _tilted );
int ystep = factor > 2 ? 1 : 2;
const int LOCS_PER_THREAD = 1000;
int stripCount = ((sz1.width/ystep)*(sz1.height + ystep-1)/ystep + LOCS_PER_THREAD/2)/LOCS_PER_THREAD;
stripCount = std::min(std::max(stripCount, 1), 100);
#ifdef HAVE_IPP
if( use_ipp )
{
cv::Mat fsum(sum1.rows, sum1.cols, CV_32F, sum1.data.ptr, sum1.step);
cv::Mat(&sum1).convertTo(fsum, CV_32F, 1, -(1<<24));
}
else
#endif
cvSetImagesForHaarClassifierCascade( cascade, &sum1, &sqsum1, _tilted, 1. );
cv::Mat _norm1(&norm1), _mask1(&mask1);
cv::parallel_for_(cv::Range(0, stripCount),
cv::HaarDetectObjects_ScaleImage_Invoker(cascade,
(((sz1.height + stripCount - 1)/stripCount + ystep-1)/ystep)*ystep,
factor, cv::Mat(&sum1), cv::Mat(&sqsum1), &_norm1, &_mask1,
cv::Rect(equRect), allCandidates, rejectLevels, levelWeights, outputRejectLevels, &mtx));
}
}
Now, I want to make sure I got everything right. As I understand, we loop over the scales and in each scale we subsample the image and try to find objects at a fixed size (20X20 for faces), going over all the x and y locations.
The pseudo- code is:
for scale=1:ScaleMax
for X=1:width
for Y=1:height
Try do detect a face at position (x,y) and of a fixedsize of 20X20.
Is that precise or did I get something wrong?
Thanks,
Gil.
While the understanding is accurate, it is not precise.
For better precision, you should read the original paper from Viola and Jones, since all the magic is in the step "Try do detect a face at position (x,y) and of a fixedsize of 20X20"

How to move a field left and right without user input, using ints in xna

Well I have this code:
Variables:
int x;
int maxX = 284;
//Rectangle
Rectangle sourceRect;
//Texture
Texture2D texture;
In the Update() method:
if (x++ >= maxX)
{
x--; //To fix this x -= 284;
}
And the Draw() method:
spriteBatch.Draw(texture, new Vector2(263 + x, 554), sourceRect, Color.White, 0f, origin, 1.0f, SpriteEffects.None, 0); //I have some properties which are not important
So what I want is to move the field horizontaly with these ints, but it moves to the right to from point 1 to point 2 and blinks back to point 1 and so on here's the desired output:
[ OUTPUT: ]
[ ]
[<1>FIELD <2>]
[ ]
So the field is at point 1. I want it to move to point 2, like this:
[<1>FIELD---------------><2>]
And then, when it reaches point 2:
[<1><---------------FIELD<2>]
And loop like this. From point 1 to point 2 and then to point 1 and point 2 again. The total distance between the points is 284 pixels (points are part of background image). I know it's about decrementing the integer but how to do it?
Since this is XNA, you have access to a GameTime object inside your update method. With that and Sin you can do what you want very simple.
...
protected override void Update(GameTime gameTime)
{
var halfMaxX = maxX / 2;
var amplitude = halfMaxX; // how much it moves from side to side.
var frequency = 10; // how fast it moves from side to side.
x = halfMaxX + Math.Sin(gameTime.TotalGameTime.TotalSeconds * frequency) * amplitude;
}
...
No need for branching logic to make something move from side to side. Hope it helps.
I'm not quite sure what you're trying to explain but I think you want to have the point move right until it hits the max point, then start moving left until it hits the min point.
one solution would be to add a direction bool e.g.
bool movingRight = true;
int minX = 263;
Update()
if( movingRight )
{
if( x+1 > maxX )
{
movingRight = false;
x--;
}
else
x++;
}
else
{
if( x-1 < minX )
{
movingRight = true;
x++;
}
else
x--;
}
Also you can work with a movement factor, this way you avoid to keep an state, that will become harder to maintain when other movements are added.
int speed = 1;
void Update() {
x += speed;
if (x < minX || x>MaxX) { speed =-speed; }
x = (int) MathHelper.Clamp(x, minx, maxx);
}

Resources