UNPKG

bowling-analysis-system

Version:

A comprehensive system for analyzing bowling techniques using video processing and metrics calculation

178 lines (138 loc) 5.17 kB
/** * @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 };