Code: Select all
local x, y = aspect.ratio(800, 600)
print("aspect ratio is: " .. x .. " : " .. y)
Code: Select all
local x, y = aspect.ratio(800, 600)
print("aspect ratio is: " .. x .. " : " .. y)
Code: Select all
--
-- Segment, ray and line casts
-- ===========================
-- Based on "Real-Time Collision Detection" by Christer Ericson
--
-- Definitions
-- ===========
-- This module works with three different types:
-- "segment" has two endpoints
-- "ray" has one endpoint
-- "line" has no endpoints
-- Results
-- =======
-- Each test, returns either one or two points.
-- The order of returned points is determined by
-- the direction of the segment, ray or line (a-b).
--
-- After each returned intersection point,
-- the module also returns the "intersection value".
-- The "intersection value" can be defined as the ratio:
-- R = |a-q|/|a-b|
-- if a-b is a segment: R is from 0 to 1
-- if a-b is a rays: R is 0 or greater
-- if a-b is a line: R could be any number
-- Example
-- =======
-- -- one intersection point:
-- qx,qy,q = line.segment(-1,0,1,0, 0,-1,0,1, "segment", "segment")
-- assert(qx == 0 and qy == 0 and q == 0.5)
--
-- -- two intersection points:
-- qx,qy,q, qx2,qy2,q2 = line.circle(-1,0,1,0, 0,0,0.5, "segment")
-- assert(qx == -0.5 and qy == 0 and q == 0.25)
-- assert(qx2 == 0.5 and qy2 == 0 and q2 == 0.75)
-- Limitations
-- ===========
-- "line.segment" does not work with "collinear" segments, rays or lines
-- None of the functions work with "degenerate" segments, rays or lines
-- Triangles are not supported :(
-- License
-- =======
-- MIT License
local sqrt = math.sqrt
local line = {}
function line.is_degenerate(ax, ay, bx, by)
--return dist2(ax, ay, bx, by) == 0
local dx, dy = ax - bx, ay - by
return dx*dx + dy*dy == 0
end
-- (a)
-- \ (b2)
-- \ /
-- (q)
-- / \
-- (a2) \
-- (b)
--- Segment
-- @param ax,ay,bx,by segment, ray or line
-- @param ax2,ay2,bx2,by2 segment, ray or line
-- @param lt defines a-b as either: "segment", "ray" or "line" (optional)
-- @param lt2 defines a2-b2 as either: "segment", "ray" or "line" (optional)
-- @return intersection point and ratio or nil
function line.segment(x1, y1, x2, y2, x3, y3, x4, y4, lt1, lt2)
lt1 = lt1 or "segment"
lt2 = lt2 or "segment"
local dx1, dy1 = x2 - x1, y2 - y1
local dx2, dy2 = x4 - x3, y4 - y3
local d = dx1*dy2 - dy1*dx2
if d == 0 then
return -- collinear
end
local dx3, dy3 = x1 - x3, y1 - y3
local t1 = (dx2*dy3 - dy2*dx3)/d
if (lt1 ~= "line" and t1 < 0) or (lt1 == "segment" and t1 > 1) then
return -- non-intersecting segment or ray
end
local t2 = (dx1*dy3 - dy1*dx3)/d
if (lt2 ~= "line" and t2 < 0) or (lt2 == "segment" and t2 > 1) then
return -- non-intersecting segment or ray
end
return x1 + t1*dx1, y1 + t1*dy1, t1, t2
end
-- (a)
-- \ .-'''-.
-- (q) \
-- | \ (c) |
-- \ \ /
-- `(q2)-'
-- \
-- (b)
--- Circle
-- @param ax,ay,bx,by segment, ray or line
-- @param cx,cy circle center
-- @param cr circle radius
-- @param lt defines a-b as either: "segment", "ray" or "line" (optional)
-- @return intersection point(s) and ratio(s) or nil
function line.circle(ax, ay, bx, by, cx, cy, cr, lt)
lt = lt or "segment"
local dx, dy = bx - ax, by - ay
local d = sqrt(dx*dx + dy*dy) -- len(dx, dy)
if d == 0 then
return -- degenerate
end
local nx, ny = dx/d, dy/d
local mx, my = ax - cx, ay - cy
local b = mx*nx + my*ny -- dot(mx, my, nx, ny)
local c = mx*mx + my*my - cr*cr -- dot(mx, my, mx, my) - cr*cr
if lt ~= "line" and c > 0 and b > 0 then
return -- non-intersecting
end
local discr = b*b - c
if discr < 0 then
return -- non-intersecting
end
discr = sqrt(discr)
local tmin = -b - discr
if lt ~= "line" and tmin < 0 then
tmin = 0
end
if lt == "segment" and tmin > d then
return -- non-intersecting
end
local tmax = discr - b
if lt == "segment" and tmax > d then
tmax = d
end
local qx, qy = ax + tmin*nx, ay + tmin*ny, tmin
if tmax == tmin then
return qx, qy, tmin/d
end
return qx, qy, tmin/d, ax + tmax*nx, ay + tmax*ny, tmax/d
end
-- (a)
-- \ --------
-- \| |
-- (q) |
-- |\ |
-- -(q2)---
-- \
-- (b)
--- Axis-aligned rectangle (l,t,r,b)
-- @param ax,ay,bx,by segment, ray or line
-- @param l,t left/top corner of the rectangle
-- @param r,b right/bottom corner of the rectangle
-- @param lt defines a-b as either: "segment", "ray" or "line" (optional)
-- @return intersection point(s) and ratio(s) or nil
function line.aabb(ax, ay, bx, by, l, t, r, b, lt)
lt = lt or "segment"
-- misaligned aabb?
if l > r then
l, r = r, l
end
if t > b then
t, b = b, t
end
local dx, dy = bx - ax, by - ay
local d = sqrt(dx*dx + dy*dy) -- len(dx, dy)
if d == 0 then
return -- degenerate
end
local nx, ny = dx/d, dy/d
local tmin, tmax
if lt == "segment" then
tmin = 0
tmax = d
elseif lt == "ray" then
tmin = 0
end
--if abs(dx) < EPSILON then
if dx == 0 then
if ax < l or ax > r then
return -- non-intersecting
end
else
local ood = 1/nx
local t1, t2 = (l - ax)*ood, (r - ax)*ood
if t1 > t2 then
t1, t2 = t2, t1
end
if tmin == nil or tmin < t1 then
tmin = t1
end
if tmax == nil or tmax > t2 then
tmax = t2
end
if tmin > tmax then
return -- non-intersecting
end
end
--if abs(dy) < EPSILON then
if dy == 0 then
if ay < t or ay > b then
return -- non-intersectings
end
else
local ood = 1/ny
local t1, t2 = (t - ay)*ood, (b - ay)*ood
if t1 > t2 then
t1, t2 = t2, t1
end
if tmin == nil or tmin < t1 then
tmin = t1
end
if tmax == nil or tmax > t2 then
tmax = t2
end
if tmin > tmax then
return -- non-intersecting
end
end
local qx, qy = ax + nx*tmin, ay + ny*tmin, tmin
if tmin == tmax then
return qx, qy, tmin
end
return qx, qy, tmin/d, ax + nx*tmax, ay + ny*tmax, tmax/d
end
--- Axis-aligned rectangle (second representation)
-- @param ax,ay,bx,by segment, ray or line
-- @param l,t left/top corner of the rectangle
-- @param w,h width and height of the rectangle
-- @param lt defines a-b as either: "segment", "ray" or "line" (optional)
-- @return intersection point(s) and ratio(s) or nil
function line.rect(ax, ay, bx, by, l, t, w, h, lt)
return line.aabb(ax, ay, bx, by, l, t, l + w, t + h, lt)
end
--- Axis-aligned rectangle (third representation)
-- @param ax,ay,bx,by segment, ray or line
-- @param x,y center point of the rectangle
-- @param hw,hh half-width and half-height extents of the rectangle
-- @param lt defines a-b as either: "segment", "ray" or "line" (optional)
-- @return intersection point(s) and ratio(s) or nil
function line.box(ax, ay, bx, by, x, y, hw, hh, lt)
return line.aabb(ax, ay, bx, by, x - hw, y - hh, x + hw, y + hh, lt)
end
return line
Code: Select all
--- Splits a path into directory, filename and extension
--- Assumes the path is a filename, if it does not end with a slash
--- Adapted from Paul Kulchenko
-- @param fn Filename
-- @return Directory path, filename and extension
function io.split(fn)
return string.match(fn, "(.-)([^\\/]-%.?([^%.\\/]*))$")
end
Code: Select all
function io.split(fn)
return string.match(fn, "(.-)([^\\/]-%.?([^%.\\/]*))$")
end
a,b,c = io.split("c:/dev/games/oops.lua")
print("path:".. (a or "nil"))
print("file:".. (b or "nil"))
print("ext:".. (c or "nil"))
Code: Select all
path:c:/dev/games/
file:oops.lua
ext:lua
Users browsing this forum: No registered users and 1 guest