Post your best Lua script examples here

User avatar
By JohnPool
#86963 I am a newby in NodeMCU ESP8266 country, and I needed a couple of math functions in lua that are not available in the math library, so I decided to write them myself. They are based on an article that I found here (except the ln function). Maybe they are useful for others.

John Pool

Code: Select allPI = math.pi;
r360 = 2*PI; -- 2*PI radians equal 360 degrees
r180 = PI;
r90  = PI/2;

function sin(x) -- x in radians
  local sign = 1;
  if x < 0 then x = -x + r180 end
  x = x % r360; -- x < 360
  if x > r180 then x = r360 - x;  sign = -1 end
  if x > r90  then x = r180 - x end
  local x2 = x*x;
  return sign*x*(x2*(x2*(-x2+42)-840)+5040)/5040;
end

function cos(x) -- x in radians
  return sin(x+r90);
end

function tan(x) -- x in radians
  return sin(x)/cos(x);
end

function atan(x) -- result in radians
  local sqrt3 = 1.732051;
  local offset = 0;
  local sign = 1;
  if x <= 0 then x = -x; sign = -1 end
  if x > 2-sqrt3 then
    x = (x*sqrt3 - 1) / (sqrt3 + x);
    offset = PI/6;
  end
  local x2 = x*x; 
  return sign*(offset + x*(x2*(x2*(-15*x2+21)-35)+105)/105);
end

function asin(x)
  if x <= -1 or x >= 1  then error("*** Illegal argument for asin()") end
  return atan(x/(1-x*x)^(0.5));
end

function acos(x)
  if x <= -1 or x >= 1  then error("*** Illegal argument for acos()") end
  return atan((1-x*x)^(0.5)/x);
end

function toRad(x) -- degrees
  return x*PI/180; -- radians
end

function toDeg(x) -- radians
  return x*180/PI; -- degrees
end

function exp(x)
  return 2.7182818284^x;
end

function ln(x) -- natural logarithm; precision approximately 5 positions after decimal dot
  if x <= 0 then error("*** Illegal argument for ln()") end
  local ln2 = 0.6931471; -- ln(x*2^k)=ln(x)+k*ln(2)
  local sign = 1;
  local k = 0; -- invariant: x*2^k is constant
  if (x < 1) then x = 1/x; sign = -1 end
  while (x > 1) do x = x/2; k = k+1 end -- postcondition: 0.5 < x <= 1
  x = 1 - x; -- 0 <= x < 0.5 for fast convergence. First 6 series expansion terms:
  local sum = x*(x*(x*(x*(x*(10*x+12)+15)+20)+30)+60)/60; -- ln(1-x)=-(sum(x^n/n),n:0..inf,-1<=x<1.
  return sign * (k*ln2 - sum);
end

function truncate(x) -- integer part of x
  return x > 0 and math.floor(x) or math.ceil(x)
end

function round(x) -- x rounded to nearest integer
  return x >= 0 and math.ceil(x-0.5) or math.floor(x+0.5)
end