(EDIT: Public Service Warning!: Do not run, especially with random colours as suggested below, if you are prone to photo-sensitive epilepsy/seizures!)
some Polyspiral fun for now (for a simple use of trig) – I have a version using vec2s as points and a couple of supporting classes, but this was easier to cut and paste.
I see there are functions that do clipping against a rectangle, etc. so may make use of them more in future – plodding thru an old graphics textbook to refresh my understanding of principles.
-- Use this function to perform your initial setup
function setup()
-- set up types and constants
Maxx = WIDTH
Maxy = HEIGHT
R=Maxy/Maxx
-- aspect ratio
CD = 100
--current direction angle
CPx = math.floor(Maxx/2)
CPy = math.floor(Maxy/2)
--current position
Wl=0
Wt=Maxy
Wr=Maxx
Wb= 0
--window in world coords - l,t,r,b
--(how much of a model can we see?)
--for now, same as screen size
-- (adjust and MapRects again to "zoom"? how?)
Vl=0.0
Vt=R
Vr=1.0
Vb=0.0
--view in (R)NDC coordinates
--(where do we want to draw it?)
--range up to 0,R,1,0 in real numbers
--change with orientation?
parameter("Distance",3,40,10)
iparameter("Repeat",10,500,60)
parameter("Angle",1,360,56.5)
parameter("Increment",0,50,9)
iparameter("LineWidth",1,20,4)
smooth()
lineCapMode(PROJECT)
--for random colours
--stroke(math.random(255),math.random(255),math.random(255))
strokeWidth(LineWidth)
-- clip()
MapRects()
end
-- This function gets called once every frame
function draw()
background(0, 0, 0, 0)
saveCPx=CPx
saveCPy=CPy
--for random colours
--stroke(math.random(255),math.random(255),math.random(255))
strokeWidth(LineWidth)
PolySpiral(Distance,Angle,Increment,Repeat)
CPx=saveCPx
CPy=saveCPy
end
function MapRects()
--compute sx, tx, sy, ty needed to map points from
--W(indow - real world) to V(iew - NDC)
-- call if window or viewport changed (zoom window, distort view)
sx,sy,tx,ty=1,1,0,0
sx = (Vr-Vl)/(Wr-Wl)
sy = (Vt-Vb)/(Wt-Wb)
tx = ((Vl*Wr)-(Wl*Vr))/(Wr-Wl)
ty = ((Vb*Wt)-(Wb*Vt))/(Wt-Wb)
end
function PolySpiral(Dist,angle,incr,num)
local i
for i = 1,num do
LineForward(Dist)
TurnRight(angle)
Dist = Dist + incr
end
end
function MoveTo(x,y)
-- move to point p (update current position in real world, CP)
CPx=x
CPy=y
end
function LineTo(x,y)
-- draw from current position CP to p
-- maybe prevent if same point?
-- but these are "real world" coordinates
DrawLine(CPx,CPy,x,y)
CPx = x
CPy = y
end
function MoveRel(dx,dy)
-- adjust current position by dx,dy
CPx = CPx + dx
CPy = CPy + dy
end
function LineRel(dx,dy)
-- draw from current position CP
local x = CPx + dx
local y = CPy + dy
LineTo(x,y)
end
function LineForward(Dist)
--local angle = CD * math.pi / 180
local angle = math.rad(CD)
local x = CPx + (Dist * math.cos(angle))
local y = CPy + (Dist * math.sin(angle))
LineTo(x,y)
end
function MoveForward(Dist)
-- just update CP, don't draw line
--local angle = CD * math.pi /180
local angle = math.rad(CD)
local x = CPx + (Dist * math.cos(angle))
local y = CPy + (Dist * math.sin(angle))
CPx = x
CPy = y
end
function TurnRight(angle)
CD = CD - angle
if CD < 0 then
CD = CD + 360
end
end
function LineNDC(x1,y1,x2,y2)
x1=math.floor((x1*Maxx)+0.5)
x2=math.floor((x2*Maxx)+0.5)
y1=math.floor((y1*Maxx)+0.5)
y2=math.floor((y2*Maxx)+0.5)
line(x1, y1, x2, y2)
end
function MapPoint(x,y)
-- map point x,y to point in NDC
-- using values from MapRects
x = (sx * x) + tx
y = (sy * y) + ty
return x, y
end
function HalfSpace(x,y)
local l = false
local t = false
local r = false
local b = false
if x < Wl then
l = true
end
if x > Wr then
r = true
end
if y < Wb then
b = true
end
if y > Wt then
t = true
end
return l,r,t,b
end
function Clipit(x1,y1,x2,y2,vis)
-- return 'visibility' and clipped line
-- clip real-world line segments against W
--Cohen-Sutherland clipping algorithm
local in1=false
local in2=false
local done=false
repeat
l1,r1,t1,b1 = HalfSpace(x1,y1)
l2,r2,t2,b2 = HalfSpace(x2,y2)
in1 = not (l1 or t1 or r1 or b1)
in2 = not (l2 or t2 or r2 or b2)
if in1 and in2 then
done = true
vis = true
elseif (l1 and l2) or (t1 or t2) or (r1 and r2) or (b1 and b2) then
done = true
vis = false
else
if in1 then
-- swap , ensure p1 outside
l1,l2,r1,r2,t1,t2,b1,b2=l2,l1,r2,r1,t2,t1,b2,b1
x1,y1,x2,y2 = x2,y2,x1,y1
end
if x2 == x1 then -- line is vertical
if t1 then
y1 = Wt -- p1 is above
-- ED.
-- elseif c1.b then
elseif b1
y1 = Wb -- p1 is below
end
else -- not vertical
m = (y2 - y1) / (x2 - x1) -- slope
if l1 then
y1 = y1 + ((Wl - x1) * m)
x1 = Wl
elseif r1 then
y1 = y1 + ((Wr - x1) * m)
x1 = Wr
elseif b1 then
x1 = x1 + ((Wb - y1) / m)
y1 = Wb
elseif t1 then
x1 = x1 + ((Wt - y1) / m)
y1 = Wt
end
end --vertical
end
until done
return x1,y1,x2,y2,vis
end
function DrawLine(x1,y1,x2,y2)
local vis=false
-- Ed.
--nx1,ny1,nx2,ny2,vis = Clipit(x1,y1,x2,y2,vis)
x1,y1,x2,y2,vis = Clipit(x1,y1,x2,y2,vis)
if vis then
nx1,ny1 = MapPoint(x1,y1)
nx2,ny2 = MapPoint(x2,y2)
LineNDC(nx1,ny1,nx2,ny2)
end
end
(Edited to correct as below.)