Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- f = fs.open("CCG/CCG", "w")
- f.write([=[
- os.loadAPI("CCG/Mat2")
- os.loadAPI("CCG/Vec2")
- os.loadAPI("CCG/Mat3")
- os.loadAPI("CCG/Vec3")
- os.loadAPI("CCG/Stack")
- RADIANS = false
- DEGREES = true
- POINTS = 0
- TRIANGLES = 1
- QUADS = 2
- WHITE = 1
- ORANGE = 2
- MAGENTA = 4
- LIGHT_BLUE = 8
- YELLOW = 16
- LIME = 32
- PINK = 64
- GRAY = 128
- LIGHT_GRAY = 256
- CYAN = 512
- PURPLE = 1024
- BLUE = 2048
- BROWN = 4096
- GREEN = 8192
- RED = 16384
- BLACK = 32768
- local Prototype = {}
- local mt = {__index = Prototype}
- local function newPixel(self, pos, background, foreground, chr)
- local x = pos.x
- local y = pos.y
- self.pixels[#self.pixels + 1] = {x, y, background, foreground, chr}
- end
- local function round(x)
- i, d = math.modf(x)
- if d >= 0.5 then
- return i + 1
- end
- return i
- end
- local function drawPixel(self, pixel)
- local x = round(pixel[1])
- local y = round(pixel[2])
- if x >= self.xMin and x <= self.xMax and y >= self.yMin and y <= self.yMax then
- local mon = self.mon
- mon.setCursorPos(self.originX + x, self.originY - y)
- mon.setBackgroundColor(pixel[3])
- mon.setTextColor(pixel[4])
- mon.write(pixel[5])
- end
- end
- local function newVertex(self, pos)
- self.prog[#self.prog + 1] = {pos, self.background, self.foreground, self.char}
- end
- local function points(self)
- for _, v in pairs(self.prog) do
- newPixel(self, v[1], v[2], v[3], v[4])
- end
- end
- local function bottomFlatTriangle(v1, v2, v3)
- local frags = {}
- local invslope1 = (v2.x - v1.x) / (v2.y - v1.y)
- local invslope2 = (v3.x - v1.x) / (v3.y - v1.y)
- local curx1 = v1.x
- local curx2 = v1.x
- for scanlineY = v1.y, v2.y do
- local inc = 1
- if curx1 > curx2 then
- inc = -1
- end
- for x = curx1, curx2, inc do
- frags[#frags + 1] = Vec3.new(x, scanlineY, 1)
- end
- curx1 = curx1 + invslope1
- curx2 = curx2 + invslope2
- end
- return frags
- end
- local function topFlatTriangle(v1, v2, v3)
- local frags = {}
- local invslope1 = (v3.x - v1.x) / (v3.y - v1.y)
- local invslope2 = (v3.x - v2.x) / (v3.y - v2.y)
- local curx1 = v3.x
- local curx2 = v3.x
- for scanlineY = v3.y, v1.y, -1 do
- local inc = 1
- if curx1 > curx2 then
- inc = -1
- end
- for x = curx1, curx2, inc do
- frags[#frags + 1] = Vec3.new(x, scanlineY, 1)
- end
- curx1 = curx1 - invslope1
- curx2 = curx2 - invslope2
- end
- return frags
- end
- local function sortByY(a, b, c)
- local v1 = a[1]
- local v2 = b[1]
- local v3 = c[1]
- if v1.y <= v2.y and v2.y <= v3.y then
- return a, b, c
- elseif v1.y <= v3.y and v3.y <= v2.y then
- return a, c, b
- elseif v2.y <= v1.y and v1.y <= v3.y then
- return b, a, c
- elseif v2.y <= v3.y and v3.y <= v1.y then
- return b, c, a
- elseif v3.y <= v1.y and v1.y <= v2.y then
- return c, a, b
- elseif v3.y <= v2.y and v2.y <= v1.y then
- return c, b, a
- end
- end
- local function triangle(self, a2, b2, c2)
- local vt1 = a2[1]
- local vt2 = b2[1]
- local vt3 = c2[1]
- local a, b, c = sortByY(a2, b2, c2)
- local v1 = a[1]
- local v2 = b[1]
- local v3 = c[1]
- if v2.y == v3.y then
- for k, v in ipairs(bottomFlatTriangle(v1, v2, v3)) do
- local dist1 = (v - vt1):magSquared()
- local dist2 = (v - vt2):magSquared()
- local dist3 = (v - vt3):magSquared()
- local closest = math.min(dist1, math.min(dist2, dist3))
- if closest == dist1 then
- newPixel(self, v, a2[2], a2[3], a2[4])
- elseif closest == dist2 then
- newPixel(self, v, b2[2], b2[3], b2[4])
- elseif closest == dist3 then
- newPixel(self, v, c2[2], c2[3], c2[4])
- end
- end
- elseif v1.y == v2.y then
- for k, v in ipairs(topFlatTriangle(v1, v2, v3)) do
- local dist1 = (v - vt1):magSquared()
- local dist2 = (v - vt2):magSquared()
- local dist3 = (v - vt3):magSquared()
- local closest = math.min(dist1, math.min(dist2, dist3))
- if closest == dist1 then
- newPixel(self, v, a2[2], a2[3], a2[4])
- elseif closest == dist2 then
- newPixel(self, v, b2[2], b2[3], b2[4])
- elseif closest == dist3 then
- newPixel(self, v, c2[2], c2[3], c2[4])
- end
- end
- else
- local v4 = Vec3.new((v1.x + ((v2.y - v1.y) / (v3.y - v1.y)) * (v3.x - v1.x)), v2.y, 1)
- local frags1 = bottomFlatTriangle(v1, v2, v4)
- local frags2 = topFlatTriangle(v2, v4, v3)
- for k, v in ipairs(frags2) do
- local dist1 = (v - vt1):magSquared()
- local dist2 = (v - vt2):magSquared()
- local dist3 = (v - vt3):magSquared()
- local closest = math.min(dist1, math.min(dist2, dist3))
- if closest == dist1 then
- newPixel(self, v, a2[2], a2[3], a2[4])
- elseif closest == dist2 then
- newPixel(self, v, b2[2], b2[3], b2[4])
- elseif closest == dist3 then
- newPixel(self, v, c2[2], c2[3], c2[4])
- end
- end
- for k, v in ipairs(frags1) do
- local dist1 = (v - vt1):magSquared()
- local dist2 = (v - vt2):magSquared()
- local dist3 = (v - vt3):magSquared()
- local closest = math.min(dist1, math.min(dist2, dist3))
- if closest == dist1 then
- newPixel(self, v, a2[2], a2[3], a2[4])
- elseif closest == dist2 then
- newPixel(self, v, b2[2], b2[3], b2[4])
- elseif closest == dist3 then
- newPixel(self, v, c2[2], c2[3], c2[4])
- end
- end
- end
- end
- local function triangles(self)
- local l = #self.prog
- local count = (l - (l % 3)) / 3
- for i = 0, count - 1 do
- triangle(self, self.prog[i * 3 + 1], self.prog[i * 3 + 2], self.prog[i * 3 + 3])
- end
- end
- local function quad(self, a2, b2, c2, d2)
- local vt1 = a2[1]
- local vt2 = b2[1]
- local vt3 = c2[1]
- local vt4 = d2[1]
- local a, b, c = sortByY(a2, b2, d2)
- local v1 = a[1]
- local v2 = b[1]
- local v3 = c[1]
- if v2.y == v3.y then
- for k, v in ipairs(bottomFlatTriangle(v1, v2, v3)) do
- local dist1 = (v - vt1):magSquared()
- local dist2 = (v - vt2):magSquared()
- local dist3 = (v - vt3):magSquared()
- local dist4 = (v - vt4):magSquared()
- local closest = math.min(math.min(dist1, dist2), math.min(dist3, dist4))
- if closest == dist1 then
- newPixel(self, v, a2[2], a2[3], a2[4])
- elseif closest == dist2 then
- newPixel(self, v, b2[2], b2[3], b2[4])
- elseif closest == dist3 then
- newPixel(self, v, c2[2], c2[3], c2[4])
- elseif closest == dist3 then
- newPixel(self, v, c2[2], c2[3], c2[4])
- elseif closest == dist4 then
- newPixel(self, v, d2[2], d2[3], d2[4])
- end
- end
- elseif v1.y == v2.y then
- for k, v in ipairs(topFlatTriangle(v1, v2, v3)) do
- local dist1 = (v - vt1):magSquared()
- local dist2 = (v - vt2):magSquared()
- local dist3 = (v - vt3):magSquared()
- local dist4 = (v - vt4):magSquared()
- local closest = math.min(math.min(dist1, dist2), math.min(dist3, dist4))
- if closest == dist1 then
- newPixel(self, v, a2[2], a2[3], a2[4])
- elseif closest == dist2 then
- newPixel(self, v, b2[2], b2[3], b2[4])
- elseif closest == dist3 then
- newPixel(self, v, c2[2], c2[3], c2[4])
- elseif closest == dist3 then
- newPixel(self, v, c2[2], c2[3], c2[4])
- elseif closest == dist4 then
- newPixel(self, v, d2[2], d2[3], d2[4])
- end
- end
- else
- local v4 = Vec3.new((v1.x + ((v2.y - v1.y) / (v3.y - v1.y)) * (v3.x - v1.x)), v2.y, 1)
- local frags1 = bottomFlatTriangle(v1, v2, v4)
- local frags2 = topFlatTriangle(v2, v4, v3)
- for k, v in ipairs(frags2) do
- local dist1 = (v - vt1):magSquared()
- local dist2 = (v - vt2):magSquared()
- local dist3 = (v - vt3):magSquared()
- local dist4 = (v - vt4):magSquared()
- local closest = math.min(math.min(dist1, dist2), math.min(dist3, dist4))
- if closest == dist1 then
- newPixel(self, v, a2[2], a2[3], a2[4])
- elseif closest == dist2 then
- newPixel(self, v, b2[2], b2[3], b2[4])
- elseif closest == dist3 then
- newPixel(self, v, c2[2], c2[3], c2[4])
- elseif closest == dist3 then
- newPixel(self, v, c2[2], c2[3], c2[4])
- elseif closest == dist4 then
- newPixel(self, v, d2[2], d2[3], d2[4])
- end
- end
- for k, v in ipairs(frags1) do
- local dist1 = (v - vt1):magSquared()
- local dist2 = (v - vt2):magSquared()
- local dist3 = (v - vt3):magSquared()
- local dist4 = (v - vt4):magSquared()
- local closest = math.min(math.min(dist1, dist2), math.min(dist3, dist4))
- if closest == dist1 then
- newPixel(self, v, a2[2], a2[3], a2[4])
- elseif closest == dist2 then
- newPixel(self, v, b2[2], b2[3], b2[4])
- elseif closest == dist3 then
- newPixel(self, v, c2[2], c2[3], c2[4])
- elseif closest == dist3 then
- newPixel(self, v, c2[2], c2[3], c2[4])
- elseif closest == dist4 then
- newPixel(self, v, d2[2], d2[3], d2[4])
- end
- end
- end
- local a, b, c = sortByY(b2, c2, d2)
- local v1 = a[1]
- local v2 = b[1]
- local v3 = c[1]
- if v2.y == v3.y then
- for k, v in ipairs(bottomFlatTriangle(v1, v2, v3)) do
- local dist1 = (v - vt1):magSquared()
- local dist2 = (v - vt2):magSquared()
- local dist3 = (v - vt3):magSquared()
- local dist4 = (v - vt4):magSquared()
- local closest = math.min(math.min(dist1, dist2), math.min(dist3, dist4))
- if closest == dist1 then
- newPixel(self, v, a2[2], a2[3], a2[4])
- elseif closest == dist2 then
- newPixel(self, v, b2[2], b2[3], b2[4])
- elseif closest == dist3 then
- newPixel(self, v, c2[2], c2[3], c2[4])
- elseif closest == dist3 then
- newPixel(self, v, c2[2], c2[3], c2[4])
- elseif closest == dist4 then
- newPixel(self, v, d2[2], d2[3], d2[4])
- end
- end
- elseif v1.y == v2.y then
- for k, v in ipairs(topFlatTriangle(v1, v2, v3)) do
- local dist1 = (v - vt1):magSquared()
- local dist2 = (v - vt2):magSquared()
- local dist3 = (v - vt3):magSquared()
- local dist4 = (v - vt4):magSquared()
- local closest = math.min(math.min(dist1, dist2), math.min(dist3, dist4))
- if closest == dist1 then
- newPixel(self, v, a2[2], a2[3], a2[4])
- elseif closest == dist2 then
- newPixel(self, v, b2[2], b2[3], b2[4])
- elseif closest == dist3 then
- newPixel(self, v, c2[2], c2[3], c2[4])
- elseif closest == dist3 then
- newPixel(self, v, c2[2], c2[3], c2[4])
- elseif closest == dist4 then
- newPixel(self, v, d2[2], d2[3], d2[4])
- end
- end
- else
- local v4 = Vec3.new((v1.x + ((v2.y - v1.y) / (v3.y - v1.y)) * (v3.x - v1.x)), v2.y, 1)
- local frags1 = bottomFlatTriangle(v1, v2, v4)
- local frags2 = topFlatTriangle(v2, v4, v3)
- for k, v in ipairs(frags2) do
- local dist1 = (v - vt1):magSquared()
- local dist2 = (v - vt2):magSquared()
- local dist3 = (v - vt3):magSquared()
- local dist4 = (v - vt4):magSquared()
- local closest = math.min(math.min(dist1, dist2), math.min(dist3, dist4))
- if closest == dist1 then
- newPixel(self, v, a2[2], a2[3], a2[4])
- elseif closest == dist2 then
- newPixel(self, v, b2[2], b2[3], b2[4])
- elseif closest == dist3 then
- newPixel(self, v, c2[2], c2[3], c2[4])
- elseif closest == dist3 then
- newPixel(self, v, c2[2], c2[3], c2[4])
- elseif closest == dist4 then
- newPixel(self, v, d2[2], d2[3], d2[4])
- end
- end
- for k, v in ipairs(frags1) do
- local dist1 = (v - vt1):magSquared()
- local dist2 = (v - vt2):magSquared()
- local dist3 = (v - vt3):magSquared()
- local dist4 = (v - vt4):magSquared()
- local closest = math.min(math.min(dist1, dist2), math.min(dist3, dist4))
- if closest == dist1 then
- newPixel(self, v, a2[2], a2[3], a2[4])
- elseif closest == dist2 then
- newPixel(self, v, b2[2], b2[3], b2[4])
- elseif closest == dist3 then
- newPixel(self, v, c2[2], c2[3], c2[4])
- elseif closest == dist3 then
- newPixel(self, v, c2[2], c2[3], c2[4])
- elseif closest == dist4 then
- newPixel(self, v, d2[2], d2[3], d2[4])
- end
- end
- end
- end
- local function quads(self)
- local l = #self.prog
- local count = (l - (l % 4)) / 4
- for i = 0, count - 1 do
- quad(self, self.prog[i * 4 + 1], self.prog[i * 4 + 2], self.prog[i * 4 + 3], self.prog[i * 4 + 4])
- end
- end
- local function fragment(self)
- if self.progID == POINTS then
- points(self)
- elseif self.progID == TRIANGLES then
- triangles(self)
- elseif self.progID == QUADS then
- quads(self)
- end
- end
- local function angle(mode, i)
- if mode then
- if i >= 360 then
- return angle(mode, i - 360)
- elseif i < 0 then
- return angle(mode, i + 360)
- else
- return math.rad(i)
- end
- else
- if i >= 2 * math.pi then
- return angle(mode, i - 2 * math.pi)
- elseif i < 0 then
- return angle(mode, i + 2 * math.pi)
- else
- return i
- end
- end
- end
- function Prototype:loadIdentity()
- stack.current.value = Mat3.identity()
- end
- function Prototype:pushMatrix(matrix)
- if type(matrix) == "table" then
- if matrix.type == "mat2" then
- self.stack:push(matrix:mat3())
- end
- else
- self.stack:push(Mat3.identity())
- end
- end
- function Prototype:popMatrix()
- return self.stack:pop()
- end
- function Prototype:vertex(x, y)
- if type(x) == "number" and type(y) == "number" then
- x = Vec3.new(x, y, 1)
- local matrices = self.stack:toTable()
- for i = #matrices, 1, -1 do
- x = x * matrices[i]
- end
- newVertex(self, x)
- elseif type(x) == "table" then
- if x.type == "vec2" then
- x = x:vec3(1)
- local matrices = self.stack:toTable()
- for i = #matrices, 1, -1 do
- x = x * matrices[i]
- end
- newVertex(self, x)
- end
- end
- end
- function Prototype:draw()
- fragment(self)
- for k, v in ipairs(self.pixels) do
- drawPixel(self, v)
- end
- end
- function Prototype:rotate(i)
- i = angle(self.angleMode, i)
- self.stack.current.value = self.stack.current.value * createRotate(i)
- end
- function Prototype:translate(x, y)
- if type(x) == "number" and type(y) == "number" then
- self.stack.current.value = stack.current.value * createTranslate(x, y)
- elseif type(x) == "table" and x.type == "vec2" then
- self.stack.current.value = stack.current.value * createTranslate(x.x, x.y)
- end
- end
- function Prototype:scale(x, y)
- if type(x) == "number" and type(y) == "number" then
- self.stack.current.value = stack.current.value * createScale(x, y)
- elseif type(x) == "table" and x.type == "vec2" then
- self.stack.current.value = stack.current.value * createScale(x.x, x.y)
- end
- end
- function Prototype:applyMatrix(matrix)
- if type(matrix) == "table" and matrix.type == "mat2" then
- self.stack.current.value = stack.current.value * matrix:mat3()
- end
- end
- function Prototype:setAngleMode(mode)
- self.angleMode = mode
- end
- function Prototype:setBackground(color)
- self.background = color
- end
- function Prototype:setForeground(color)
- self.foreground = color
- end
- function Prototype:setChar(char)
- self.char = char
- end
- function Prototype:setClearColor(color)
- self.clear = color
- end
- function Prototype:pixelClear()
- self.pixels = {}
- end
- function Prototype:matrixClear()
- self.stack = Stack.new()
- pushMatrix()
- end
- function Prototype:screenClear()
- self.mon.setBackgroundColor(self.clear)
- for x = self.xMin, self.xMax do
- for y = self.yMin, self.yMax do
- self.mon.setCursorPos(self.originX + x, self.originY - y)
- self.mon.write(" ")
- end
- end
- end
- function Prototype:begin(prog)
- fragment(self)
- self.progID = prog
- self.prog = {}
- end
- function Prototype:finish()
- self:begin(POINTS)
- end
- function createTranslate(x, y)
- return Mat3.new(1, 0, x,
- 0, 1, y,
- 0, 0, 1)
- end
- function createScale(x, y)
- return Mat3.new(x, 0, 0,
- 0, y, 0,
- 0, 0, 1)
- end
- function createRotate(radians)
- s = math.sin(radians)
- c = math.cos(radians)
- return Mat3.new(c, s, 0,
- -s, c, 0,
- 0, 0, 1)
- end
- function createScale2(x, y)
- return Mat2.new(x, 0,
- 0, y)
- end
- function createRotate2(radians)
- s = math.sin(radians)
- c = math.cos(radians)
- return Mat2.new(c, s,
- -s, c)
- end
- function createContext(originX, originY, xMin, yMin, xMax, yMax, mon)
- t = {["originX"] = originX, ["originY"] = originY,
- ["xMin"] = xMin, ["yMin"] = yMin,
- ["xMax"] = xMax, ["yMax"] = yMax,
- ["mon"] = mon, ["angleMode"] = DEGREES, ["char"] = " ", ["background"] = BLACK, ["foreground"] = WHITE, ["clear"] = BLACK, progID = POINTS,
- pixels = {}, prog = {}, stack = Stack.new()}
- setmetatable(t, mt)
- t:pushMatrix()
- return t
- end]=])
- f.close()
- f = fs.open("CCG/Mat2", "w")
- f.write([=[
- local cofactorMap = {{1, -1},
- {-1, 1}}
- function add(a, b)
- return new(a[1][1] + b[1][1], a[2][1] + b[2][1],
- a[1][2] + b[1][2], a[2][2] + b[2][2])
- end
- function sub(a, b)
- return new(a[1][1] - b[1][1], a[2][1] - b[2][1],
- a[1][2] - b[1][2], a[2][2] - b[2][2])
- end
- function mult(a, b)
- if type(b) == "number" then
- return new(a[1][1] * b, a[2][1] * b,
- a[1][2] * b, a[2][2] * b)
- elseif type(a) == "number" then
- return new(b[1][1] * a, b[2][1] * a,
- b[1][2] * a, b[2][2] * a)
- elseif type(a) == "table" and type(b) == "table" then
- if a.type == "mat2" and b.type == "mat2" then
- return new(a[1][1] * b[1][1] + a[2][1] * b[1][2], a[1][1] * b[2][1] + a[2][1] * b[2][2],
- a[1][2] * b[1][1] + a[2][2] * b[2][1], a[2][1] * b[1][2] + a[2][2] * b[2][2])
- elseif a.type == "mat2" and b.type == "vec2" then
- return b * a
- end
- end
- error("cannot multiply matrix", 2)
- end
- function div(a, b)
- if type(b) == "number" then
- return new(a[1][1] / b, a[2][1] / b,
- a[1][2] / b, a[2][2] / b)
- elseif type(a) == "table" and type(b) == "table" then
- if a.type == "mat2" and b.type == "mat2" then
- return a * b:inv()
- end
- end
- error("cannot divide matrix", 2)
- end
- function transpose(a)
- return new(a[1][1], a[1][2],
- a[2][1], a[2][2])
- end
- function minor(a, col, row)
- local ret = 0
- for x = 1, 2 do
- for y = 1, 2 do
- if x ~= col and y ~= row then
- ret = a[x][y]
- end
- end
- end
- end
- function cofactor(a, col, row)
- return a:minor(col, row) * cofactorMap[col][row]
- end
- function det(a)
- return a[1][1] * a[2][2] - a[2][1] * a[1][2]
- end
- function inv(a)
- return 1 / a:det() * new(a[2][2], -a[2][1]
- -a[1][2], a[2][2])
- end
- function mat3(a)
- return Mat3.new(a[1][1], a[2][1], 0,
- a[2][1], a[2][2], 0,
- 0, 0, 1)
- end
- --[[
- To be implemented
- function Mat4(a)
- return Mat4.new(a[1][1], a[2][1], 0, 0,
- a[1][2], a[2][2], 0, 0,
- 0, 0, 1, 0,
- 0, 0, 0, 1)
- end]]
- function identity()
- return new(1, 0,
- 0, 1)
- end
- local Prototype = {["type"] = "mat2"}
- local mt = {}
- mt.__index = Prototype
- function new(a, b,
- c, d)
- t = {{a, c}, {b, d}}
- setmetatable(t, mt)
- return t
- end
- Prototype.add = add
- Prototype.div = div
- Prototype.mult = mult
- Prototype.sub = sub
- Prototype.cofactor = cofactor
- Prototype.minor = minor
- Prototype.inv = inv
- Prototype.det = det
- Prototype.transpose = transpose
- Prototype.mat3 = mat3
- --Prototype.Mat4 = Mat4
- mt.__add = add
- mt.__mul = mult
- mt.__div = div
- mt.__sub = sub
- function mt.__unm(a)
- return -1 * a
- end
- function mt.__tostring(a)
- return a[1][1] .. ", " .. a[2][1] .."\n" ..
- a[1][2] .. ", " .. a[2][2]
- end
- ]=])
- f.close()
- f = fs.open("CCG/Mat3", "w")
- f.write([=[
- local cofactorMap = {{1, -1, 1},
- {-1, 1, -1},
- {1, -1, 1}}
- function add(a, b)
- return new(a[1][1] + b[1][1], a[2][1] + b[2][1], a[3][1] + b[3][1],
- a[1][2] + b[1][2], a[2][2] + b[2][2], a[3][2] + b[3][2],
- a[1][3] + b[1][3], a[2][3] + b[2][3], a[3][3] + b[3][3])
- end
- function sub(a, b)
- return new(a[1][1] - b[1][1], a[2][1] - b[2][1], a[3][1] - b[3][1],
- a[1][2] - b[1][2], a[2][2] - b[2][2], a[3][2] - b[3][2],
- a[1][3] - b[1][3], a[2][3] - b[2][3], a[3][3] - b[3][3])
- end
- function mult(a, b)
- if type(b) == "number" then
- return new(a[1][1] * b, a[2][1] * b, a[3][1] * b,
- a[1][2] * b, a[2][2] * b, a[3][2] * b,
- a[1][3] * b, a[2][3] * b, a[3][3] * b)
- elseif type(a) == "number" then
- return new(b[1][1] * a, b[2][1] * a, b[3][1] * a,
- b[1][2] * a, b[2][2] * a, b[3][2] * a,
- b[1][3] * a, b[2][3] * a, b[3][3] * a)
- elseif type(a) == "table" and type(b) == "table" then
- if a.type == "mat3" and b.type == "mat3" then
- local c = a[1][1] * b[1][1] + a[2][1] * b[1][2] + a[3][1] * b[1][3]
- local d = a[1][1] * b[2][1] + a[2][1] * b[2][2] + a[3][1] * b[2][3]
- local e = a[1][1] * b[3][1] + a[2][1] * b[3][2] + a[3][1] * b[3][3]
- local f = a[1][2] * b[1][1] + a[2][2] * b[1][2] + a[3][2] * b[1][3]
- local g = a[1][2] * b[2][1] + a[2][2] * b[2][2] + a[3][2] * b[2][3]
- local h = a[1][2] * b[3][1] + a[2][2] * b[3][2] + a[3][2] * b[3][3]
- local i = a[1][3] * b[1][1] + a[2][3] * b[1][2] + a[3][3] * b[1][3]
- local j = a[1][3] * b[2][1] + a[2][3] * b[2][2] + a[3][3] * b[2][3]
- local k = a[1][3] * b[3][1] + a[2][3] * b[3][2] + a[3][3] * b[3][3]
- return new(
- c, d, e,
- f, g, h,
- i, j, k
- )
- elseif a.type == "mat3" and b.type == "vec3" then
- return b * a
- end
- end
- error("cannot multiply matrix", 2)
- end
- function div(a, b)
- if type(b) == "number" then
- return new(a[1][1] / b, a[2][1] / b, a[3][1] / b,
- a[1][2] / b, a[2][2] / b, a[3][2] / b,
- a[1][3] / b, a[2][3] / b, a[3][3] / b)
- elseif type(a) == "table" and type(b) == "table" then
- if a.type == "mat3" and b.type == "mat3" then
- return a * b:inv()
- end
- end
- error("cannot divide matrix", 2)
- end
- function transpose(a)
- return new(a[1][1], a[1][2], a[1][3],
- a[2][1], a[2][2], a[2][3],
- a[3][1], a[3][2], a[3][3])
- end
- function minor(a, col, row)
- local ret = {}
- local xx = 0
- for x = 1, 3 do
- if x ~= col then
- xx = xx + 1
- end
- local yy = 0
- for y = 1, 3 do
- if y ~= col then
- yy = yy + 1
- end
- if x ~= col and y ~= col then
- ret[xx][yy] = a[x][y]
- end
- end
- end
- return Mat2.new(ret[1][1], ret[2][1],
- ret[1][2], ret[2][2]):det()
- end
- function cofactor(a, col, row)
- return a:minor(col, row) * cofactorMap[col][row]
- end
- function det(a)
- return a[1][1] * a[2][2] * a[3][3] +
- a[2][1] * a[3][2] * a[1][3] +
- a[3][1] * a[1][2] * a[2][3] -
- a[3][1] * a[2][2] * a[1][3] -
- a[2][1] * a[1][2] * a[3][3] -
- a[1][1] * a[3][2] * a[2][3]
- end
- function inv(a)
- return 1 / a:det() * new((a[2][2] * a[3][3] - a[3][2] * a[2][3]), -(a[2][1] * a[3][3] - a[3][1] * a[2][3]), (a[2][1] * a[3][2] - a[3][1] * a[2][2]),
- -(a[1][2] * a[3][3] - a[3][2] * a[1][3]), (a[1][1] * a[3][3] - a[3][1] * a[1][3]), -(a[1][1] * a[3][2] - a[3][1] * a[1][2]),
- (a[1][2] * a[2][3] - a[2][2] * a[1][3]), -(a[1][1] * a[2][3] -a[2][1] * a[1][3]), (a[1][1] * a[2][2] - a[2][1] * a[1][2]))
- end
- --[[
- To be implemented
- function Mat4(a)
- return Mat4.new(a[1][1], a[2][1], a[3][1], 0,
- a[1][2], a[2][2], a[3][2], 0,
- a[1][3], a[2][3], a[3][3], 0,
- 0, 0, 0, 1)
- end]]
- function identity()
- return new(1, 0, 0,
- 0, 1, 0,
- 0, 0, 1)
- end
- local Prototype = {["type"] = "mat3"}
- local mt = {}
- mt.__index = Prototype
- function new(a, b, c,
- d, e, f,
- g, h, i)
- t = {{a, d, g}, {b, e, h}, {c, f, i}}
- setmetatable(t, mt)
- return t
- end
- Prototype.add = add
- Prototype.div = div
- Prototype.mult = mult
- Prototype.sub = sub
- Prototype.cofactor = cofactor
- Prototype.minor = minor
- Prototype.inv = inv
- Prototype.det = det
- Prototype.transpose = transpose
- Prototype.cross = cross
- --Prototype.Mat4 = Mat4
- mt.__add = add
- mt.__mul = mult
- mt.__div = div
- mt.__sub = sub
- mt.__unm = function(a)
- return -1 * a
- end
- function mt.__tostring(a)
- return a[1][1] .. ", " .. a[2][1] .. ", " .. a[3][1] .. "\n" ..
- a[1][2] .. ", " .. a[2][2] .. ", " .. a[2][3] .. "\n" ..
- a[1][3] .. ", " .. a[2][3] .. ", " .. a[3][3]
- end
- ]=])
- f.close()
- f = fs.open("CCG/Stack", "w")
- f.write([=[
- local function newEntry(nxt, val)
- return {["next"] = nxt, ["value"] = val}
- end
- function push(stack, value)
- stack.current = newEntry(stack.current, value)
- end
- function pop(stack)
- if stack.current ~= nil then
- local ret = stack.current.value
- stack.current = stack.current.next
- return ret
- end
- return nil
- end
- function forEach(stack, func)
- local v = stack.current
- local k = 1
- while v ~= nil do
- func(k, v.value)
- k = k + 1
- v = v.next
- end
- end
- function toTable(stack)
- local ret = {}
- stack:forEach(function(k, v)
- ret[k] = v
- end)
- return ret
- end
- local Prototype = {}
- Prototype.push = push
- Prototype.pop = pop
- Prototype.forEach = forEach
- Prototype.toTable = toTable
- local mt = {}
- mt.__index = Prototype
- function new()
- t = {}
- setmetatable(t, mt)
- return t
- end]=])
- f.close()
- f = fs.open("CCG/test", "w")
- f.write([=[
- os.loadAPI("CCG/CCG")
- x, y = term.getSize()
- originX = math.floor(x / 2)
- originY = math.floor(y / 2)
- xMin = 1 - originX
- yMin = originY - y
- xMax = x - originX
- yMax = originY - 1
- g = CCG.createContext(originX, originY, xMin, yMin, xMax, yMax, term)
- while true do
- g:setBackground(CCG.GREEN)
- g:begin(CCG.QUADS)
- g:vertex(-5, 5)
- g:setBackground(CCG.RED)
- g:vertex(5, 5)
- g:setBackground(CCG.BLUE)
- g:vertex(5, -5)
- g:setBackground(CCG.PURPLE)
- g:vertex(-5, -5)
- g:finish()
- g:draw()
- sleep(0.1)
- g:pixelClear()
- g:screenClear()
- g:rotate(3)
- end
- --g:setBackground(CCG.RED)
- --g:vertex(0, 0)
- term.clear()
- g:draw()
- term.setCursorPos(1, 1)
- sleep(3)]=])
- f.close()
- f = fs.open("CCG/Vec2", "w")
- f.write([=[
- function add(a, b)
- return new(a.x + b.x, a.y + b.y)
- end
- local function sub(a, b)
- return new(a.x - b.x, a.y - b.y)
- end
- function mult(a, b)
- if type(b) == "number" then
- return new(a.x * b, a.y * b)
- elseif type(a) == "number" then
- return new(b.x * a, b.y * a)
- elseif type(a) == "table" and type(b) == "table" then
- if a.type == "vec2" and b.type == "vec2" then
- return a.x * b.x + a.y * b.y
- elseif a.type == "vec2" and b.type == "mat2" then
- return new(a.x * b[1][1] + a.y * b[2][1], a.x * b[1][2] + a.y * b[2][2])
- end
- end
- error("cannot multiply vector", 2)
- end
- function div(a, b)
- if type(b) == "number" then
- return new(a.x / b, a.y / b)
- elseif type(a) == "table" and type(b) == "table" then
- if a.type == "vec2" and b.type == "mat2" then
- return a * b:inv()
- end
- end
- error("cannot divide vector", 2)
- end
- function mag(a)
- return math.sqrt(magSquared(a))
- end
- function magSquared(a)
- return a.x * a.x + a.y * a.y
- end
- function reverse(a)
- return a * -1
- end
- function normalize(a)
- local m = mag(a)
- if m == 0 then
- error("cannot normalize a vector with length 0", 2)
- end
- return new(a.x / m, a.y / m)
- end
- function vec3(v, z)
- return Vec3.new(v.x, v.y, z)
- end
- --[[
- To be implemented
- function Vec4(v, z, a)
- return Vec4.new(v,x, v.y, z, a)
- end]]
- local Prototype = {["type"] = "vec2"}
- local mt = {}
- mt.__index = Prototype
- function mt.__tostring(a)
- return a.x .. ", " .. a.y
- end
- function new(x, y)
- t = {["x"] = x, ["y"] = y}
- setmetatable(t, mt)
- return t
- end
- Prototype.add = add
- Prototype.div = div
- Prototype.mult = mult
- Prototype.sub = sub
- Prototype.mag = mag
- Prototype.magSquared = magSquared
- Prototype.reverse = reverse
- Prototype.normalize = normalize
- Prototype.vec3 = vec3
- --Prototype.Vec4 = Vec4
- mt.__add = add
- mt.__mul = mult
- mt.__div = div
- mt.__sub = sub
- mt.__unm = reverse]=])
- f.close()
- f = fs.open("CCG/Vec3", "w")
- f.write([=[
- function add(a, b)
- return new(a.x + b.x, a.y + b.y, a.z + b.z)
- end
- local function sub(a, b)
- return new(a.x - b.x, a.y - b.y, a.z - b.z)
- end
- function mult(a, b)
- if type(b) == "number" then
- return new(a.x * b, a.y * b, a.z * b)
- elseif type(a) == "number" then
- return new(b.x * a, b.y * a, b.z * a)
- elseif type(a) == "table" and type(b) == "table" then
- if a.type == "vec3" and b.type == "vec3" then
- return a.x * b.x + a.y * b.y + a.z * b.z
- elseif a.type == "vec3" and b.type == "mat3" then
- return new(a.x * b[1][1] +
- a.y * b[2][1] +
- a.z * b[3][1],
- a.x * b[1][2] +
- a.y * b[2][2] +
- a.z * b[3][2],
- a.x * b[1][3] +
- a.y * b[2][3] +
- a.z * b[3][3])
- end
- end
- error("cannot multiply vector", 2)
- end
- function div(a, b)
- if type(b) == "number" then
- return new(a.x / b, a.y / b, a.z / b)
- elseif type(a) == "table" and type(b) == "table" then
- if a.type == "vec3" and b.type == "mat3" then
- return a * b:inv()
- end
- end
- error("cannot divide vector", 2)
- end
- function mag(a)
- return math.sqrt(magSquared(a))
- end
- function magSquared(a)
- return a.x * a.x + a.y * a.y + a.z * a.z
- end
- function reverse(a)
- return a * -1
- end
- function normalize(a)
- local m = mag(a)
- if m == 0 then
- error("cannot normalize a vector with length 0", 2)
- end
- return new(a.x / m, a.y / m, a.z / m)
- end
- function cross(a, b)
- return new(
- a.y * b.z - a.z * b.y,
- a.z * b.x - a.x * b.z,
- a.x * b.y - a.y - b.x
- )
- end
- --[[
- To be implemented
- function Vec4(v, a)
- return Vec4.new(v,x, v.y, v.z, a)
- end]]
- local Prototype = {["type"] = "vec3"}
- local mt = {}
- mt.__index = Prototype
- function mt.__tostring(a)
- return a.x .. ", " .. a.y .. ", " .. a.z
- end
- function new(x, y, z)
- t = {["x"] = x, ["y"] = y, ["z"] = z}
- setmetatable(t, mt)
- return t
- end
- Prototype.add = add
- Prototype.div = div
- Prototype.mult = mult
- Prototype.sub = sub
- Prototype.mag = mag
- Prototype.magSquared = magSquared
- Prototype.reverse = reverse
- Prototype.normalize = normalize
- Prototype.cross = cross
- --Prototype.Vec4 = Vec4
- mt.__add = add
- mt.__mul = mult
- mt.__div = div
- mt.__sub = sub
- mt.__unm = reverse
- mt.__pow = cross]=])
- f.close()
Advertisement
Add Comment
Please, Sign In to add comment