mysticsymbolic.github.io/lib/attach.tsx

48 wiersze
1.5 KiB
TypeScript

import { Point } from "../vendor/bezier-js";
import { normalizedPoint2rad, scalePointXY, subtractPoints } from "./point";
import { PointWithNormal } from "./specs";
import { rad2deg } from "./util";
function normalizeDeg(deg: number): number {
deg = deg % 360;
if (deg < 0) {
deg = 360 + deg;
}
return deg;
}
/**
* Convert the given normal in screen-space coordinates into
* degrees of rotation in attachment-space coordinates.
*/
export function normalToAttachmentSpaceDegrees(normal: Point): number {
// We need to flip our y because we're in screen space, yet our
// rotational math assumes we're not.
const yFlipped = scalePointXY(normal, 1, -1);
const rad = normalizedPoint2rad(yFlipped);
// The origin of our rotation space assumes that "up" is 0
// degrees, while our rotational math assumes 0 degrees is "right".
const reoriented = normalizeDeg(90 - rad2deg(rad));
return reoriented;
}
/**
* Given a child point that needs to be attached to a parent
* point, return the amount of translation and rotation we
* need to apply to the child point in order to align its
* position and normal with that of its parent.
*/
export function getAttachmentTransforms(
parent: PointWithNormal,
child: PointWithNormal
) {
const translation = subtractPoints(parent.point, child.point);
const parentRot = normalToAttachmentSpaceDegrees(parent.normal);
const childRot = normalToAttachmentSpaceDegrees(child.normal);
const rotation = parentRot - childRot;
return { translation, rotation };
}