How to break a long line in Lua - lua

Util = {
scale = function (x1, x2, x3, y1, y3) return (y1) + ( (y2) - (y1)) * \
( (x2) - (x1)) / ( (x3) - (x1)) end
}
print(Util.scale(1, 2, 3, 1, 3))
What is the proper syntax for breaking a long line in Lua?

In your particular case, the convention would be ...
Util = {
scale = function (x1, x2, x3, y1, y3)
return (y1) + ( (y2) - (y1)) * ( (x2) - (x1)) / ( (x3) - (x1))
end
}
Where the break is on statements
Further breaking could be done if the multiplication needs to be split with
Util = {
scale = function (x1, x2, x3, y1, y3)
return (y1) + ( (y2) - (y1)) *
( (x2) - (x1)) / ( (x3) - (x1))
end
}
With the multiplication token used to split the line. By leaving a token at the end of the line, the parser requires more input to complete the expression, so looks onto the next line.
Lua is generally blind to line characters, they are just white-space. However, there are cases where there can be differences, and I would limit line breaks to places where there is an obvious need for extra data.
a = f
(g).x(a)
Is a specific case where it could be treated as a = f(g).x(a) or a = f and (g).x(a)
By breaking after a token which requires continuation, you ensure you are working with the parser.

Related

How can I set transition.to to continue in the same direction with the same velocity once it has arrived at the set point?

Hi I am new to coding and I am using Lua and solar2d, trying to transition object1 via another object2's co-ordinates and for object1 to continue along the same path with the same velocity if it doesn't hit object2.
I can easily transition to the obeject but I don't know how to then go beyond that.
transition.to( object1, { x=object2.x, y=object2.y, time=3000, })
I feel I will have to add an oncomplete but not sure what.
any help would be greatly appreciated.
You have to calculate the equation of the line (y = m * x + b) that you are traveling.
Formulas:
m = (y2 - y1) / (x2 - x1)
b = y1 - m * x1
So in your case:
m = (object2.y - object1.y) / (object2.x - object1.x)
b = object1.y - m * object1.x
Now you have the equation of the path (line) to keep if object1 doesn't hit object2.
When the transition ends, you want to check if the object2 is still there (object1 hit it) or not (object1 keeps moving), so you need to include an onComplete listener to check for that.
As for the speed, you have to decide if you want a constant speed and then you have to calculate the time for each transition or if you are using always 3 seconds no matter if the object2 is close or far away from the object1. I guess you probably want the first option, so it doesn't go pretty slow if objects are close and too fast if the object are far away. In that case you have to set a constant speed s, that you want.
Formulas:
Speed = Distance / Time
Time = Distance / Speed
Distance between 2 points:
d = squareRoot( (x2 - x1)^2 + (y2 - y1)^2 )
In summary, it would be something like that:
s = 10 --Constant speed
m = (object2.y - object1.y) / (object2.x - object1.x)
b = object1.y - m * object1.x
direction = 1 --assume it's traveling to the right
if(object2.x < object1.x)then
direction = -1 --it's traveling to the left
end
local function checkCollision( obj )
if(obj.x == object2.x and obj.y == object2.y)then
-- Object1 hit Object2
else
-- Object2 is not here anymore, continue until it goes offscreen
-- following the line equation
x3 = -10 -- if it's traveling to the left
if(direction == 1)then
--it's traveling to the right
x3 = display.contentWidth + 10
end
y3 = m * x3 + b
d2 = math.sqrt( (x3 - obj.x)^2 + (y3 - obj.y)^2 )
t2 = d2 / s
transition.to( obj, {x=x3, y=y3, time=t2} )
end
end
d1 = math.sqrt( (object2.x - object1.x)^2 + (object2.y - object1.y)^2 )
t1 = d1 / s
transition.to( object1, { x=object2.x, y=object2.y, time=t1, onComplete=checkCollision} )
You should try different values for the speed s until you get the desired movement.

Trying to emulate Bressenham's Line Algorithm in Lua but it returns an error(CC: Tweaked)

I am trying to make a module for CC: Tweaked that as one of its features uses Bressenham's Line Algorithm to draw a line between 2 points on a monitor. However when I run my program I get this error:
pixels.lua:24: attempt to index local 'y1' (a number value)
Please note that I got this code from a youtube video and it is possible that I wrote something wrong.
Here is my code:
local pixels = {}
function pixels.drawPixel(x, y, monitor, color)
monitor.setCursorPos(x, y)
monitor.setBackgroundColor(color)
monitor.write(" ")
end
function pixels.fillScreen(color)
x, y = monitor.getSize()
for j = 1,y,1
do
for i = 1,x,1
do
pixels.drawPixel(i,j,monitor,color)
end
end
end
function pixels.drawLine(x1, y1, x2, y2, monitor, color)
error = 0
slope = y2 - y1 / x2 - x1
pixels.drawPixel(x1, y1. monitor, color)
for x = x1,x2,1
do
error = error + slope
if error >= 0.5
then
y = y1 + 1
error = error - 1
end
pixels.drawPixel(x,y,monitor,color)
end
end
return pixels
Line 24:
pixels.drawPixel(x1, y1. monitor, color)
As stated in the comments above, y1 has a period instead of a comma after it, telling Lua to look for a value from y1.monitor when y1 is not a table. Thus, "Attempted to index a number".
(Also, you do not have to declare your incrementor number with your for loops if the number is 1)

