Jump to content

isMouseInCircleSector?


Recommended Posts

Hello,

I'm working with circles (dxDrawCircle) recently and I need a function to check if the player's cursor is within a circle's sector (a button). Is there a function to do this? I found the isMouseInCircle function, but it's not enough. Any ideas?

Link to post

use a triple check, first whether the cursor is in a large circle, then whether the cursor is in a small circle, and whether the cursor is in a triangle

 

x, y - cursor coordinates

x1, y1, x2, y2, x3, y3 - coordinates of the angles of the triangle

the function returns true if the point x, y belongs to a triangle

function getPosition(x, y, x1, y1, x2, y2, x3, y3)
    local k = (x1 - x) * (y2 - y1) - (x2 - x1) * (y1 - y)
    local m = (x2 - x) * (y3 - y2) - (x3 - x2) * (y2 - y)
    local n = (x3 - x) * (y1 - y3) - (x1 - x3) * (y3 - y)
    return ((k >= 0 and m >= 0 and n >= 0) or (k <= 0 and m <= 0 and n <= 0))
end
Edited by MRmihailZH
  • Like 1
Link to post

If you only want to see if the point is inside one of the circle's quadrants, it can be done really simple.

If you want to check for any sector, I have made the following, where you define the sector from two angles. It would also be possible to define the sectors from vectors instead.

local sx, sy = guiGetScreenSize( )
function isMouseInCircleSector(cx, cy, r, angleStart, angleEnd)
	local mx, my = getCursorPosition()
	if not mx then return end
	
	-- Relativise mouse position to circle center
	mx = mx * sx - cx
	my = my * sy - cy
	
	-- Convert angles to vectors
	local x1, y1 = r * math.cos(angleStart), r * math.sin(angleStart)
	local x2, y2 = r * math.cos(angleEnd), r * math.sin(angleEnd)
	
	return mx^2 + my^2 <= r^2 and -- Check if within radius
	-x1*my + y1*mx <= 0 and -- Check if counterclockwise to angleStart
	-x2*my + y2*mx > 0 -- Check if clockwise to angleEnd
end

Where:

cx, cy = Circle center

r = Circle radius

angleStart = start of sector, in radians

angleEnd = end of sector, in radians

spacer.png

So as an example, here are the angleStart and angleEnd values for each quadrant

270, 0 - First quadrant
180, 270 - Second quadrant
90, 180 - Third quadrant
0, 90 - Fourth quadrant

Hope it's useful

  • Like 1
Link to post

Thank you! I tested it and for some reason it's not working properly, did I mess something up? I wanted make it green when it's within the sector, otherwise red. 
 

-- 1st test

if isMouseInCircleSector(sx/2, sy/2, 330, 0, 90) then
    dxDrawCircle(sx/2, sy/2, 330, 0, 90, tocolor(0, 255, 0, 255))
else
    dxDrawCircle(sx/2, sy/2, 330, 0, 90, tocolor(255, 0, 0, 255))
end


-- 2nd test

if isMouseInCircleSector(sx/2, sy/2, 330, 0, 180) then
    dxDrawCircle(sx/2, sy/2, 330, 0, 180, tocolor(0, 255, 0, 255))
else
    dxDrawCircle(sx/2, sy/2, 330, 0, 180, tocolor(255, 0, 0, 255))
end

https://imgur.com/a/g6udD5L
 

Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...