I don't know how to clamp the scale tool to the plot

I’m making a plot-building system and have a scale tool, but I don’t know how to make the scale clamped to a plot.

Current Bounding code:

function module.bounds(c: CFrame, primaryRotation: Vector3, primary: BasePart, plot): CFrame
	-- Calculate plot bounds in local space
	local plotCFrame = plot.CFrame
	local plotSize = plot.Size

	-- Transform the input point to the plot's local space
	local relativePos = plotCFrame:PointToObjectSpace(c.Position)

	-- Account for primary part rotation
	local primaryRotCFrame = CFrame.Angles(
		math.rad(primaryRotation.X),
		math.rad(primaryRotation.Y),
		math.rad(primaryRotation.Z)
	)

	-- Calculate the rotated size
	local primarySize = primary.Size
	local rotatedSize = Vector3.new(
		math.abs(primarySize.X * primaryRotCFrame.RightVector.X) +
			math.abs(primarySize.Y * primaryRotCFrame.UpVector.X) +
			math.abs(primarySize.Z * primaryRotCFrame.LookVector.X),

		math.abs(primarySize.X * primaryRotCFrame.RightVector.Y) +
			math.abs(primarySize.Y * primaryRotCFrame.UpVector.Y) +
			math.abs(primarySize.Z * primaryRotCFrame.LookVector.Y),

		math.abs(primarySize.X * primaryRotCFrame.RightVector.Z) +
			math.abs(primarySize.Y * primaryRotCFrame.UpVector.Z) +
			math.abs(primarySize.Z * primaryRotCFrame.LookVector.Z)
	)

	-- Update bounds based on rotated size
	local lowerX = -plotSize.X / 2 + rotatedSize.X / 2
	local upperX = plotSize.X / 2 - rotatedSize.X / 2
	local lowerY = plot.Size.Y/2 + rotatedSize.Y/2
	local upperY = Placement:GetAttribute("MaxHeight" ) - rotatedSize.Y / 2
	local lowerZ = -plotSize.Z / 2 + rotatedSize.Z / 2
	local upperZ = plotSize.Z / 2 - rotatedSize.Z / 2

	-- Clamp the position in local space
	local clampedX = math.clamp(relativePos.X, math.min(lowerX, upperX), math.max(lowerX, upperX))
	local clampedY = math.clamp(relativePos.Y, math.min(lowerY, upperY), math.max(lowerY, upperY))
	local clampedZ = math.clamp(relativePos.Z, math.min(lowerZ, upperZ), math.max(lowerZ, upperZ))

	-- Transform the clamped position back to world space
	local clampedWorldPos = plotCFrame:PointToWorldSpace(Vector3.new(clampedX, clampedY, clampedZ))

	-- Combine the clamped position with the rotation from the original CFrame
	return CFrame.new(clampedWorldPos.X, clampedWorldPos.Y, clampedWorldPos.Z) * c - c.Position
end

A simple method is to just move the part away from the edge when it is scaled. It may be annoying but will prevent this from happening

Right but how would I detect it has gone beyond the plot boundaries?

Did you have a solution? sjflfsdfsd

Tried it myself, give this a shot.

function module.bounds(c: CFrame, primaryRotation: Vector3, primary: BasePart, plot): CFrame
    local plotCFrame = plot.CFrame
    local plotSize = plot.Size
    
    local relativePos = plotCFrame:PointToObjectSpace(c.Position)
    
    local primaryRotCFrame = CFrame.Angles(
        math.rad(primaryRotation.X),
        math.rad(primaryRotation.Y),
        math.rad(primaryRotation.Z)
    )
    
    local primarySize = primary.Size
    local rotatedSize = Vector3.new(
        math.abs(primarySize.X * primaryRotCFrame.RightVector.X) +
            math.abs(primarySize.Y * primaryRotCFrame.UpVector.X) +
            math.abs(primarySize.Z * primaryRotCFrame.LookVector.X),
        math.abs(primarySize.X * primaryRotCFrame.RightVector.Y) +
            math.abs(primarySize.Y * primaryRotCFrame.UpVector.Y) +
            math.abs(primarySize.Z * primaryRotCFrame.LookVector.Y),
        math.abs(primarySize.X * primaryRotCFrame.RightVector.Z) +
            math.abs(primarySize.Y * primaryRotCFrame.UpVector.Z) +
            math.abs(primarySize.Z * primaryRotCFrame.LookVector.Z)
    )
    
    local lowerY = plot.Size.Y/2
    local upperY = Placement:GetAttribute("MaxHeight") or plot.Size.Y
    
    local lowerX = -plotSize.X / 2 + rotatedSize.X / 2
    local upperX = plotSize.X / 2 - rotatedSize.X / 2
    local lowerZ = -plotSize.Z / 2 + rotatedSize.Z / 2
    local upperZ = plotSize.Z / 2 - rotatedSize.Z / 2
    
    local clampedX = math.clamp(relativePos.X, lowerX, upperX)
    local clampedY = math.clamp(relativePos.Y, lowerY - rotatedSize.Y/2, upperY - rotatedSize.Y/2)
    local clampedZ = math.clamp(relativePos.Z, lowerZ, upperZ)
    
    local clampedWorldPos = plotCFrame:PointToWorldSpace(Vector3.new(clampedX, clampedY, clampedZ))
    
    return CFrame.new(clampedWorldPos.X, clampedWorldPos.Y, clampedWorldPos.Z) * c - c.Position
end

Tried it, it didn’t work. I could still scale the part out side the plot