Hey I did a forum search, but I couldn’t find anything that worked, so does anyone know how to detect if a touch is inside a triangle?
This answer seems good. You calculate some cross products and check if they are all positive or all negative. If so, the point is in the triangle.
Codea has a function that does cross products as required by this solution
@Ignatz, thanks!
In case anyone needs it, here’s the function i wrote to tell if a point is in a triangle:
function pointInTriangle(A, B, C, P)
local line1 = B - A
local tline1 = P - A
local cross1 = tline1:cross(line1)
local line2 = C - B
local tline2 = P - B
local cross2 = tline2:cross(line2)
local line3 = A - C
local tline3 = P - C
local cross3 = tline3:cross(line3)
if (cross1 < 0 and cross2 < 0 and cross3 < 0) or
(cross1 > 0 and cross2 > 0 and cross3 > 0) then
return true
else
return false
end
end
Touch inside or outside of the triangle.
displayMode(FULLSCREEN)
function setup()
tx=350
ty=650
verts1={vec2(200,300),vec2(500,300),vec2(350,600)}
end
function draw()
background(40, 40, 50)
stroke(255)
strokeWidth(2)
j=#verts1
for z=1,#verts1 do
line(verts1[z].x,verts1[z].y,verts1[j].x,verts1[j].y)
j=z
end
ellipse(tx,ty,10)
check()
fill(255)
text(str,350,700)
end
function check() -- check if points tx,ty are within triangle
j=#verts1
c=-1
for i=1,#verts1 do
a1=false
if verts1[i].y>ty then
a1=true
end
a2=false
if verts1[j].y>ty then
a2=true
end
b1=verts1[j].x-verts1[i].x
b2=ty-verts1[i].y
b3=(verts1[j].y-verts1[i].y)
if a1~=a2 and tx<(b1*b2/b3+verts1[i].x) then
c = c *-1
end
j=i
end
str="outside"
if c==1 then
str="inside"
end
end
function touched(t)
tx=t.x
ty=t.y
end
If you use the physics library you could use
function pointInTriangle(A, B, C, P)
local b = physics.body( POLYGON, A, B, C)
return b:testPoint(P)
end
@tnlogy - the only problem with the physics solution is that garbage collection may not destroy the triangle for a minute or so, and if you are using other physics objects, this could cause problems in the meantime.
I think a pure code solution works better here, but I must say I didn’t know about the testPoint function, that is handy.
Here’s another version using collide. Just slide your finger around the screen. I have a point and a triangle that can be moved around at the same time to overlap with the stationary triangle. I still like my first version at the top because I like math and formulas. That way I can see exactly what’s happening with the calculations.
displayMode(FULLSCREEN)
function setup()
str=""
c1 = physics.body(CIRCLE,1)
p1=physics.body(POLYGON,vec2(-100,0),vec2(100,0),vec2(0,200))
p1.type=STATIC
p2=physics.body(POLYGON,vec2(-50,0),vec2(50,0),vec2(0,100))
end
function collide(contact)
if contact.state == BEGAN or contact.state==MOVING then
str="overlap"
else
str=""
end
end
function draw()
background(0, 0, 0, 255)
stroke(255)
strokeWidth(2)
fill(255)
text(str,WIDTH/2,HEIGHT/2+300)
x=CurrentTouch.x
y=CurrentTouch.y
c1.x=0
c1.y=0
ellipse(x,y+250,2)
c1.position = vec2(c1.x+x,c1.y+y+250)
p1.x=WIDTH/2
p1.y=HEIGHT/2
a=p1.points
j=#a
for z=1,#a do
line(a[z].x+p1.x,a[z].y+p1.y,a[j].x+p1.x,a[j].y+p1.y)
j=z
end
p1.position=vec2(p1.x,p1.y)
p2.x=0
p2.y=0
a=p2.points
j=#a
for z=1,#a do
line(a[z].x+x,a[z].y+y+100,a[j].x+x,a[j].y+y+100)
j=z
end
p2.position=vec2(p2.x+x,p2.y+y+100)
end