Skip to content

Instantly share code, notes, and snippets.

@samuelmaddock
Last active December 20, 2015 10:58
Show Gist options
  • Save samuelmaddock/6119135 to your computer and use it in GitHub Desktop.
Save samuelmaddock/6119135 to your computer and use it in GitHub Desktop.
Clamps a given 2D screen coordinate to a radial space. Created for the game Garry's Mod.
local math = math
function ScreenRadialClamp(x,y,padding)
local w, h = ScrW(), ScrH()
local ratio = w / h
-- Default padding is 10% of the screen height
padding = padding or h * 0.1
-- Radius of width and height of screen
-- Equivalent to the center of the screen
local rx, ry = w / 2, h / 2
-- Vector to given point w/ equalize ratio
local targetx, targety = x - rx, ratio * (y - ry)
-- Angle to target coordinate (in radians)
local ang = math.atan2( targety, targetx )
-- Find maximum point on screen given the angle
local clampx, clampy =
(rx - padding) * math.cos(ang),
(ry - padding) * math.sin(ang) * ratio
-- If our clamped vector is smaller than the target vector
-- we will return the clamped vector
local targetmag = math.sqrt( targetx^2 + targety^2 )
local clampmag = math.sqrt( clampx^2 + clampy^2 )
if targetmag > clampmag then
return clampx + rx, clampy * 1/ratio + ry, true
else
return x, y, false
end
end
hook.Add( "HUDPaint", "ScreenRadialClampTest", function()
local pos = LocalPlayer():GetPos():ToScreen()
local x, y, clamped = ScreenRadialClamp( pos.x, pos.y )
local size = 16
local color = Color(255,0,0)
surface.SetDrawColor( color )
surface.DrawRect( x - size/2, y - size/2, size, size )
if clamped then
draw.SimpleText( "clamped", "DermaDefault", x, y + size*2,
color, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER )
end
end )
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment