Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Touching triangle

edited August 2013 in General Posts: 2,042

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?


  • IgnatzIgnatz Mod
    Posts: 5,396

    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

  • Posts: 2,042

    @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
            return false
  • dave1707dave1707 Mod
    Posts: 7,923

    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
  • Posts: 502

    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)
  • IgnatzIgnatz Mod
    Posts: 5,396

    @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.

  • dave1707dave1707 Mod
    Posts: 7,923

    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
Sign In or Register to comment.