bowling-analysis-system
Version:
A comprehensive system for analyzing bowling techniques using video processing and metrics calculation
178 lines (138 loc) • 5.17 kB
JavaScript
/**
* @module metrics/calculations/angles/LowerBodyAngles
* @description Functions for calculating lower body joint angles
*/
const { calculateAngleBetweenVectors, getSafeLandmark, createVector } = require('../MetricsUtilities');
/**
* Calculate knee flexions for both sides
* @param {Array} landmarks - Array of pose landmarks
* @returns {Object} Left and right knee flexions
*/
function calculateKneeFlexions(landmarks) {
return {
left: calculateLeftKneeFlexion(landmarks),
right: calculateRightKneeFlexion(landmarks)
};
}
/**
* Calculate ankle flexions for both sides
* @param {Array} landmarks - Array of pose landmarks
* @returns {Object} Left and right ankle flexions
*/
function calculateAnkleFlexions(landmarks) {
return {
left: calculateLeftAnkleFlexion(landmarks),
right: calculateRightAnkleFlexion(landmarks)
};
}
/**
* Calculate hip flexions for both sides
* @param {Array} landmarks - Array of pose landmarks
* @returns {Object} Left and right hip flexions
*/
function calculateHipFlexions(landmarks) {
return {
left: calculateLeftHipFlexion(landmarks),
right: calculateRightHipFlexion(landmarks)
};
}
/**
* Calculate hip rotations for both sides
* @param {Array} landmarks - Array of pose landmarks
* @returns {Object} Left and right hip rotations
*/
function calculateHipRotations(landmarks) {
return {
left: calculateLeftHipRotation(landmarks),
right: calculateRightHipRotation(landmarks)
};
}
// Individual calculation functions
function calculateRightKneeFlexion(landmarks) {
const hip = getSafeLandmark(landmarks, 24);
const knee = getSafeLandmark(landmarks, 26);
const ankle = getSafeLandmark(landmarks, 28);
if (!hip || !knee || !ankle) return null;
const thigh = createVector(hip, knee);
const shin = createVector(knee, ankle);
return 180 - calculateAngleBetweenVectors(thigh, shin);
}
function calculateLeftKneeFlexion(landmarks) {
const hip = getSafeLandmark(landmarks, 23);
const knee = getSafeLandmark(landmarks, 25);
const ankle = getSafeLandmark(landmarks, 27);
if (!hip || !knee || !ankle) return null;
const thigh = createVector(hip, knee);
const shin = createVector(knee, ankle);
return 180 - calculateAngleBetweenVectors(thigh, shin);
}
function calculateRightAnkleFlexion(landmarks) {
const knee = getSafeLandmark(landmarks, 26);
const ankle = getSafeLandmark(landmarks, 28);
const foot = getSafeLandmark(landmarks, 32);
if (!knee || !ankle || !foot) return null;
const shin = createVector(knee, ankle);
const footVector = createVector(ankle, foot);
return calculateAngleBetweenVectors(shin, footVector);
}
function calculateLeftAnkleFlexion(landmarks) {
const knee = getSafeLandmark(landmarks, 25);
const ankle = getSafeLandmark(landmarks, 27);
const foot = getSafeLandmark(landmarks, 31);
if (!knee || !ankle || !foot) return null;
const shin = createVector(knee, ankle);
const footVector = createVector(ankle, foot);
return calculateAngleBetweenVectors(shin, footVector);
}
function calculateRightHipFlexion(landmarks) {
const shoulder = getSafeLandmark(landmarks, 12);
const hip = getSafeLandmark(landmarks, 24);
const knee = getSafeLandmark(landmarks, 26);
if (!shoulder || !hip || !knee) return null;
const trunk = createVector(hip, shoulder);
const thigh = createVector(hip, knee);
return calculateAngleBetweenVectors(trunk, thigh);
}
function calculateLeftHipFlexion(landmarks) {
const shoulder = getSafeLandmark(landmarks, 11);
const hip = getSafeLandmark(landmarks, 23);
const knee = getSafeLandmark(landmarks, 25);
if (!shoulder || !hip || !knee) return null;
const trunk = createVector(hip, shoulder);
const thigh = createVector(hip, knee);
return calculateAngleBetweenVectors(trunk, thigh);
}
function calculateRightHipRotation(landmarks) {
const leftHip = getSafeLandmark(landmarks, 23);
const rightHip = getSafeLandmark(landmarks, 24);
const rightKnee = getSafeLandmark(landmarks, 26);
if (!leftHip || !rightHip || !rightKnee) return null;
const hipLine = createVector(leftHip, rightHip);
const thigh = createVector(rightHip, rightKnee);
const thighHorizontal = {
x: thigh.x,
y: 0,
z: thigh.z
};
return calculateAngleBetweenVectors(hipLine, thighHorizontal);
}
function calculateLeftHipRotation(landmarks) {
const leftHip = getSafeLandmark(landmarks, 23);
const rightHip = getSafeLandmark(landmarks, 24);
const leftKnee = getSafeLandmark(landmarks, 25);
if (!leftHip || !rightHip || !leftKnee) return null;
const hipLine = createVector(rightHip, leftHip);
const thigh = createVector(leftHip, leftKnee);
const thighHorizontal = {
x: thigh.x,
y: 0,
z: thigh.z
};
return calculateAngleBetweenVectors(hipLine, thighHorizontal);
}
module.exports = {
calculateKneeFlexions,
calculateAnkleFlexions,
calculateHipFlexions,
calculateHipRotations
};