The easiest way to explain this is with pseudocode local function quadMod(x) return math.fmod(math.fmod(x + PI/4, PI/2) + PI/2, PI/2) end local mapRadius = Distance from center to top of minimap; local buttonRadius = Distance from center to edge of button; -- Step 1. Calculate angle local angle = Use self.angle or math.atan2 if moving -- Step 2. Calculate map radius at that angle if (not quadTable[quadrantIndex]) then local radiusFactor = 1 / math.cos(quadMod(angle)); -- Smooth corners if you want, use any value up to sqrt(2) radiusFactor = math.min(radiusFactor, 1.3); mapRadius = mapRadius * radiusFactor; end -- Step 3. If necessary calculate 'gap' local radius; If we've got a gap and we're noo moving then radius = mapRadius = buttonRadius + self.gap; Else Calculate radius using existing button or cursor and the math we already did self.gap = radius - buttonRadius - mapRadius; -- Step 4, position the new button x = math.sin(angle) * radius; y = math.cos(angle) * radius; That's all.