export interface Point { x: number; y: number; } export function calculateCenterOffset( corner: string, deltaWidth: number, deltaHeight: number, rotation: number, ): Point { const rad = (rotation * Math.PI) / 180; const cos = Math.cos(rad); const sin = Math.sin(rad); let localDx = 0; let localDy = 0; if (corner.includes('w')) localDx = -deltaWidth / 2; else if (corner.includes('e')) localDx = deltaWidth / 2; if (corner.includes('n')) localDy = -deltaHeight / 2; else if (corner.includes('s')) localDy = deltaHeight / 2; return { x: localDx * cos - localDy * sin, y: localDx * sin + localDy * cos, }; } export function constrainToAspectRatio( newWidth: number, newHeight: number, aspectRatio: number, ): { width: number; height: number } { const newRatio = newWidth / newHeight; if (newRatio > aspectRatio) { return { width: newHeight * aspectRatio, height: newHeight }; } else { return { width: newWidth, height: newWidth / aspectRatio }; } } export function detectRotationCorner( localX: number, localY: number, halfWidth: number, halfHeight: number, zoneRadius: number, ): string | null { const corners: Record = { nw: { x: -halfWidth, y: -halfHeight }, ne: { x: halfWidth, y: -halfHeight }, sw: { x: -halfWidth, y: halfHeight }, se: { x: halfWidth, y: halfHeight }, }; const isInsideBounds = localX >= -halfWidth && localX <= halfWidth && localY >= -halfHeight && localY <= halfHeight; if (isInsideBounds) return null; for (const [name, corner] of Object.entries(corners)) { const dx = localX - corner.x; const dy = localY - corner.y; const dist = Math.sqrt(dx * dx + dy * dy); if (dist > zoneRadius || dist < 3) continue; const isOutwardX = (name.includes('w') && dx < 0) || (name.includes('e') && dx > 0); const isOutwardY = (name.includes('n') && dy < 0) || (name.includes('s') && dy > 0); if (isOutwardX || isOutwardY) return name; } return null; }