forked from perelman/contra-renderer
151 lines
4.1 KiB
TypeScript
151 lines
4.1 KiB
TypeScript
enum DanceRoleEnum {
|
|
Lark = "Lark",
|
|
Robin = "Robin",
|
|
}
|
|
|
|
export class DanceRole {
|
|
public static readonly Lark = new DanceRole(DanceRoleEnum.Lark);
|
|
public static readonly Robin = new DanceRole(DanceRoleEnum.Robin);
|
|
|
|
private readonly enumValue: DanceRoleEnum;
|
|
|
|
private constructor(danceRole: DanceRoleEnum) {
|
|
this.enumValue = danceRole;
|
|
}
|
|
|
|
public opposite() : DanceRole {
|
|
return this.enumValue === DanceRoleEnum.Lark ? DanceRole.Robin : DanceRole.Lark;
|
|
}
|
|
|
|
public toString() : string {
|
|
return this.enumValue.toString();
|
|
}
|
|
}
|
|
|
|
enum CoupleRoleEnum {
|
|
Ones = "Ones", // aka "Actives"
|
|
Twos = "Twos", // aka "Inactives"
|
|
}
|
|
|
|
export class CoupleRole {
|
|
public static readonly Ones = new CoupleRole(CoupleRoleEnum.Ones);
|
|
public static readonly Twos = new CoupleRole(CoupleRoleEnum.Twos);
|
|
|
|
readonly enumValue: CoupleRoleEnum;
|
|
|
|
private constructor(danceRole: CoupleRoleEnum) {
|
|
this.enumValue = danceRole;
|
|
}
|
|
|
|
public opposite() : CoupleRole {
|
|
return this.enumValue === CoupleRoleEnum.Ones ? CoupleRole.Twos : CoupleRole.Ones;
|
|
}
|
|
|
|
public toString() : string {
|
|
return this.enumValue.toString();
|
|
}
|
|
}
|
|
|
|
export type StartFormation = "improper" | "Becket" | "Becket ccw" | "Sawtooth Becket";
|
|
|
|
export enum Rotation {
|
|
Up = 180,
|
|
Down = 0,
|
|
Left = 270,
|
|
Right = 90,
|
|
}
|
|
|
|
export function normalizeRotation(rotation: number, minRotation: number | undefined) {
|
|
if (minRotation === undefined) {
|
|
if (rotation > 180) {
|
|
rotation = rotation - 360;
|
|
} else if (rotation < -180) {
|
|
rotation = rotation + 360;
|
|
}
|
|
} else if (minRotation === 0) {
|
|
if (rotation !== 0) {
|
|
throw "Expected zero rotation"
|
|
}
|
|
} else if (minRotation > 0) {
|
|
while (rotation <= 0 || rotation < minRotation - 180) rotation += 360;
|
|
} else /* minRotation < 0 */ {
|
|
while (rotation >= 0 || rotation > minRotation + 180) rotation -= 360;
|
|
}
|
|
return rotation;
|
|
}
|
|
|
|
export class DancerIdentity {
|
|
public static readonly OnesLark = new DancerIdentity(DanceRole.Lark, CoupleRole.Ones);
|
|
public static readonly OnesRobin = new DancerIdentity(DanceRole.Robin, CoupleRole.Ones);
|
|
public static readonly TwosLark = new DancerIdentity(DanceRole.Lark, CoupleRole.Twos);
|
|
public static readonly TwosRobin = new DancerIdentity(DanceRole.Robin, CoupleRole.Twos);
|
|
|
|
public readonly danceRole: DanceRole;
|
|
public readonly coupleRole: CoupleRole; // TODO better name for this?
|
|
|
|
private constructor(danceRole: DanceRole, coupleRole: CoupleRole) {
|
|
this.danceRole = danceRole;
|
|
this.coupleRole = coupleRole;
|
|
}
|
|
|
|
public static get(danceRole: DanceRole, coupleRole: CoupleRole) : DancerIdentity {
|
|
if (coupleRole === CoupleRole.Ones) {
|
|
if (danceRole === DanceRole.Lark) {
|
|
return DancerIdentity.OnesLark;
|
|
} else {
|
|
return DancerIdentity.OnesRobin;
|
|
}
|
|
} else {
|
|
if (danceRole === DanceRole.Lark) {
|
|
return DancerIdentity.TwosLark;
|
|
} else {
|
|
return DancerIdentity.TwosRobin;
|
|
}
|
|
}
|
|
}
|
|
|
|
public neighbor() : DancerIdentity {
|
|
return DancerIdentity.get(this.danceRole.opposite(), this.coupleRole.opposite());
|
|
}
|
|
|
|
public partner() : DancerIdentity {
|
|
return DancerIdentity.get(this.danceRole.opposite(), this.coupleRole);
|
|
}
|
|
|
|
public oppositeSameRole() : DancerIdentity {
|
|
return DancerIdentity.get(this.danceRole, this.coupleRole.opposite());
|
|
}
|
|
|
|
public asExtendedDancerIdentity(relativeSet?: number, relativeLine?: number) : ExtendedDancerIdentity {
|
|
return {
|
|
setIdentity: this,
|
|
relativeSet: relativeSet ?? 0,
|
|
relativeLine: relativeLine ?? 0,
|
|
}
|
|
}
|
|
|
|
public toString() : string {
|
|
return this.danceRole.toString() + "!" + this.coupleRole.toString();
|
|
}
|
|
|
|
public static all() : DancerIdentity[] {
|
|
return [
|
|
DancerIdentity.OnesLark,
|
|
DancerIdentity.OnesRobin,
|
|
DancerIdentity.TwosLark,
|
|
DancerIdentity.TwosRobin,
|
|
]
|
|
}
|
|
}
|
|
|
|
export interface ExtendedDancerIdentity {
|
|
// Identity within own set.
|
|
setIdentity: DancerIdentity,
|
|
|
|
// 0 = focused line, -1 = line to left, +1 = line to right, ...
|
|
relativeLine: number,
|
|
|
|
// 0 = focused set, +1 = next set up, -1 = next set down.
|
|
relativeSet: number,
|
|
}
|