48 wiersze
1.5 KiB
TypeScript
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 };
|
|
}
|