Constrain wall moves along wall normals

This commit is contained in:
sudhir
2026-05-20 00:53:10 +00:00
committed by open-pascal
parent c31c08fd90
commit fe68dbeebd
+13 -7
View File
@@ -3,7 +3,8 @@ import type { WallNode } from '../../schema'
const AXIS_EPSILON = 1e-6 const AXIS_EPSILON = 1e-6
export type WallPlanPoint = [number, number] export type WallPlanPoint = [number, number]
export type WallMoveAxis = 'x' | 'z' // Unit direction vector (x,z) to constrain move deltas along.
export type WallMoveAxis = [number, number]
export type WallMoveEndpoint = 'start' | 'end' export type WallMoveEndpoint = 'start' | 'end'
export type WallMoveBridgePlan<TWall extends Pick<WallNode, 'id' | 'start' | 'end'>> = { export type WallMoveBridgePlan<TWall extends Pick<WallNode, 'id' | 'start' | 'end'>> = {
@@ -29,12 +30,15 @@ export function getPerpendicularWallMoveAxis(
start: WallPlanPoint, start: WallPlanPoint,
end: WallPlanPoint, end: WallPlanPoint,
): WallMoveAxis | null { ): WallMoveAxis | null {
const wallDeltaX = Math.abs(end[0] - start[0]) const dx = end[0] - start[0]
const wallDeltaZ = Math.abs(end[1] - start[1]) const dz = end[1] - start[1]
const length = Math.hypot(dx, dz)
if (wallDeltaX < AXIS_EPSILON && wallDeltaZ < AXIS_EPSILON) return null if (length < AXIS_EPSILON) return null
return wallDeltaX >= wallDeltaZ ? 'z' : 'x' // Perpendicular (normal) direction for moving the wall "sideways".
// This matches the arrow handles shown in the editor.
return [-dz / length, dx / length]
} }
export function constrainWallMoveDeltaToAxis( export function constrainWallMoveDeltaToAxis(
@@ -42,8 +46,10 @@ export function constrainWallMoveDeltaToAxis(
deltaZ: number, deltaZ: number,
axis: WallMoveAxis | null, axis: WallMoveAxis | null,
): WallPlanPoint { ): WallPlanPoint {
if (axis === 'x') return [deltaX, 0] if (axis) {
if (axis === 'z') return [0, deltaZ] const projected = deltaX * axis[0] + deltaZ * axis[1]
return [axis[0] * projected, axis[1] * projected]
}
return [deltaX, deltaZ] return [deltaX, deltaZ]
} }