How does Roblox's math.noise() deal with negative inputs?

While messing around with noise outside of Roblox, I realized Perlin/Simplex Noise does not like negative inputs. Remembering Roblox has a noise function, I tried there, and found out negative numbers do work nicely for Roblox's math.noise(). Does anybody know how they made this work, or how to get negative numbers to work for Perlin/Simplex noise in general?
The Simplex Noise I am using (copied from here but changed to have the bitwise and operation):
local function bit_and(a, b) --bitwise and operation
local p, c = 1, 0
while a > 0 and b > 0 do
local ra, rb = a%2, b%2
if (ra + rb) > 1 then
c = c + p
end
a = (a - ra) / 2
b = (b - rb) / 2
p = p * 2
end
return c
end
-- 2D simplex noise
local grad3 = {
{1,1,0},{-1,1,0},{1,-1,0},{-1,-1,0},
{1,0,1},{-1,0,1},{1,0,-1},{-1,0,-1},
{0,1,1},{0,-1,1},{0,1,-1},{0,-1,-1}
}
local p = {151,160,137,91,90,15,
131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180}
local perm = {}
for i=0,511 do
perm[i+1] = p[bit_and(i, 255) + 1]
end
local function dot(g, ...)
local v = {...}
local sum = 0
for i=1,#v do
sum = sum + v[i] * g[i]
end
return sum
end
local noise = {}
function noise.produce(xin, yin)
local n0, n1, n2 -- Noise contributions from the three corners
-- Skew the input space to determine which simplex cell we're in
local F2 = 0.5*(math.sqrt(3.0)-1.0)
local s = (xin+yin)*F2; -- Hairy factor for 2D
local i = math.floor(xin+s)
local j = math.floor(yin+s)
local G2 = (3.0-math.sqrt(3.0))/6.0
local t = (i+j)*G2
local X0 = i-t -- Unskew the cell origin back to (x,y) space
local Y0 = j-t
local x0 = xin-X0 -- The x,y distances from the cell origin
local y0 = yin-Y0
-- For the 2D case, the simplex shape is an equilateral triangle.
-- Determine which simplex we are in.
local i1, j1 -- Offsets for second (middle) corner of simplex in (i,j) coords
if x0 > y0 then
i1 = 1
j1 = 0 -- lower triangle, XY order: (0,0)->(1,0)->(1,1)
else
i1 = 0
j1 = 1
end-- upper triangle, YX order: (0,0)->(0,1)->(1,1)
-- A step of (1,0) in (i,j) means a step of (1-c,-c) in (x,y), and
-- a step of (0,1) in (i,j) means a step of (-c,1-c) in (x,y), where
-- c = (3-sqrt(3))/6
local x1 = x0 - i1 + G2 -- Offsets for middle corner in (x,y) unskewed coords
local y1 = y0 - j1 + G2
local x2 = x0 - 1 + 2 * G2 -- Offsets for last corner in (x,y) unskewed coords
local y2 = y0 - 1 + 2 * G2
-- Work out the hashed gradient indices of the three simplex corners
local ii = bit_and(i, 255)
local jj = bit_and(j, 255)
local gi0 = perm[ii + perm[jj+1]+1] % 12
local gi1 = perm[ii + i1 + perm[jj + j1+1]+1] % 12
local gi2 = perm[ii + 1 + perm[jj + 1+1]+1] % 12
-- Calculate the contribution from the three corners
local t0 = 0.5 - x0 * x0 - y0 * y0
if t0 < 0 then
n0 = 0.0
else
t0 = t0 * t0
n0 = t0 * t0 * dot(grad3[gi0+1], x0, y0) -- (x,y) of grad3 used for 2D gradient
end
local t1 = 0.5 - x1 * x1 - y1 * y1
if t1 < 0 then
n1 = 0.0
else
t1 = t1 * t1
n1 = t1 * t1 * dot(grad3[gi1+1], x1, y1)
end
local t2 = 0.5 - x2 * x2 - y2 * y2
if t2 < 0 then
n2 = 0.0
else
t2 = t2 * t2
n2 = t2 * t2 * dot(grad3[gi2+1], x2, y2)
end
-- Add contributions from each corner to get the final noise value.
-- The result is scaled to return values in the interval [-1,1].
return 70.0 * (n0 + n1 + n2)
end
return noise
The Lua programming language version that Roblox uses, LuaU (or Luau), is actually open-source since November of 2021. You can find it here. The math library can be found in this file called lmathlib.cpp and it contains the math.noise function along with internal functions to calculate it, perlin (main function), grad, lerp, and fade. It's a quite complicated thing I can't explain myself, but I have converted it into Lua here.

how to write private function in lua class

I'm trying to write a lua "class" with a private function like this:
local myTable = {}
function myTable.func()
private()
end
local function private()
print(":O")
end
return myTable
Let's say I'll require myTable and then run myTable.func() I'll get an error that says private is not defined.
I've found 2 ways to solve this:
move the function private in front of func
Forward declare local private before func and change the signature of private to function private.
But I'm a little confused about why they are working and which is the common way.
which is the common way
Both work and both are advisable. The second approach is needed in situations where you have two functions that call each other and both need to be local but not inside a table.
You could always use the second style and thus keep consistency, though it might not be as readable as you would need to go to a different place in code to see if your function is local.
However for readability and shorter code I would use the first approach so I don't need a separate "declaration" of my local functions.
im little confused about why they are working
The reason the original code does not work is because of local variable scope.
From lua reference manual:
Lua is a lexically scoped language. The scope of a local variable
begins at the first statement after its declaration and lasts until
the last non-void statement of the innermost block that includes the
declaration.
So in your original code the variable private is defined as the function only after the line where it is defined. And the code fails because you try to use it in code that is before that line.
The approaches work because both move the local variable scope to start above the code where you use the variable.
You may want to read about local variables and the scoping in the reference manual:
http://www.lua.org/manual/5.2/manual.html#3.3.7
http://www.lua.org/manual/5.2/manual.html#3.5
First of all: In your code snippet it's not clear to me where the "class" is, as myTable is just an object. If you put this in a module and require it, you just get an object.
You could do something like this:
local function MyTable() -- constructor
local function private()
print(":O")
end
return {
func = function()
private()
end
}
end
local m = MyTable()
m.func()
This may not be the usual way of doing OOP in Lua, but here private obviously is .. well .. private.
I created this samplecode:
local object = {}
do -- Creates Scope
-- Private Scope
local fire_rate = 5
-- Public Scope
function object:load()
end
function object:update()
end
function object:draw()
end
function object:setFireRate(rate)
fire_rate = rate
end
function object:getFireRate()
return fire_rate
end
end
return object
Hope this helps.
You'll basically need something like this:
local function Bezier(x1,y1,x2,y2,x3,y3)
--Private
local inf = 1/0
local x1 = x1
local y1 = y1
local x2 = x2
local y2 = y2
local x3 = x3
local y3 = y3
local maxY = y1 > y2 and (y1 > y3 and y1 or y3) or y2 > y3 and y2 or y3
local minY = y1 < y2 and (y1 < y3 and y1 or y3) or y2 < y3 and y2 or y3
local maxX = x1 > x2 and (x1 > x3 and x1 or x3) or x2 > x3 and x2 or x3
local minX = x1 < x2 and (x1 < x3 and x1 or x3) or x2 < x3 and x2 or x3
local xc = (x3 - 2*x2 + x1)
local xb = 2*(x2 - x1)
local yc = (y3 - 2*y2 + y1)
local yb = 2*(y2 - y1)
--Public
local self = {}
--Render
self.render = function(resolution)
local path = {}
local num = 1
for index=0, 1, 1/resolution do
path[num] = {(1-index)^2*x1+2*(1-index)*index*x2+index^2*x3, (1-index)^2*y1+2*(1-index)*index*y2+index^2*y3}
num = num + 1
end
return path
end
--Point
function self.point(index)
return {(1-index)^2*x1+2*(1-index)*index*x2+index^2*x3, (1-index)^2*y1+2*(1-index)*index*y2+index^2*y3}
end
--Get x of patricular y
function self.getX(y)
if y > maxY or y < minY then
return
end
local a = y1 - y
if a == 0 then
return
end
local b = yb
local c = yc
local discriminant = (b^2 - 4*a*c )
if discriminant < 0 then
return
else
local aByTwo = 2*a
if discriminant == 0 then
local index1 = -b/aByTwo
if 0 < index1 and index1 < 1 then
print("=====",y,1,maxY,minY)
return (1-index1)^2*x1+2*(1-index1)*index1*x2+index1^2*x3
end
else
local theSQRT = math.sqrt(discriminant)
local index1, index2 = (-b -theSQRT)/aByTwo, (-b +theSQRT)/aByTwo
if 0 < index1 and index1 < 1 then
if 0 < index2 and index2 < 1 then
print("=====",y,2,maxY,minY)
return (1-index1)^2*x1+2*(1-index1)*index1*x2+index1^2*x3, (1-index2)^2*x1+2*(1-index2)*index2*x2+index2^2*x3
else
print("=====",y,1,maxY,minY)
return (1-index1)^2*x1+2*(1-index1)*index1*x2+index1^2*x3
end
elseif 0 < index2 and index2 < 1 then
print("=====",y,1,maxY,minY)
return (1-index2)^2*x1+2*(1-index2)*index2*x2+index2^2*x3
end
end
end
end
--Get y of patricular x
function self.getY(x)
if x > maxX or x < minX then
return
end
if maxX == minX and x == minX then
return minY, maxY
end
local index1, index2, buffer1, buffer2
local a = (x1 - x)
if a == 0 then
return
end
local b = xb
local c = xc
local discriminant = b^2 - 4*a*c
if discriminant < 0 then
return
else
local aByTwo = 2*a
local theSQRT = math.sqrt(discriminant)
if discriminant == 0 then
local index1 = -b/aByTwo
return (1-index1)^2*y1+2*(1-index1)*index1*y2+index1^2*y3
else
local index1, index2 = (-b - theSQRT)/aByTwo, (-b + theSQRT)/aByTwo
return (1-index1)^2*y1+2*(1-index1)*index1*y2+index1^2*y3, (1-index2)^2*y1+2*(1-index2)*index2*y2+index2^2*y3
end
end
end
--Scanline render
function self.scanRender()
local path = {}
local counter = 1
local fX, sX
local a = (y3 - 2*y2 + y1)
local b = 2*(y2 - y1)
for i=minY, maxY do
fX, sX = self.getX(i,a,b)
if fX then
path[counter] = fX
path[counter+1] = i
counter = counter + 2
if sX then
path[counter] = sX
path[counter+1] = i
counter = counter + 2
end
end
end
return path
end
--More efficient
--Self
return self
end
By calling bezier, you get a Bezier object. This object will be able to access all the private attributes and the public interface that is in the self table.

(Lua) Doing mathematical operations with non-number values

I want to make some sort of a Vector3 library for Lua which could let you make simple 3D position operations with simple syntax. I'll mention that I'm using Luaj for running Lua code for Java manipulation.
Here's my beginning code:
Vector3 = {
new = function (x1, y1, z1)
return {x = x1, y = y1, z = z1}
end
}
Position1 = Vector3.new(1, 5, 8)
Position2 = Vector3.new(4, 7, 2)
And here's what I want to be able to happen:
Subtraction = Position1 - Position2
print(Subtraction.x, Subtraction.y, Subtraction.z) -- prints "-3, -2, 6"
Any idea on making EXACT code to work?
This is what metatables and metamethods are for. You should have a read in the documentation.
Basically, they let you redefine what operators (and some other things) do on your values. What you want right now is to define the __sub metamethod, which defines how to handle the - operator. I guess in the future you'll want to redefine the other metamethods as well.
First, define a subtraction function in your Vector3 "class" that takes two vectors:
function Vector3.subtract(u,v)
return Vector3.new(u.x - v.x, u.y - v.y, u.z - v.z)
end
Then create let Vector3 know the metatable it should give all vectors:
Vector3.mt = {__sub = Vector3.subtract}
And when you create a new vector:
new = function (x1, y1, z1)
local vec = {x = x1, y = y1, z = z1}
setmetatable(vec, Vector3.mt)
return vec
end
You could also make the metatable (mt) a local variable inside your new function - that would prevent external code from messing with the metatable (as it would be only accessible by your new function). However, having it inside Vector3 allows you to check against usages like v - "string":
function Vector3.subtract(u,v)
if getmetatable(u) ~= Vector3.mt or
getmetatable(v) ~= Vector3.mt then
error("Only vectors can be subtracted from vectors", 2)
end
return Vector3.new(u.x - v.x, u.y - v.y, u.z - v.z)
end
You could do something like this:
Vector3 = {}
mt = {}
function Vector3:new(_x, _y, _z)
return setmetatable({
x = _x or 0,
y = _y or 0,
z = _z or 0
}, mt)
end
mt.__sub = function(v1, v2) return Vector3:new(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z) end
mt.__tostring = function(v) return "Vector3=(" .. v.x .. "," .. v.y .. "," .. v.z .. ")" end
mt.__index = Vector3 -- redirect queries to the Vector3 table
-- test Vector3
Position1 = Vector3:new(1, 5, 8)
Position2 = Vector3:new(4, 7, 2)
Sub = Position1 - Position2
print(Sub)
which would print:
Vector3=(-3,-2,6)
More on Lua & OO, see: http://lua-users.org/wiki/ObjectOrientationTutorial

Resources