Created
November 17, 2015 04:52
-
-
Save dermotbalson/1376155bfae6d18666e3 to your computer and use it in GitHub Desktop.
Frustum test 3
This file contains 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
--Circles2 | |
local dx,dy,f1x,f1y,f2x,f2y,invPM1,cosFOV,cosFOV2 | |
local sqrt=math.sqrt | |
function setup() | |
pos=vec2(100,100) --circle position | |
camPos=vec2(WIDTH/2,HEIGHT/2) --fixed camera | |
far=700 | |
print("Fructum is in blue, pointing up") | |
print("True tangent is in pink") | |
print("Fake tangent is in green") | |
print("Use your finger to drag the circle around") | |
print("The circle goes bright yellow when it enters the frustum") | |
FOV=45 | |
parameter.integer("radius",10,100,50) | |
--parameter.number("PM1",1,12,2.6) | |
parameter.integer("angle",0,360,0,SetAngle) | |
parameter.integer("FOV",10,120,45,SetAngle) | |
end | |
function SetAngle() | |
perspective(FOV) | |
camposX,camposY=camPos.x,camPos.y | |
tangentAdjust=1/math.sin(math.rad(FOV/2)) | |
PM1=projectionMatrix()[1] | |
ortho() | |
camDir=vec2(math.cos(math.rad(angle)),math.sin(math.rad(angle))) | |
camdirX,camdirY=camDir.x,camDir.y | |
fructum=mesh() | |
local w=far/PM1*vec2(-camDir.y,camDir.x) | |
fructum.vertices={camPos,camPos+far*camDir-w,camPos+far*camDir+w} | |
fructum:setColors(color(136, 168, 199, 255)) | |
end | |
function draw() | |
background(150) | |
fructum:draw() | |
pushStyle() | |
stroke(99, 124, 183, 255) | |
strokeWidth(2) | |
line(camPos.x,camPos.y,camPos.x+far*camDir.x,camPos.y+far*camDir.y) | |
popStyle() | |
DrawCircle() | |
end | |
function DrawCircle() | |
--calculate fake tangent | |
local fake=pos+camDir*radius*tangentAdjust | |
pushStyle() | |
cosFOV=math.cos(math.rad(FOV/2)) | |
cosFOV2=cosFOV*cosFOV | |
if IsVisible3(pos,camPos,camDir,radius,far) then fill(255,255,0) else fill(255,255,0,100) end | |
ellipse(pos.x,pos.y,radius*2) | |
stroke(195, 72, 169, 255) strokeWidth(2) | |
stroke(52, 162, 48, 255) | |
line(camPos.x,camPos.y,fake.x,fake.y) | |
--ellipse(tangent.x,tangent.y,10) | |
popStyle() | |
end | |
function touched(t) | |
pos=vec2(t.x,t.y) | |
end | |
--[ | |
function setup() | |
FOV=45 | |
tangentAdjust=1/math.sin(math.rad(FOV/2)) | |
pos=vec2(100,100) --circle position | |
camPos=vec2(WIDTH/2,0) --fixed camera | |
camposX,camposY=camPos.x,camPos.y | |
camDir=vec2(0,1) | |
camdirX,camdirY=camDir.x,camDir.y | |
radius=50 | |
n=20000000 | |
PM1=2.5 | |
cosFOV=math.cos(math.rad(FOV/2)) | |
cosFOV2=cosFOV*cosFOV | |
t=os.time() | |
for i=1,n do | |
a=IsVisible4(pos,radius) | |
end | |
print("1=",os.time()-t) | |
print(n/60/(os.time()-t)) | |
t=os.time() | |
for i=1,n do | |
a=IsVisible5(pos,radius) | |
end | |
print("2=",os.time()-t) | |
print(n/60/(os.time()-t)) | |
end | |
function draw() | |
end | |
--]] | |
function IsVisible(pos,camPos,camDir,radius) | |
local px,py,pcx,pcy,pdx,pdy=pos.x,pos.y,camPos.x,camPos.y,camDir.x,camDir.y | |
--local dx,dy=px-pcx,py-pcy | |
--if dx*pdx+dy*pdy<0 then return end | |
local u=radius*tangentAdjust | |
local ptx,pty=px+pdx*u-pcx,py+pdy*u-pcy | |
local sq=ptx*ptx+pty*pty | |
local a=ptx*pdx+pty*pdy | |
return a*a>cosFOV2*sq | |
end | |
function IsVisible2(pos,camPos,camDir,radius) | |
local v=(pos+camDir*(radius*PM1)-camPos):normalize() | |
return v:dot(camDir)>cosFOV | |
end | |
function IsVisible3(pos,camPos,camDir,radius) | |
local px,py,pcx,pcy,pdx,pdy=pos.x,pos.y,camPos.x,camPos.y,camDir.x,camDir.y | |
local dx,dy=px-pcx,py-pcy | |
if dx*pdx+dy*pdy<0 then return end | |
local u=radius*tangentAdjust | |
local ptx,pty=px+pdx*u-pcx,py+pdy*u-pcy | |
local sq=ptx*ptx+pty*pty | |
local a=ptx*pdx+pty*pdy | |
return a*a>cosFOV2*sq | |
end | |
function IsVisible4(pos,radius) --fastest | |
local px,py=pos.x,pos.y | |
local dx,dy=px-camposX,py-camposY | |
if dx*camdirX+dy*camdirY<0 then return end | |
local u=radius*tangentAdjust | |
local ptx,pty=px+camdirX*u-camposX,py+camdirY*u-camposY | |
local sq=ptx*ptx+pty*pty | |
local a=ptx*camdirX+pty*camdirY | |
return a*a>cosFOV2*sq | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment