English how to check for intersection

4 replies
Goto Page
To the start Previous 1 Next To the start
04.01.15 11:12:15 pm
Up
M_
User
Offline Off
Example:

I have two points:
one set at (1,5) and another at (10,13)
How can i detect if a tile is between them.


Here is a photo explaining exactly what i want

IMG:http://s21.postimg.org/difbnuzaf/image.png


I want this red tile to fail the check, but the blue tile returns true.
04.01.15 11:26:40 pm
Up
Rainoth
Moderator
Offline Off
Well, isn't it the case that you find angle your line is drawn with and then loop every spot of your line to check if there's anything in intersection. I say one pixel cause it's the most reliable way, you could do it every say 3-4 pixels to make it less laggy. Another way would be to take the CORNERS of your tile and check if some are below your line and some are above (or on the left or right). As far as I know, if you're using just a few tiles, the second method is better for me.
MAL • DeviantArt • For Wallpaper Engine users • Check YT for playlists... •
05.01.15 01:05:34 am
Up
Flacko
User
Offline Off
I'm assuming you don't care about pixel-perfect detection and you just want a straight line from the center of square A to the center of B.

Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
local dx = B.x - A.x
local dy = B.y - A.y
-- we will use the following function for the line:
-- C(t) = (A.x + t*dx, A.y + t*dy) with 0<=t<=1
-- ofc, t can take an infinite number of values
-- and we can't evaluate them all

-- hopefully, this is enough, and maybe not too much
local maxd = math.abs(dx)+math.abs(dy)
-- we divide t in maxd pieces


for t = 0, maxd do
     local tx = math.floor(A.x + t/maxd * dx)
     local ty = math.floor(A.y + t/maxd * dy)
     if tile(tx,ty) meets condition then
          -- do sth
     end
end


I have done a similar algorithm for other purposes in Java but not in Lua, so this one isn't tested.
edited 5×, last 05.01.15 11:26:27 am
05.01.15 08:08:29 am
Up
DC
Admin
Offline Off
Here's a Lua implementation of the Bresenham algorithm which is probably what you're looking for:
https://github.com/kikito/bresenham.lua
It has a callback function which is called for each pixel (in case of CS2D you can simply handle tiles as if they were pixels) so you can do individual checks for each tile.
www.UnrealSoftware.de | www.CS2D.com | www.CarnageContest.com | Use the forum & avoid PMs!
05.01.15 09:21:55 pm
Up
M_
User
Offline Off
@user DC:

Thank you, this package is very neat and useful.

@user Flacko: Thanks for helping me too...



I know it is giant and stupid, but it works for me...
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
function stab_p(uid)
     local x,y,rot = player(uid,"x"),player(uid,"y"),player(uid,"rot")
     local new_rot=rot
     if new_rot<-90 then new_rot=new_rot+360 end 
     local angle=math.rad(math.abs(new_rot +90))-math.pi
     local x1=x+math.cos(angle)*52
     local y1=y+math.sin(angle)*52
     local x2=x+math.cos(angle)*106
     local y2=y+math.sin(angle)*106

     local player_targeted={}
     local tx,ty,dx,dy=pixel_totile(x),pixel_totile(y),pixel_totile(x2),pixel_totile(y2)
     local tile_check = bresenham.los(tx,ty,dx,dy,function(x,y)
          --effect("flare",tile_topixel(x),tile_topixel(y),20,20,0,0,0) 
          if not tile(x,y,"walkable") then
               return false
          end
          for index,tid in ipairs(player(0,"table")) do
               if player(tid,"tilex")==x and player(tid,"tiley")==y and tid~=uid then
                    table.insert(player_targeted,tid)
               end
          end
          
          --[[
          local ti=image("gfx/block.png",0,0,1)
          imagepos(ti,tile_topixel(x),tile_topixel(y),0)
          timerex(1000,freeimage,1,ti)
          --]]
          
          return true
     end)
     
     if not tile_check then return false end

     ---------------------------------------------------------
     local sword=image("gfx/classmod/adaga.png",0,0,1)
     imagepos(sword,x1,y1,rot)
     setpos(uid,x2,y2)
     --parse('setpos '..uid..' '..x2..' '..y2)
     
     tween_alpha(sword,1000,0)
     timerex(1000,freeimage,1,sword)
     
     
     for index,tid in ipairs(player_targeted) do
          bleed_p(tid,30)
          class.bleeding[tid][1]=5
          class.bleeding[tid][2]=uid
          class.refresh_status(tid)
     end
     --]]
     
     class.cooldown[uid]=os.time()+3
end
To the start Previous 1 Next To the start