Constrain wall moves along wall normals
This commit is contained in:
@@ -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]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user