Calculating Angle from 3D Coordinates - javascript

I am working with a pose estimator that is giving me (x, y, z) for each joint. I am attempting to calculate angles based on these and running into some issues.
const find_angle = (Ax,Ay,Az,Bx,By,Bz,Cx,Cy,Cz) =>
{
var AB = Math.sqrt(Math.pow(Bx-Ax,2) + Math.pow(By-Ay,2) + Math.pow(Bz-Az,2));
var CB = Math.sqrt(Math.pow(Bx-Cx,2) + Math.pow(By-Cy,2) + Math.pow(Bz-Cz,2));
var AC = Math.sqrt(Math.pow(Cx-Ax,2) + Math.pow(Cy-Ay,2) + Math.pow(Cz-Az,2));
const radians = Math.acos((CB*CB+AB*AB-AC*AC) / (2*CB*AB));
const angle = (Math.abs(radians*180.0/Math.PI))
console.log(angle)
}
// Knee
find_angle(101, 166, 409, 107, 209, 790, 115, 248, 9564)
// Ankle
find_angle(100, 259, 1549, 97, 299, 9471, 95, 315, 1575)
Ouput:
The Knee output looks correct to me but Ankle does not. I was expecting an angle in the range of 70-90. I'm wondering if this function is too simple for what I am trying to do or what improvements could be made to make it consistent across all joints. User is facing the camera while pose is being estimated.

Related

Vector math to keep track of points relations. How to do this with vectors?

I’m using scalar math to keep track of points relations to one another. It’s fine. I’m bad at vector math, but it looks to me that this would be really easier and cleaner using vectors. They are already all around… but I’m unpacking it to make mundane calculations and packing again… How could this be done using vector math and p5Vectors methods.
Here a working explanatory example
let r, g, b;
//green grid
let p0, p1, p2, p3;
//red green
let p00, p10, p20, p30;
// green grid 'margins'
let marginx = 10,marginy = 10;
// an arbitrary point
let refp;
let green_grid = [],red_grid = [];
let newbase = 30;
function setup() {
createCanvas(400, 400);
//colors
g = color(40, 220, 40);
r = color(255, 40, 40);
b = color(40, 40, 220);
// green grid
p0 = createVector(0 + marginx, 0 + marginy);
p3 = createVector(width - marginx, height - marginy);
p1 = createVector(p3.x, p0.y);
p2 = createVector(p0.x, p3.y);
//red grid
p00 = createVector(0 + marginx, 0 + marginy);
p30 = createVector(width - marginx - newbase, height - marginy - newbase);
p10 = createVector(p30.x, p00.y);
p20 = createVector(p00.x, p30.y);
//arbitrary ref point
refp = createVector(100, 200);
//grids points
green_grid = [p0, p1, p2, p3];
red_grid = [p00, p10, p20, p30];
//grids w and h (ref is not zero)
const green_w = p1.x - p0.x;
const green_h = p3.y - p1.y;
const red_w = p10.x - p00.x
const red_h = p30.y - p10.y
// intersection refp with axis
const xax = createVector(refp.x, p0.y);
const yax = createVector(p0.x, refp.y);
//ratios for ref point and green grid
//************//dist divided //grid width/height
const rx = (refp.x - p0.x) / (green_w);
const ry = (refp.y - p0.y) / (green_w);
//calc a point with the same ratio to the red grid
const pp_x = rx * (red_w);
const pp_y = ry * (red_h);
const proppoint = createVector(pp_x, pp_y);
// intersection proppoint with axis
const xaxis = createVector(proppoint.x, p0.y);
const yaxis = createVector(p0.x, proppoint.y);
///draw
background(121);
points_D(green_grid, r);
points_D([refp],r);
points_D(red_grid, r);
stroke(40, 255, 40);
//green grid
push();
stroke(40, 255, 40);
strokeWeight(2.5);
pvline(p0, p1);
pvline(p1, p3);
pvline(p2, p3);
pvline(p0, p2);
pop();
//red_grid
push();
stroke(255, 40, 40);
pvline(p00, p10);
pvline(p10, p30);
pvline(p20, p30);
pvline(p00, p20);
pop();
// the ref arbitrary point to grid w/h
push();
stroke(40, 40, 255);
pvline(p3, refp);
pvline(p1, refp);
pop();
//the intersections
push();
stroke('black');
pvline(refp, xax);
pvline(refp, yax);
pop();
//the calculated point
push();
points_D([proppoint], 'white');
//triagle with grid's vertices
stroke('white')
pvline(proppoint,p10);
pvline(proppoint,p30);
//intersection with grid axis
stroke('black');
pvline(proppoint, xaxis);
pvline(proppoint, yaxis);
pop();
// that's it
console.log(`original rx= ${rx}
calculated point x= ${proppoint.x}
calculated point x / red_w= ${proppoint.x / red_w}
original ry= ${ry}
calculated point y= ${proppoint.y}
calculated point y / red_h= ${proppoint.y / red_h}`);
push()
noStroke();
text(`original rx= ${rx}
calc point x= ${proppoint.x}
calc point x/red_w= ${proppoint.x / red_w}
original ry= ${ry}
calc point y= ${proppoint.y}
calc point y/red_h= ${proppoint.y / red_h}`, 180, 100)
text('this black lines are respectively\nproportional to red and green grids.', refp.x - 80, refp.y + 40);
stroke(0);
fill(255,50);
rect(180, 90, 195, 90);
rect(refp.x - 82, refp.y + 30, 195, 31);
ellipse(refp.x - 40, refp.y -4,4)
line(refp.x - 40, refp.y -4, refp.x - 80,refp.y + 30 )
pop()
}
function points_D(p5vs, c) {
push();
noFill();
stroke(c);
for (const p5v of p5vs) {
ellipse(p5v.x, p5v.y, 7);
}
pop();
}
function pvline(pv1, pv2) {
line(pv1.x, pv1.y, pv2.x, pv2.y);
}
and an image
and the sketch online
https://editor.p5js.org/v-k-/sketches/70zPrc33L
thanks.
Just found out, not hard.
const rpv = p5.Vector.sub(refp,p0).div(green_dim).mult(red_dim);
where green_dim is a vector holding the green grid width/height
and red_dim is the same for red grid.

