UAT-8a: rotate the rect, not a separate axis vector

reduceAxisState 'rotate' now changes state.rect.angle and re-derives
state.axis via axisFromRect(newRect). The rectangle rotates as a whole;
the axis for Measure is derived from the rotated rect's long side.

2 new regression tests: rect.angle changes on rotate, axis is
re-derived from rotated rect. 109/109 tests green.
This commit is contained in:
Ty
2026-09-14 11:23:00 -07:00
parent 0d06e6f7b7
commit f00c4a7460
2 changed files with 23 additions and 2 deletions
+4 -2
View File
@@ -274,8 +274,10 @@ export function reduceAxisState(state, action) {
case 'rotate': {
const angle = action.angle;
if (angle === 0) return state;
const newAxis = rotateAxis(state.axis, angle);
return { ...state, axis: newAxis, approved: false };
// Rotate the RECTANGLE, not a separate axis vector. The rect's angle
// changes, and the axis is re-derived from the rotated rect.
const newRect = { ...state.rect, angle: state.rect.angle + angle };
return { ...state, rect: newRect, axis: axisFromRect(newRect), approved: false };
}
case 'approve': {
return { ...state, approved: true };
+19
View File
@@ -319,6 +319,25 @@ describe('reduceAxisState', () => {
expect(s.axis.y).toBeCloseTo(1, 6);
});
it('rotate changes the rect angle (not just a separate axis vector)', () => {
let s = createAxisState(rect);
const originalAngle = s.rect.angle;
s = reduceAxisState(s, { type: 'rotate', angle: Math.PI / 4 });
// The rect itself must have rotated
expect(s.rect.angle).toBeCloseTo(originalAngle + Math.PI / 4, 6);
// And the axis is re-derived from the rotated rect
expect(s.axis).toEqual(axisFromRect(s.rect));
});
it('rotate by 90 deg: rect angle changes, axis is perpendicular to original', () => {
let s = createAxisState(rect);
s = reduceAxisState(s, { type: 'rotate', angle: Math.PI / 2 });
expect(s.rect.angle).toBeCloseTo(Math.PI / 2, 6);
// Original axis was +x (1,0). After 90 deg rect rotation, axis is +y (0,1)
expect(s.axis.x).toBeCloseTo(0, 6);
expect(s.axis.y).toBeCloseTo(1, 6);
});
it('rotate composes (rotates from current axis)', () => {
let s = createAxisState(rect);
s = reduceAxisState(s, { type: 'rotate', angle: Math.PI / 2 });