Skip to content

Instantly share code, notes, and snippets.

@dermotbalson
Created April 9, 2013 14:48
Show Gist options
  • Select an option

  • Save dermotbalson/5346291 to your computer and use it in GitHub Desktop.

Select an option

Save dermotbalson/5346291 to your computer and use it in GitHub Desktop.
23. Raytracing
--# Main
-- Main
function setup()
t=Track2()
parameter.boolean("Rays",true)
end
function draw()
t:draw()
end
function touched(touch)
t:touched(touch)
end
--# Track1
Track1 = class()
function Track1:init(x)
self.car={x=350,y=100}
self.FOV=75 --degrees each side
self.slice=1 --degrees per view
end
function Track1:draw()
background(128)
spriteMode(CORNER)
--create new shapes every second or sl
if counter==nil then counter=0 end
counter = counter + 1
if counter%60==1 then --every 60 redraws, or about one second
screen=image(WIDTH,HEIGHT) --draw on an image the same size as the screen
setContext(screen)
fill(0,0,255,100)
for i=1,3 do
rect(self.car.x+math.random(-200,200),self.car.y+math.random(100,500),
math.random(10,100),math.random(10,100))
ellipse(self.car.x+math.random(-200,200),self.car.y+math.random(100,500),math.random(10,100))
end
setContext()
views=self:GetRays(screen)
end
sprite(screen,0,0)
fill(255,0,0)
ellipse(self.car.x,self.car.y,20)
stroke(0,100,200,200)
strokeWidth(1)
if views~=nil then
for i,v in ipairs(views) do
line(self.car.x,self.car.y,v.x,v.y)
end
end
end
function Track1:GetRays(s)
local rays={} --to store results
local f=math.pi/180 --to convert degrees to radians
for i=-self.FOV,self.FOV,self.slice do
local d,dy,dy=0,0,0 --distance to object, and x,y position of object
for u=1,1000 do --put a limit ont he looping
local xx=self.car.x+u*math.sin(i*f) --step forward
local yy=self.car.y+u*math.cos(i*f)
--if in bounds, and pixel non blank, we've hit something
if xx>1 and xx<=WIDTH and yy>1 and yy<=HEIGHT then
local r,g,b,a=s:get(xx,yy)
if b~=0 then d=u dx=xx dy=yy break end
else break end
end
--store angle, distance and x,y position of object
if d>0 then table.insert(rays,{angle=i,dist=d,x=dx,y=dy}) end
end
return rays
end
function Track1:touched(touch)
--dummy for now
end
--# Track2
Track2 = class()
function Track2:init(x)
self.car={x=25,y=50,speed=4,angle=0}
self.FOV=75 --degrees each side
self.slice=5 --degrees per view
self.trackOffset={x=50,y=50}
self:CreateTrack()
end
function Track2:draw()
--assign temporary short names just to make code easier to read
local tx,ty=self.trackOffset.x,self.trackOffset.y
background(128)
pushStyle()
spriteMode(CORNER)
sprite(imgTrack,tx,ty)
fill(255,0,0)
ellipse(tx+self.car.x,ty+self.car.y,12)
stroke(0,100,200,200)
strokeWidth(1)
views=self:GetRays(imgTrack)
if views~=nil and Rays then
for i,v in ipairs(views) do
line(tx+self.car.x,ty+self.car.y,tx+v.x,ty+v.y)
end
end
popStyle()
self:SetNewPosition()
end
function Track2:CreateTrack()
imgTrack=image(500,400)
setContext(imgTrack)
pushStyle()
fill(0,0,0,0) --transparent
stroke(201,201,201) --white
self.TrackBlue=201 --define the track colour (blue)
strokeWidth(50)
rect(0,0,500,400)
popStyle()
setContext()
end
function Track2:GetRays(s)
local rays={} --to store results
local f=math.pi/180 --to convert degrees to radians
for i=self.car.angle-self.FOV,self.car.angle+self.FOV,self.slice do --CHANGE
local d,dy,dy=0,0,0 --distance to object, and x,y position of object
for u=1,1000 do --put a limit on the looping
local xx=self.car.x+u*math.sin(i*f) --step forward
local yy=self.car.y+u*math.cos(i*f)
--if in bounds, and pixel non blank, we've hit something
if xx>1 and xx<=WIDTH and yy>1 and yy<=HEIGHT then
local r,g,b,a=s:get(xx,yy)
if b~=self.TrackBlue then d=u dx=xx dy=yy break end
else break end
end
--store angle, distance and x,y position of object
if d>0 then table.insert(rays,{angle=i,dist=d,x=dx,y=dy}) end
end
return rays
end
function Track2:SetNewPosition()
local maxd,maxa=0,0
for i,v in ipairs(views) do
if v.dist>maxd then maxd=v.dist maxa=v.angle end
end
local f=math.pi/180 --to convert degrees to radians
self.car.x=self.car.x+self.car.speed*math.sin(maxa*f)
self.car.y=self.car.y+self.car.speed*math.cos(maxa*f)
self.car.angle=maxa
end
function Track2:touched(touch)
--dummy for now
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment