Skip to content

Instantly share code, notes, and snippets.

@pawarherschel
Last active October 22, 2023 22:40
Show Gist options
  • Save pawarherschel/08552d1d93cc454b03aab106bf72c0be to your computer and use it in GitHub Desktop.
Save pawarherschel/08552d1d93cc454b03aab106bf72c0be to your computer and use it in GitHub Desktop.
class Vec2 {
/*
* A 2D vector
* @param x The x coordinate
* @param y The y coordinate
*/
constructor(public x: number, public y: number) {}
}
class Line {
/*
* A line between two points
* @param p1 The first point
* @param p2 The second point
* @property angle The angle of the line in radians
* @property angle_degrees The angle of the line in degrees
* @property length The length of the line
* @method lerp Get a point on the line at a certain percentage between the two points
*/
constructor(public p1: Vec2, public p2: Vec2) {}
/*
* The angle of the line in radians
*/
get angle() {
return Math.atan2(this.p2.y - this.p1.y, this.p2.x - this.p1.x);
}
/*
* The angle of the line in degrees
*/
get angle_degrees() {
return this.angle * 180 / Math.PI;
}
/*
* The length of the line
*/
get length() {
return Math.sqrt(Math.pow(this.p2.x - this.p1.x, 2) + Math.pow(this.p2.y - this.p1.y, 2));
}
/*
* Get a point on the line at a certain percentage between the two points
* @param percent The percentage between the two points (0-1)
* @returns The point on the line as a Vec2
*/
lerp(percent: number) {
return new Vec2(this.p1.x + percent * (this.p2.x - this.p1.x), this.p1.y + percent * (this.p2.y - this.p1.y));
}
}
/*
* Type alias for return type of calculate_angles.
* It is an object with three properties: spine, shoulder, and hip.
* Each of those properties is an object with two properties: angle and length.
* Along with the original line.
* Angle is the angle of the line in degrees.
* Length is the length of the line.
* Original is the original line.
*
* @property spine The angle and length of the spine
* @property shoulder The angle and length of the shoulders
* @property hip The angle and length of the hips
*/
type body_angles = {
spine: {
original: Line,
angle: number,
length: number
},
shoulder: {
original: Line,
angle: number,
length: number
},
hip: {
original: Line,
angle: number,
length: number
}
}
function calculate_angles(left_shoulder: Vec2, right_shoulder: Vec2, left_hip: Vec2, right_hip: Vec2): body_angles {
const shoulder = new Line(left_shoulder, right_shoulder);
const shoulder_angle = shoulder.angle_degrees;
const shoulder_length = shoulder.length;
const hip = new Line(left_hip, right_hip);
const hip_angle = hip.angle_degrees;
const hip_length = hip.length;
const mid_shoulder = shoulder.lerp(0.5);
const mid_hip = hip.lerp(0.5);
const spine = new Line(mid_shoulder, mid_hip);
const spine_angle = spine.angle_degrees;
const spine_length = spine.length;
// imagine the body as a stick figure
//
// O <- head
// |
// right_shoulder -> ____🅰️___ <- left_shoulder
// | | |
// | | |
// | | |
// |
// right_hip -> ____🅱️___ <- left_hip
// | |
// | |
// | |
//
// 🅰️ = mid_shoulder
// 🅱️ = mid_hip
//
// spine = line between mid_shoulder and mid_hip
// shoulder = line between left_shoulder and right_shoulder
// hip = line between left_hip and right_hip
//
// angle of spine is how much the body is leaning sideways
return {
spine: {
original: spine,
angle: spine_angle,
length: spine_length
},
shoulder: {
original: shoulder,
angle: shoulder_angle,
length: shoulder_length
},
hip: {
original: hip,
angle: hip_angle,
length: hip_length
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment