Created
April 9, 2013 14:48
-
-
Save dermotbalson/5346291 to your computer and use it in GitHub Desktop.
23. Raytracing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| --# 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