Calculate speed from velocity vector using box2d GetLinearVelocity(); - javascript

I need to find the speed of an object in a game. The game is made in HTML5 with jquery and jquery.box2d.
For this I can use these methods:
GetLinearVelocity().x;
GetLinearVelocity().y;
I'm then trying to calculate the speed from this piece of code, but get some values that doesn't make sense when I console.log it. This is my code:
var heroVelX = game.currentHero.GetLinearVelocity().x;
var heroVelY = game.currentHero.GetLinearVelocity().y;
var speed = Math.sqrt(heroVelX^2 + heroVelY^2);
console.log(speed);
Some of the values in console.log are numbers, but most of them are NaN (Not-A-Number), which confuses me? Can someone help me solve this?
The goal I want to achieve, is to see when the speed(of object .currenHero) drop below a certain value, so I can excute a new state in the game.

Your problem is that you're using the wrong operator (Bitwise XOR) for doing square - see here.
What you need to do is:
var speed = Math.sqrt(Math.pow(heroVelX, 2) + Math.pow(heroVelY, 2));

The only time the square root function should return NaN is when the value being square rooted is negative. A way to go about testing if this is the issue would be to try squaring the values in a different line of code before square rooting them.
heroVelX = (heroVelX) * (heroVelX)
Another way to potentially shine some light on the problem would be to add log statements printing out the values of the velocities and the velocities squared before square rooting.

Related

Is object facing another

I'd like to derive a value for how much one object is facing another. For example if it is directly facing the value would be 1 and facing directly away -1.
I have the object's global position and a quaternion for orientation. I'm using three.js
This is what I have so far, but its not giving me numbers I would expect.
Storing the object orientation as 3 part vector:
const lookVector = new THREE.Vector3(0,0,1);
const direction = lookVector.clone().applyMatrix4(torsoMesh.matrix);
this.lookVector = direction.sub(this.worldPosition);
Then using this to derive an angle to another point:
angleTo(pointOfInterest){
const vectorToPOI = pointOfInterest.sub(this.worldPosition);
const angle = this.lookVector.angleTo(vectorToPOI);
return angle;
}
one way to achieve this is using dot product. It is very simple, you just normalize both vectors and multiply each component respectively, then sum them up. I won't go into more detail here, because there is loads of resources explaining this on the internet. But here is an example of how to do it in three.js:
this.lookVector.normalize();
pointOfInterest.normalize();
var angleValue = this.lookVector.dot(pointOfInterest);
this will give exactly what you asked for (just remember that by calling normalize() on a vector, you are modifying it).
angleValue is actually just the cosine of the angle between the two vectors, so another way would just be to do:
.
.
return Math.cos(angle);
hope I understood you question correctly.
I know the mesh objects keep rotation values in radians. Maybe you can have a "parent mesh" so to speak and its its rotation values to determine this.

JavaScript math gives completely wrong results

I have an assignment to make a program that can calculate the area beneath a graph in a certain area.
My function is f(x)=3+(tan(x))^2
I have turned this into javascript so it looks like this:
var y = 3 + Math.pow(Math.tan((x)*(180/Math.PI)), 2)
This is giving the right result at certain x-values. But sometimes, eg. at x = 3.4, it gives a strange number like 16 where I expected something around 3 or 4.
I have read that it can be caused by the problem with floating point behavior, but it should not give that big a difference? I don't understand it. :(
I use a for loop to change the x value and and array to store the values.
x*180/π converts an angle x, given in radians, into degrees. But that's almost certainly wrong here: The JavaScript trigonometric functions expect their arguments in radians. So if your angle is in radians, you don't need any conversion at all, and if it is in degrees, you should convert the other way round, namely x*π/180.

Detecting a Fist with Leap Motion SDK V2

