Skip to content

Instantly share code, notes, and snippets.

@shakesoda
Created September 11, 2014 04:18
Show Gist options
  • Save shakesoda/a775635d21233c77ecc6 to your computer and use it in GitHub Desktop.
Save shakesoda/a775635d21233c77ecc6 to your computer and use it in GitHub Desktop.
axis + face button -> letters. the guts of a controller keyboard.
function gate(axis, num)
local function wrap(x)
return math.fmod(x, math.pi * 2)
end
if math.abs(axis.x) < 0.1 and math.abs(axis.y) < 0.1 then
return num + 1
end
local angle = math.atan2(axis.y, axis.x) -- in radians
angle = wrap(math.pi * 3 - angle) -- CCW -> CW + half rotation
--print(axis.x, axis.y, angle)
-- offset to the left by half the width of a segment
local angle_offset = angle + ((math.pi * 2) / (num * 2))
--print(angle_offset)
-- map to number of segments
local final_angle = angle_offset * (num / (math.pi * 2))
--print(final_angle)
-- un-quantized output is useful for display.
return math.floor(final_angle) + 1, final_angle + 1
end
-- This function is REALLY defensive because of how easy it is to screw up
-- key mappings when playing with different setups.
function chord(mapping, axis, face)
-- standard setup: 8x4. section #num_gates+1 is neutral.
local num_gates = 8
local num_faces = 4
assert(#mapping == num_gates + 1, "Invalid key map! Wrong number of sections.")
assert(axis ~= nil, "No axis!")
assert(axis.x ~= nil and axis.y ~= nil, "Axis needs x/y!")
assert(face ~= nil, "No face!")
assert(face >= 0, "Face in the wrong base! This data has become waste in your haste!")
-- gate the axis to one of 8 directions
local section = mapping[gate(axis, num_gates)]
assert(#section == num_faces, "Invalid key map! Wrong number of faces.")
return section[face]
end
-- mappings: in LURD order (CW from left)
local standard_map = {
{"e","t","a","o"}, -- left
{"i","n","s","r"},
{"h","d","l","u"}, -- up
{"c","m","f","y"},
{"w","g","p","b"}, -- right
{"v","k","x","q"},
{"j","z","\'","\""}, -- down
{",","!","?","."},
{":","(",")","/"} -- neutral
}
local tests = {
{
map = standard_map,
axis = { x = -1, y = 0 },
face = 1,
output = standard_map[1][1]
}
--
, {
map = standard_map,
axis = { x = 1, y = 0 },
face = 4,
output = standard_map[5][4]
}, {
map = standard_map,
axis = { x = 0, y = 1 },
face = 3,
output = standard_map[3][3]
}
--]]
}
for i, test in ipairs(tests) do
local output = chord(standard_map, test.axis, test.face)
local str = "Test #" .. i .. ": "
if output ~= test.output then
print(str .. "FAILED. Expected " .. test.output .. ", but got " .. output .. "!")
else
print(str .. "PASSED. (" .. output .. ")")
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment