This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
digpoe's profile picture

Sine-wave problems

Started by digpoe, 24 April 2013 - 08:26 AM
digpoe #1
Posted 24 April 2013 - 10:26 AM
I'm currently having problems with my sine wave code that I made, in the sense that it's drawing in the wrong place.

I was thinking this piece of code would draw a nice sine wave onto the monitor (max size) above the computer, but the X positioning is way off, like it's five characters ahead. No ideas as to why this is actually happening, but I think my math MIGHT be wrong somewhere.

Here's my code:


local mon = peripheral.wrap("top")
term.redirect(mon)
local sizex, sizey = term.getSize()
sleep(3)
for i = 1, sizex do
  term.setCursorPos(i, math.floor((100*math.sin(i))+0.5))
  term.write("@")
  sleep(1)
end
SadKingBilly #2
Posted 24 April 2013 - 10:40 AM
You mean it starts printing five spaces from the left edge of the monitor? Or do you just mean that the wave itself doesn't look the way you want it to? Because as far as I can tell, there is no reason for that code to start printing five pixels from the left.
electrodude512 #3
Posted 24 April 2013 - 10:41 AM
You did (100*math.sin(i))+0.5 instead of 100*(math.sin(i)+0.5)

Try this:


local mon = peripheral.wrap("top")
term.redirect(mon)
local sizex, sizey = term.getSize()
sleep(3)
for i = 1, sizex do
  term.setCursorPos(i, math.floor(100*(math.sin(i)+0.5)))
  term.write("@")
  sleep(1)
end
digpoe #4
Posted 24 April 2013 - 10:42 AM
You mean it starts printing five spaces from the left edge of the monitor? Or do you just mean that the wave itself doesn't look the way you want it to? Because as far as I can tell, there is no reason for that code to start printing five pixels from the left.

It doesn't look like it should to me. It looks something like this:

  @
						   @
For the first two characters.

EDIT: Okay, formatting didn't appear. Lets try CODE BBcode?
digpoe #5
Posted 24 April 2013 - 10:44 AM
You did (100*math.sin(i))+0.5 instead of 100*(math.sin(i)+0.5)

Try this:


local mon = peripheral.wrap("top")
term.redirect(mon)
local sizex, sizey = term.getSize()
sleep(3)
for i = 1, sizex do
  term.setCursorPos(i, math.floor(100*(math.sin(i)+0.5)))
  term.write("@")
  sleep(1)
end

No, the +0.5 is for the math.floor() function to round up and down properly…

Example:

math.floor(0.1) = 0
math.floor(0.5) = 0

math.floor(0.1 + 0.5) = 0
math.floor(0.5 + 0.5) = 1
AfterLifeLochie #6
Posted 24 April 2013 - 11:00 AM
(Whoa I'm posting in AaP)

This code works fine in that the logic is correct – just the things aren't in the right place.

We know from sinusoidal functions that any function, f(x) = a sin(p * t) + s, where a is the amplitude, t is any given angle and s is a translation factor from the x-axis. P also represents the period in which the sine-graph completes a cycle. To demonstrate this works without any additional a, p or s values:


local sx, sy = term.getSize()

for i = 1, sx do
  local h = math.sin(i) + math.floor(sy/2)
  term.setCursorPos(i, h)
  term.write("#")
end
local doNothing = {os.pullEvent()}
… and running this, you'll see a sine wave in the middle of the screen. Changing the multiplication factor in front of math.sin(i) is going to affect the amplitude of the graph, but as your amplitude grows, you will lose points along the way. To fix this, you also need to change the period of the function (the p factor) to use a value such as 1 / 4 (which is really i / 4)!

Also, remember (iirc) Lua uses Radians for angular measurements – so be careful not to be caught up on that trick. Good luck!
digpoe #7
Posted 24 April 2013 - 11:07 AM
(Whoa I'm posting in AaP)

This code works fine in that the logic is correct – just the things aren't in the right place.

We know from sinusoidal functions that any function, f(x) = a sin(p * t) + s, where a is the amplitude, t is any given angle and s is a translation factor from the x-axis. P also represents the period in which the sine-graph completes a cycle. To demonstrate this works without any additional a, p or s values:


local sx, sy = term.getSize()

for i = 1, sx do
  local h = math.sin(i) + math.floor(sy/2)
  term.setCursorPos(i, h)
  term.write("#")
end
local doNothing = {os.pullEvent()}
… and running this, you'll see a sine wave in the middle of the screen. Changing the multiplication factor in front of math.sin(i) is going to affect the amplitude of the graph, but as your amplitude grows, you will lose points along the way. To fix this, you also need to change the period of the function (the p factor) to use a value such as 1 / 4 (which is really i / 4)!

Also, remember (iirc) Lua uses Radians for angular measurements – so be careful not to be caught up on that trick. Good luck!

Thanks, I was sure the math was wrong somewhere. It might've also been the fact that my friend told me how to do a Sine-wave in Scratch, which has the center of it's 'screen' as 0, 0. Much like a graph.
AfterLifeLochie #8
Posted 24 April 2013 - 11:12 AM
Thanks, I was sure the math was wrong somewhere. It might've also been the fact that my friend told me how to do a Sine-wave in Scratch, which has the center of it's 'screen' as 0, 0. Much like a graph.
No problems – you do need to move the whole graph "down" (which is actually up, if you think about it) by half the screen's height. term.setCursorPos() also doesn't care if you give it floating-point numbers, it will round them (iirc, down) to the nearest whole "pixel".

By the by, the same mathematical rules apply for cosine and tangent graphs, if that's what you're going to play with next. ;)/>
electrodude512 #9
Posted 24 April 2013 - 11:52 AM
Oh, right, if the +0.5 was to make the output always positive it would have been +1…