JavaScript, how do I make fill() a variable (that I can use in a custom function)?

I'm new to JS and have not found an answer to this question (or any question like it). I'm making a relatively simple program: create fish in tank and have them be of different lengths and colour.
I can make them different lengths through having a length variable in the parameters and editing the length argument within the function, but I do not think that same logic can be applied to custom adjustable colours in the same way*.
So in essence, how would I structure my code so that I can create the command fill(), a variable such that it can be edited to make different colours from the function call?
*EDIT: Apologies, I forgot to add code:
background(147, 226, 250);
var colour = fill(158, 52, 158); //Failed attempt at custom fill()
var drawFish = function(posX, posY, x) {
ellipse(posX, posY, 166, 31);
triangle(posX + 81, posY, posX + 125, posY - 16, posX + 125, posY + 16);
ellipse(posX - 60, posY - 1, 10, 10);
};
drawFish(90, 241);
drawFish(121, 174);
drawFish(175, 356);
drawFish(238, 300);
drawFish(263, 22);
ANSWERED!
I couldn't make fill() a variable of course but instead I created variables that would generate random numbers from 0 to 256(exclusive) and placed them inside the fill() function. This allowed me to generate different colours for my fish!
Thanks for the help.
Sample code:
var drawFish = function (posX, posY, tailSize) {
stroke(74, 74, 74);
var randomNum = random(0,256);
var randomNum1 = random(0,256);
var randomNum2 = random(0, 256);
fill(randomNum, randomNum1, randomNum2);
var bodySize = random(150, 200);
ellipse (posX, posY, 166,31); //body
fill(randomNum1, randomNum, randomNum2);
triangle (posX + 81, posY, posX + 125/20*tailSize, posY - 16/20*tailSize, posX + 125/20*tailSize, posY+16/20*tailSize); //tail
//...(Removed code)
};

I try to use three.js to calculate the point after rotate and translate but the result is wrong?

I want to calculate the point A to H after rotate 90 degrees and rotate to direction vector CE(-42,51,11) and let the point translate to point(-62,283,63) and reduce (66/151).like this then point A will be(-62, 283,63), point B will be(-104,334,74)
But the result point B is not the correct answer.
I've tried multiple variations of this, but none of them seem to work.Thank you in advance and please excause my bad english. Best regards.
const tree = [
[ 0, 0, 0], // A
[ 2, 151, 2], // B
[ -62, 283, 63], // C
[ 62, 296, -58], // D
[-104, 334, 74], // E
[ -58, 338, 45], // F
[ 67, 403, -55], // G
[ 105, 365, -86], // H
]
let axis = new THREE.Vector3(-42, 51, 11)
// Normalize the axis:
axis.normalize()
// Define the matrix:
let matrix = new THREE.Matrix4()
// Define the rotation in radians:
let radians = 90 * Math.PI / 180
// Rotate the matrix:
matrix.makeRotationAxis(axis, radians)
let newTree = []
for(const vector of tree) {
// Define the vector3:
let vec = new THREE.Vector3(vector[0], vector[1], vector[2])
vec.applyMatrix4(matrix)
vec.multiplyScalar(66/151);//reduce
let transVector = new THREE.Vector3( -62, 283, 63);//translate
vec.add(transVector)
newTree.push(vec.toArray())
}
console.log(newTree)

