Skip to content

Instantly share code, notes, and snippets.

@joselitosn
Last active January 19, 2018 03:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save joselitosn/95192237ced4b54fdfddb3481ccfe1e7 to your computer and use it in GitHub Desktop.
Save joselitosn/95192237ced4b54fdfddb3481ccfe1e7 to your computer and use it in GitHub Desktop.
Attempt to create a text graph using unicode braille - not finished
local class = require 'middleclass'
Node = class("Node")
function Node:initialize(data)
self.next = nil
self.data = nil
end
LinkedList = class("LinkedList")
function LinkedList:initialize()
self.size = 0
self.head = nil
self.tail = nil
end
function LinkedList:isEmpty()
if self.size <= 0 then
return true
end
return false
end
function LinkedList:insertAfter(node, data)
newnode = Node(data)
-- You can send nil or any value as node if the list is empty
if self.isEmpty() then
self.head = newnode
self.tail = newnode
-- If you sent nil as the node value, it inserts before the head
elseif node == nil then
newnode.next = self.head
self.head = newnode
else
-- If inserting after the tail, update the tail
if node == self.tail then
self.tail = newnode
newnode.next = node.next
node.next = node
end
-- Increase the list size
self.size = self.size + 1
end
--- Inserts a new node at the head of the list
function LinkedList:push(data)
self.insertAfter(nil, data)
end
--- Remove and returns the head from the list
-- @return Return the head node
function LinkedList:pull()
-- If the list is empty returns null
if self.head == nil then
return nil
end
node = self.head
self.head = node.next
-- Decrease the list size
self.size = self.size - 1
-- If there was only one node in the list, update the tail
if self.head == nil then
self.tail = nil
end
return node
end
Queue = class("Queue", LinkedList)
function Queue:initialize()
LinkedList.initialize(self)
end
function Queue:enqueue(data)
self.insertAfter(self.tail, data)
end
function Queue:dequeue()
return self.pull()
end
graphvalues = Queue:new()
-----------------------
--- Round to integer using the round to nearest even algorithm
-- Based on the article: https://mattjibson.com/blog/2017/07/06/rounding/
-- And the source code: https://github.com/postgres/postgres/blob/REL9_6_3/src/port/rint.c
function round(num)
-- Check if num is NaN and return it unchanged
if num ~= num then
return num
end
if num <= 0 then
-- Both positive and negative zero should return unchanged
if num == 0.0 then
return num
end
originalvalue = num
num = num + 0.5
if num >= 0.0 then
return -0.0
end
if num == originalvalue + 1.0 then
return originalvalue
end
result = math.floor(num)
if result ~= num then
return result
end
return math.floor(num * 0.5) * 2.0
else
originalvalue = num
num = num -0.5
if num <= 0.0 then
return num
end
if num == originalvalue - 1.0 then
return originalvalue
end
result = math.ceil(num)
if result ~= num then
return result
end
return math.ceil(num * 0.5) * 2.0
end
end
function max(arraytable)
-- If not a table is sent, return nil
if arraytable == nil then
return nil
end
i, v = next(arraytable, nil)
maxnum = v
while i do
i, v = next(arraytable, i)
if v > maxnum then
maxnum = v
end
end
return maxnum
end
graph = {}
function graph:new(x, y, width, height, backgroundColor, foregroundColor)
self.x = x
self.y = y
self.width = width
self.height = height
self.backgroundColor = backgroundColor
self.foregroundColor = foregroundColor
self.values = {}
self.canvas = {}
self.range = nil
end
function graph:insert(value)
table.insert(self.values, value)
-- If we have more values than the graph size, remove the oldest ones
while #self.values > self.width * 2 do
table.remove(self.values, 1)
end
end
function graph:render()
local range = self.range or max(self.values)
local printvertical = true
if self.width >= self.height then
self.printvertical = false
end
end
-- Insert the current input value converted to RF
table.insert(graph.values, component.induction_matrix.getInput()/2.5)
-- Start filling the dot representation for each value, from back to front
numdots = round((graph.values[i] * graph.height * 4) / currentmax)
numdots = {}
for i = #graph.values, 1, -2 do
numdots[1] = round((graph.values[i] * graph.height * 4) / currentmax)
numdots[2] = round(((graph.values[i-1] or 0) * graph.height * 4) / currentmax)
for j = graph.height, 1, -1 do
if j * 4 >
end
value = 0
while numdots[1] > 0 or numdots[2] > 0 do
if numdots[1] / 4 > 1 then
value = value | 0xB8
elseif numdots[1] == 3 then
value = value | 0xB0
elseif numdots[1] == 2 then
value = value | 0xA0
elseif numdots[1] == 1 then
value = value | 0x80
end
if numdots[2] / 4 > 1 then
value = value | 0x47
elseif numdots[2] == 3 then
value = value | 0x46
elseif numdots[2] == 2 then
value = value | 0x44
elseif numdots[2] == 1 then
value = value | 0x40
end
numdots[1] = numdots[1] - 4
numdots[2] = numdots[2] - 4
end
if value == 0 then
value = " "
else
value = value | 0x2800
end
fulldots = math.floor(numdots / graph.height)
h = graph.height
while numdots > 4 do
end
end
table.insert(graph.dots, {})
if graph.printvertical then
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment