I'm trying to create an arc using mouse position.
The idea is that the arc begins where you start pressing the mouse button, and ends where the mouse is currently at
However I'm having some troubles because the angle is normalized or something,
Click then start dragging the mouse:
Suddendly this happens:
As you may see, the finish angle changes from a positive to a negative value
function love.load()
cx = love.graphics.getWidth()/2
cy = love.graphics.getHeight()/2
begin = 0
finish = 0
end
function love.update(dt)
mx = love.mouse.getX()
my = love.mouse.getY()
dx = mx-cx
dy = my-cy
angle = math.atan2(dy,dx)
if love.mouse.isDown("l") then
finish = angle
end
end
function love.draw()
love.graphics.arc("line",cx,cy,100,begin,finish)
love.graphics.print("begin: "..begin.. " finish: "..finish,30,30)
end
function love.mousepressed( x, y, button )
mx = love.mouse.getX()
my = love.mouse.getY()
dx = mx-cx
dy = my-cy
angle = math.atan2(dy,dx)
begin = angle
end
function love.mousereleased( x, y, button )
begin = 0
finish = 0
end
Write the ö of Löve with Alt+numPad(148) or Alt+numPad(153)
Hello, math.atan2 returns the smallest angle. So if your arc is 270 degrees, it will return -90. What happens is that when you arc crosses the horizontal, it switches angle from negative to positive and vice versa; this will switch the orientation of the arc. You'll need to add some sort of check to determine which way your mouse is spinning.
meoiswa wrote:I'm trying to create an arc using mouse position.
The idea is that the arc begins where you start pressing the mouse button, and ends where the mouse is currently at
However I'm having some troubles because the angle is normalized or something,
Click then start dragging the mouse:
<image>
Suddendly this happens:
<image>
As you may see, the finish angle changes from a positive to a negative value
function love.load()
cx = love.graphics.getWidth()/2
cy = love.graphics.getHeight()/2
begin = 0
finish = 0
end
function love.update(dt)
mx = love.mouse.getX()
my = love.mouse.getY()
dx = mx-cx
dy = my-cy
angle = math.atan2(dy,dx)
if love.mouse.isDown("l") then
finish = angle
end
end
function love.draw()
love.graphics.arc("line",cx,cy,100,begin,finish)
love.graphics.print("begin: "..begin.. " finish: "..finish,30,30)
end
function love.mousepressed( x, y, button )
mx = love.mouse.getX()
my = love.mouse.getY()
dx = mx-cx
dy = my-cy
angle = math.atan2(dy,dx)
begin = angle
end
function love.mousereleased( x, y, button )
begin = 0
finish = 0
end
iirc love uses the absolute value of the difference between the two angles to determine which of the two arcs it should draw
dunno, i just found love.graphics.arc to be frustrating. maybe i was just being stupid but i had to fuck around with the values A LOT just to get the corners of a rounded box to work. i ended up just writing my own arc function (i needed the capability to leave off the two straight lines, which love.graphics.arc doesn't have an option for)
function love.load()
cx = love.graphics.getWidth()/2
cy = love.graphics.getHeight()/2
begin = 0
finish = 0
end
function love.update(dt)
mx = love.mouse.getX()
my = love.mouse.getY()
if love.mouse.isDown("l") then
x2,y2 = mx-cx,my-cy
dot = x1*x2+y1*y2 -- find delta angle by using dot product
lprod = math.sqrt((x1*x1+y1*y1)*(x2*x2+y2*y2))
angled = math.acos(dot/lprod)
crossK = x1*y2-y1*x2 -- fine direction of angle by cross product
if crossK < 0 then angled = -angled end
finish = finish+angled
x1,y1 = x2,y2
end
end
function love.draw()
love.graphics.arc("line",cx,cy,100,begin,finish)
love.graphics.print("begin: "..begin.. " finish: "..finish,30,30)
end
function love.mousepressed( x, y, button )
x1,y1 = mx-cx,my-cy
begin = math.atan2(y1,x1)
finish = begin
end
function love.mousereleased( x, y, button )
begin = 0
finish = 0
end
meoiswa wrote:Can I get to see that custom arc function? I want to be able to draw this shape and I guess I'll have to create my own function for that:
this is what i used: positive sweep goes ccw, negative goes cw
local function arc (mode, x, y, radius, start, sweep, segments, omitlines)
local points = { }
sweep = math.max(-math.pi * 2, math.min(sweep, math.pi * 2))
local o = 0
if mode == "fill" or not omitlines then
o = 2
points[1] = x
points[2] = y
end
segments = (segments or 10) - 1
for i = 0, segments do
local dir = start + (i / segments) * sweep
points[o+i*2+1] = math.cos(dir) * radius + x
points[o+i*2+2] = -math.sin(dir) * radius + y
end
if mode == "fill" then
love.graphics.polygon("fill", points)
elseif mode == "line" then
if not omitlines then
points[#points+1] = x
points[#points+1] = y
end
love.graphics.line(points)
end
end
not extensively tested
EDIT: technically this by itself wouldn't draw the exact shape you want (it could just be used for the outline)
Last edited by Xgoff on Tue Aug 14, 2012 2:37 am, edited 1 time in total.
function arc_seg()
local acx, acy = mask.width/2, mask.height/2 -- arc center
local rado, radi = 1.5 * mask.size, mask.size -- outer & inner radius
local arco, arci = {}, {} -- tables of arc points
local arcs, arce = mask.angle, mask.angle + mask.circle -- start & ending angle
local idx = mask.size / 4 -- steps in arc
local val = 1
for i = arcs, arce,pi / idx do
local xo = rado * math.cos(i) + acx
local yo = rado * math.sin(i) + acy
local xi = radi * math.cos(i) + acx
local yi = radi * math.sin(i) + acy
arco[val] = { xo, yo }
arci[val] = { xi, yi }
val = val + 1
end
for i = 1, #arco - 1 do -- polygon can't handle all the points at once
gr.polygon('fill',
arco[i][1], arco[i][2], arco[i+1][1], arco[i+1][2],
arci[i+1][1], arci[i+1][2], arci[i][1], arci[i][2])
end
end
Added code to my test script 'mask.love'.
<c><v> change the number of segments in arc
<q><w> change radius of arc
Polygon adds a hidden gotch-u because of its limits.