misunderstanding and questions around arrays and key pressed functions

My aim is to hook up a midi device to my computer to create and manipulate shapes in p5.js. I'm still learning code so have a few questions regarding arrays and keys.
Is there a way to say if any of the values in noteC, noteE and noteG are triggered then 'something happens'?
But in a sort of combo as that is a chord as a opposed to say noteD and noteE which is not a chord.
Essentially I am trying to manipulate the shapes via chords being played but I am unaware of if "noteC + noteE + noteG" would do anything.
For example:
var noteC = [24, 36, 48, 60, 72, 84, 96, 108]
var noteE = [28, 40, 52, 64, 76, 88, 100]
var noteG = [31, 43, 55, 67, 79, 91, 103]
function keyPressed();
if (value ===noteC, noteE, noteG) {
ellipse(200, 200, 25, 30);
ellipse(200, 200, 50, 60);
ellipse(200, 200, 100, 100);
To do it without chords I imagine it would go something like:
function keyPressed() {
if (value ===36) {
ellipse(200, 200, 25, 30);
} else if (value === 40) {
ellipse(200, 200, 50, 60);
}
}
However manually transforming shapes separately away from any combination of chords feels static and I would like there to be a relationship between the manipulation if a chord is being played.
I would like it so that the scale of the ellipse is determined by the velocity of the keys being played but if it is part of a chord the x and y parameters will be the same.
Not asking for someone to do the code but if anyone could help me understand or point me in the right direction that would be great!
Thanks!

How can I get mouseClick to find a variable and randomize it?

Im working my way through the Khanacademy site and a a bit confused on how to make randomly sized(within certain parameters), and colored fish after mouseClick. I cant even get mouseClick working.
background(89, 216, 255);
var mouseClicked = function(drawFish){
};
^^^^^^^^^^^^^^^ What am I missing here? ^^^^^^^^^^
var drawFish = function(centerX, centerY, bodyLength, bodyHeight, bodyColor, tailWidth,
tailHeight, eyeColor,tailColor, eyeWidth, eyeHeight){
noStroke();
fill(bodyColor);
// body
ellipse(centerX, centerY, bodyLength, bodyHeight);
// tail
fill(tailColor);
triangle(centerX-bodyLength/2, centerY,
centerX-bodyLength/2-tailWidth, centerY-tailHeight,
centerX-bodyLength/2-tailWidth, centerY+tailHeight);
// eye
fill(eyeColor);
ellipse(centerX+bodyLength/3, centerY, eyeWidth, eyeHeight);
};
drawFish(296, 281, -57,52, color(245, 227, 30),-15, 60,color(13, 12, 12),color(66, 58, 58),4,4); // yellowFish
drawFish(290, 80, 180, 140, color(255, 0, 0), 57, 45,color(46, 66, 194), color(255, 204, 0),32,8); // redFish
drawFish(146,233, 218, 141, color(62, 110, 67), 30, 10, color(245, 240, 245), color(0, 51, 255),12,48); // greenFish
drawFish(233, 370, 322, 36, color(133, 34, 199), 61,15, color(255, 0, 0), color(34, 255, 0),67,20); // purpFish
Any other pointers or recommendations would be greatly appreciated.
Thanks guys!
Cool fishes! I'm learning Processing too. I ran your code and came up with this function for having random fishes appear when you click.
void mouseReleased() {
var c1 = color(random(0,255),random(0,255),random(0,255),random(0,255))
var c2 = color(random(0,255),random(0,255),random(0,255),random(0,255))
var c3 = color(random(0,255),random(0,255),random(0,255),random(0,255))
var s1 = random(10,100)
var s2 = random(10,100)
var s3 = random(10,100)
var s4 = random(10,100)
var s5 = random(5,s1)
var s6 = random(5,s2)
drawFish(mouseX, mouseY, s1, s2, c2, s3,s4, c2, c3,s5,s6); //randFish
}
To make an animation, I think you will want to use the draw() function, use variables for the x,y locations and redraw the background each time. This example has the red fish follow the mouse around.
void draw(){
background(89, 216, 255);
drawFish(mouseX, mouseY, 180, 140, color(255, 0, 0), 57, 45,color(46, 66, 194), color(255, 204, 0),32,8); // redFish
}
I hope your aquarium comes out really great!

Categories

Resources