I want to check if a Hand in a Leap Motion Frame is currently a Fist.
The usually suggested method is to look for hand.grabStrength with a value of 1. The problem is that the value jumps to 1 even with a "Claw-Like" Hand, or anything else with very slightly curled fingers.
Another approach would be to check on each finger if it is extended. But this has a similiar issue, Fingers only count as extended if they are completely straight. So even if i check for all fingers to be not extended, the same issue as above occurs (claw-like hands get recognized as grabbed).
Combining these two methods also does not solve the issue, which is not surprising given that they both suffer from the same problems.
Now, we do have all the bones of each finger available, with positions and everything. But I have no idea where to start with the math to detect if a finger is curled.
Basically I have this setup for now:
var controller = Leap.loop(function(frame){
if(frame.hands.length>0){
//we only look at the first available hand
var hand = frame.hands[0];
//we get the index finger only, but later on we should look at all 5 fingers.
var index = hands.fingers[1];
//after that we get the positions of the joints between the bones in a hand
//the position of the metacarpal bone (i.e. the base of your hand)
var carp = index.carpPosition;
//the position of the joint on the knuckle of your hand
var mcp = index.mcpPosition;
//the position of the following joint, between the proximal and the intermediate bones
var pip = index.pipPosition;
//the position of the distal bone (the very tip of your finger)
var dip = index.dipPosition;
//and now we need the angle between each of those positions, which is where i'm stuck
}
});
So, how do I get the angle between two of those positions (carp to mcp, mcp to pip, pip to dip)? Any ideas?
Alright, I think I found a sort of working approach to detect an actual fist, and not a claw.
First off, instead of the positions of the joints, we need the distance Vectors for each Bone.
Then we calculate the Dot product between the Metacarpal and the Proximal bone, as well as the dot Product between the Proximal and the Intermediate Bone. We can ignore the Distal bone, it doesn't change the result too much.
We sum all the calculated dot products (10 in total) and calculate the average out (we divide by 10). This will give us a value between 0 and 1. A Fist is beneath 0.5 and everything above that is basically not a fist.
Additionally you might also want to check for the amount of extended fingers on a Hand and check if it is 0. This will ensure that a "Thumbs-up" and similiar 1-digit poses do not get recognized as a Fist.
Here is my implementation:
const minValue = 0.5;
var controller = Leap.loop(function(frame){
if(frame.hands.length>0)
{
var hand = frame.hands[0];
var isFist = checkFist(hand);
}
});
function getExtendedFingers(hand){
var f = 0;
for(var i=0;i<hand.fingers.length;i++){
if(hand.fingers[i].extended){
f++;
}
}
return f;
}
function checkFist(hand){
var sum = 0;
for(var i=0;i<hand.fingers.length;i++){
var finger = hand.fingers[i];
var meta = finger.bones[0].direction();
var proxi = finger.bones[1].direction();
var inter = finger.bones[2].direction();
var dMetaProxi = Leap.vec3.dot(meta,proxi);
var dProxiInter = Leap.vec3.dot(proxi,inter);
sum += dMetaProxi;
sum += dProxiInter
}
sum = sum/10;
if(sum<=minValue && getExtendedFingers(hand)==0){
return true;
}else{
return false;
}
}
While this works like it should, I doubt that this is the correct and best approach to detect a Fist. So please, if you know of a better way, post it.
Solution works perfect, any chance you could explain why you divide by 10 and why the minValue is 0.5? Thanks!
Well, it doesn't work that good, to be honest. I'll soon start to work on a little project that has the goal to improve the detection of fists with Leap Motion.
Regarding your questions, We divide the sum by 10 because we have 2 Bone Joints per finger, with 5 fingers. We want the average value from the sum of all those calculations, because not all fingers will be angled in the same way. So we want some value that encompasses all of these values into a single one: the average value. Given that we have 10 calculations in total (2 per each finger, 5 fingers), we divide the sum of those calculations and there we go. We will get a value between 0 and 1.
Regarding the minValue: Trial&Error. In a project of mine, I used a value of 0.6 instead.
This is another problem of this approach: ideally a flat hand should be a value of nearly 0, while a fist should be 1.
I know it is an old topic but if you guys still around the answer could be simpler just by using sphereRadius() ;
I found "grabStrength" is good

Seed-based world generation using sin

