import { DancerIdentity, Rotation } from "./danceCommon"; export interface Offset { x: number; y: number; } export function OffsetTranspose(a: Offset): Offset { return { x: a.y, y: a.x }; } export function OffsetRotate(a: Offset, r: Rotation): Offset { const rad = degreesToRadians(r); const sin = Math.sin(rad); const cos = Math.cos(rad); return { x: a.x * cos - a.y * sin, y: a.x * sin + a.y * cos, }; } function _OffsetPlus(a: Offset, b: Offset): Offset { return { x: a.x + b.x, y: a.y + b.y, }; } export function OffsetPlus(...args: Offset[]): Offset { return args.reduce(_OffsetPlus, offsetZero); } export function OffsetTimes(a: Offset, b: number): Offset { return { x: a.x * b, y: a.y * b, }; } export function OffsetMinus(a: Offset, b: Offset): Offset { return { x: a.x - b.x, y: a.y - b.y, }; } export function OffsetEquals(a: Offset, b: Offset): boolean { return a.x === b.x && a.y === b.y; } export function OffsetDistance(a: Offset, b: Offset): number { const dx = a.x - b.x; const dy = a.y - b.y; return Math.sqrt(dx * dx + dy * dy); } export interface DancerSetPosition { // Position of the dancer relative to the center of their set. position: Offset; // Rotation in degrees where 0 is up the hall, // 90 is to the right, 180 is down the hall, // and 270 is to the left. rotation: number; leftArmEnd?: Offset; rightArmEnd?: Offset; drawDebug?: (CanvasRenderingContext2D) => void; } export type DancersSetPositions = Map; export const offsetZero : Offset = { x: 0, y: 0 }; // Distance from one side of the set to the other. Set so the left // of the set is -1 and the right of the set is +1. export const setWidth : number = 2; // Distance from top of one hands four to its bottom. // Equivalently, the distance between a dancer and their neighbor // in improper position. Set so +1 is the top and -1 is the bottom. export const setHeight : number = 2; // Distance between two hands fours in neutral position. export const setSpacing : number = setHeight; // y offset between any dancer and their previous/next neighbor // of the same role. export const setDistance : number = setHeight + setSpacing; export const lineSpacing : number = setWidth; // x offset between any dancer and their eqivalent in the line to // to left/right. export const lineDistance : number = setWidth + lineSpacing; export const dancerWidth : number = 0.75; // Not sure about this value. export const dancerHeight : number = 0.25; // Not sure about this value. export const dancerHeightOffset : number = dancerHeight/4; export const leftShoulder : Offset = { x: -dancerWidth/2, y: -dancerHeightOffset }; export const rightShoulder : Offset = { x: dancerWidth/2, y: -dancerHeightOffset }; export function degreesToRadians(degrees: number) { return degrees * (Math.PI / 180); } export function radiansToDegrees(radians: number) { return radians * (180 / Math.PI); } enum HandEnum { Left = "Left", Right = "Right", } export class Hand { public static readonly Left = new Hand(HandEnum.Left); public static readonly Right = new Hand(HandEnum.Right); private readonly enumValue: HandEnum; private constructor(enumValue: HandEnum) { this.enumValue = enumValue; } public opposite() : Hand { return this.enumValue === HandEnum.Left ? Hand.Right : Hand.Left; } public shoulderPosition() : Offset { return this.enumValue === HandEnum.Left ? leftShoulder : rightShoulder; } public toString() : string { return this.enumValue.toString(); } }