I'm tried to make some world generation mechanism using Math.random() whenever I needed something random, but then decided that I wanted it seed-based, so, given a seed, I changed all of the Math.random() to Math.sin(seed++)/2+0.5, hoping it would do the same thing, but would be the same if the seed was the same seed.
Then someone made me notice that the sin wave hasn't got even distribution, and finally I saw why some of my code was working strangely.
I was wondering if there was a simple fix, or if there isn't, another very simple seed based randomizer like this
So, I looked at your method, t1wc, and I found that it isn't actually evenly distributed. It is significantly more likely to spit out numbers near 0 or near 1 than it is to spit out numbers near 0.5, for example. This is just a consequence of the way that the sine function works.
Instead, you might try using a method called Blum Blum Shub (named after the authors of the original paper, wonderfully). It is evenly distributed and quite fast. Given a seed, it works as follows:
Square the seed and put the result in a temporary variable (x).
Take the mod of x base M.
M is a product of two large primes.
The value of x is a new seed to be used for future calculations.
Return x/M as your pseudo-random number. It will be evenly distributed between 0 and 1.
Below is a simple implementation of a Blum Blum Shub:
var SeededRand = function(seed, mod1, mod2)
{
return function()
{
seed = (seed*seed) % (mod1*mod2);
return seed/(mod1*mod2);
};
};
If you want to make a new random number generator, you just call:
var rand = SeededRand(seed, mod1, mod2);
Where seed is some initial seed (1234567890 works well), and mod1 and mod2 are some large primes (7247 and 7823 work well). rand is just a variable that I've defined to hold the output.
Now, to start getting random values, you just call:
rand();
Which will spit out a different value each time you run it.
If you have any questions, please ask!
There is a very nice seed-based randomizing script already made. It can be found here.
ok guys, found out this is what I'm really looking for:
(((Math.sin(seed.value++)/2+0.5)*10000)%100)/100
It sends out even spreaded numbers, and I guess it's a lot simpler than any other number generator I've seen

trig functions with imaginary numbers in javascript

I am trying to write some code in javascript to calculate trig functions, inverse trig functions, and hyperbolic trig functions with imaginary numbers. I have the sin, cos, sinh, and cosh working well. However, I am having some trouble getting my solutions for others to match the only verification that I can find at this site.
For example, below is the code for asin(x+yi). I am using the formula located here along with the definitions for modulus and argument found there as well. It has no errors, but doesn't match the results from the site I cited. What am I doing wrong?
asin(z)=-i*ln(iz+sqrt(1-z^2))
var id1=SquareComplex (window[id].Solution_real, window[id].Solution_imag);
var real=1-window[id1].Solution_real;
var imag=window[id1].Solution_imag;
var id2=SquareRoot(real, imag);
imag=window[id].Solution_real+window[id2].Solution_imag;
real=-window[id].Solution_imag+window[id2].Solution_real;
var modulus=Math.sqrt(real^2+imag^2);
var argument=Math.atan2(imag,real);
var Solution_imag=-Math.log(modulus);
var Solution_real=argument;
This code is intended to work in several steps. The first line calls a function that squares the complex number z. The second and third lines subtract the result from the number 1. The fourth line calls a function to take the square root of the complex number. The fifth and sixth lines add the results of the previous actions to the result of multiplying the complex number by i. The remaining lines get the modulus and argument of those results, take the natural logarithm, and multiply it by a negative i.
Your first three lines are:
var id1=SquareComplex (window[id].Solution_real, window[id].Solution_imag);
var real=1-window[id1].Solution_real;
var imag=window[id1].Solution_imag;
assuming that id is your initial z then this is not calculating the real and imaginary parts of 1-z^2 as I believe it is indtended to. The reason being that the imaginary part isn't being subtracted.
Try it with
var imag = -window[id1].Solution_imag;
and see if that helps. I can't guarantee there aren't any more errors in it but I'd suggest just going through and being really careful about making sure each line does what it should.
You may be interested in math.js, which comes with support for complex numbers for all functions including trigonometry:
var value = math.complex(2, 3);
var ans = math.asin(value);
Or using the expression parser:
var ans = math.eval('asin(2 + 3i)');

Categories