width based on difference between two time values - lua

When a function is run, it saves two values:
os.clock() + int
os.clock()
so example values:
2795.100
2790.100
(5 second difference)
so the moment this function is called, I need to draw a bar, and at this moment it would be drawn at 0% width, when os.clock() returns 2792.550 it should be at 50% width, os.clock() returns 2795.100 it should be at 100% width.
I am trying to find the math logic to:
based on the difference between these two values, decide how many pixels one % would be, so I can use os.clock() to calculate the bar length
I have been struggling with this but I have no code of use to show. Since in example values there's a 5 second difference between the two values, and I want to draw a bar that is at 0% width that grows to 100% over 5 seconds.

That's just basic math.
local interval_start = 2790.100
local interval_end = 2795.100
local current_value = 2792
local bar_max_width = 350
-- how far current value is from start / entire length of interval of allowed values
local fill_percentage = ((current_value - interval_start) / (interval_end - interval_start))
local fill_width = bar_max_width * fill_percentage
print(fill_percentage, fill_width)
Feed one of those values to whatever drawing facility you use.

Related

Parallel loading images in Julia

I am trying to create mosaic images of simulation data where each tile is in .jpg format and has a fixed number of pixels. I combine hundreds of these into a larger image for easier parameter analysis. So far I was able to parallelize getting the tiles to create a larger image with the following code:
using Distributed
addprocs(8)
# add #everywhere macro before every function and variable so it magically works
#everywhere big_image = zeros(RGB, 300, 1000); #each tile has 100x100 pixels for simplicity
function createBigFrame(big_image)
#sync for row = 1:10 # #sync waits until all the images are fetched and then continue with plotting
for col = 1:3
i = #range for x
j = #range for y (or vice versa)
image_path = #get the path
Threads.#spawn big_image[i, j] = load(image_path);
end
 end
plot(...) # add axes and ticks to the image
savefig(...) # save the figure on the disk
end
Although I used this on small data, it gave me a 20% increase in performance. Higher performance will be seen with larger data since there are more tile images to parallel. However, it has been told me that this is not the proper way of parallelizing things. I am very curious to know the right way to load images in parallel (not concurrently since the load() function is not thread-safe) and improve the code and performance further. I am very grateful for your help.
EDIT: The following code is supposed to be a minimal working example, but since you don't have the files to load(), the situation is a little different.
using Distributed
addprocs(4) #do not re-run
#everywhere using Colors, Images
#everywhere img = Images.zeros(RGB, 300, 1000);
function createBigFrame(image)
#sync for row = 1:10
for col = 1:3
j = 100*(col-1)+1:100*col;
i = 100*(row-1)+1:100*row;
Threads.#spawn image[j, i] .= RGB(rand(3)...)
end
 end
return image
end
createBigFrame(img)
I managed to run my code as the second suggestion of the selected answer in here. However, I'm not sure I fully understand how the code works under the hood.
I'll put this example picture here so we are on the same page:
There are 3 rows and 10 columns of tiles in this image.
Now, in my first attempt, I used the following way to get the images to row 1 in parallel.
arr = SharedArray{Float32,3}(ones(3, 512*3, 512*10))
#sync #distributed for row = 1:3
for col = 1:10
row_index = #index range for the height of the image
col_index = #index range for the width of the image
arr[:, row_index, col_index] = channelview(testimage("lake_color"))
end
end
If my understanding is correct, #sync is used to wait for each row iteration to complete while workers fetch images in that row in parallel. I thought if this is the case, there should be a waste of time between rows waiting for the previous row to complete.
So I flattened the 2D fetching loop to 1D in order to have more space to move and fetch the images freely:
#sync #distributed for s = 1:30
row_index = #index range for the height of the image
col_index = #index range for the width of the image
arr[:, row_index, col_index] = channelview(testimage("lake_color"))
end
But I was wrong? The second code came out 25% slower than the first one (150 seconds to 190 seconds), so I wonder what is going on here?

Trig, placing items and updating their position

I have a problem I just cannot solve, and after a week it's really winding me up.
Background.
I'm placing items onto a circle using basic trig. The number of items can change dynamically, and they are spaced around the circle equally.
The items rotate around the circle, and the speed of rotation changes to be in sync with a BPM (Beats Per Minute) clock. This clock can change at any time.
The problem I'm having is that the items seem to be placed randomly on the circle, not equally spaced in order (see image 1). They'll appear out of order even though it's a basic for loop that places them. I think they may in face be in order, but the rotation values may be off making them look like they are in an odd order.
The second issue is that when the number of items reduces, the speed of rotation increases (it shouldn't) and if the number increases, the speed slows.
So I expect an issue with my trig function. I'm showing the complete code here but can simplify if it'll help.
What have I tried?
I've tried simplified versions without the graphical output, and the numbers all seem to make perfect sense. The radians between items is correct, the placement looks correct. It all looks correct, but it isn't.
The code.
--the variables
orbitalCircle.xPos = x or 0
orbitalCircle.yPos = y or 0
orbitalCircle.circleDiameter = diameter or 10
orbitalCircle.numberOfNotes = number_of_notes
orbitalCircle.spaceBetweenNotes = (360 / number_of_notes)
orbitalCircle.beatsPerSecond = (beats_per_minute / 60)
orbitalCircle.currentRotation = 0
orbitalCircle.framesPerSecond = frames_per_second or 15
orbitalCircle.framesPerFullRotation = (orbitalCircle.numberOfNotes/orbitalCircle.beatsPerSecond)+orbitalCircle.framesPerSecond
orbitalCircle.degreesPerFrame = 360 / orbitalCircle.framesPerFullRotation
orbitalCircle.newRotationValue = orbitalCircle.currentRotation + orbitalCircle.degreesPerFrame
orbitalCircle.sequenceData = sequence_data
--the function that updates the sequence data and therefore the number of items on the circle
function orbitalCircle.updateNotes(sq)
orbitalCircle.sequenceData = sq
orbitalCircle.numberOfNotes = (#sq)
orbitalCircle.spaceBetweenNotes = (360 / orbitalCircle.numberOfNotes)
end
--the function that calculates the new rotation value of the item to be placed on the circle
function orbitalCircle.tick()
orbitalCircle.spaceBetweenNotes = (360 / number_of_notes)
orbitalCircle.framesPerFullRotation = (orbitalCircle.numberOfNotes/orbitalCircle.beatsPerSecond)*orbitalCircle.framesPerSecond
orbitalCircle.degreesPerFrame = (360 / orbitalCircle.framesPerFullRotation)
orbitalCircle.newRotationValue = (orbitalCircle.currentRotation + orbitalCircle.degreesPerFrame)
if orbitalCircle.newRotationValue > 360 then
orbitalCircle.currentRotation = 0
else
orbitalCircle.currentRotation = orbitalCircle.newRotationValue
end
end
--finally the function that places the items onto the circle
function orbitalCircle.redraw()
screen.circle(orbitalCircle.xPos, orbitalCircle.yPos, orbitalCircle.circleDiameter)
screen.stroke()
for i=1, (#orbitalCircle.sequenceData) do
if orbitalCircle.sequenceData[i] > 0 then
screen.circle(
math.cos(math.rad(orbitalCircle.newRotationValue)+(orbitalCircle.spaceBetweenNotes*i))*orbitalCircle.circleDiameter + orbitalCircle.xPos,
math.sin(math.rad(orbitalCircle.newRotationValue)+(orbitalCircle.spaceBetweenNotes*i))*orbitalCircle.circleDiameter + orbitalCircle.yPos,
map(orbitalCircle.sequenceData[i], 5, 128, 0.5, 4)
)
end
end
end
end
I'd expect that the items would be:
equally spaced no matter the amount (that works)
in order (they appear not to be)
the speed of rotation should remain fixed unless the BPM changes (this doesn't happen)
I'm lost!
Let us take a closer look at the drawing.
screen.circle(
math.cos(math.rad(orbitalCircle.newRotationValue)+(orbitalCircle.spaceBetweenNotes*i))*orbitalCircle.circleDiameter + orbitalCircle.xPos,
math.sin(math.rad(orbitalCircle.newRotationValue)+(orbitalCircle.spaceBetweenNotes*i))*orbitalCircle.circleDiameter + orbitalCircle.yPos,
map(orbitalCircle.sequenceData[i], 5, 128, 0.5, 4)
)
What is the angle that is being drawn here? It is the argument to math.cos and math.sin (I will ignore the scaling and the translation that is applied afterwards):
math.rad(orbitalCircle.newRotationValue)+(orbitalCircle.spaceBetweenNotes*i)
So... it is the neRotationValue converted to radians and added to that the space between notes. This one is defined as 360 / number_of_notes, so it is in degrees. Adding a radians and degrees most likely does not produce the expected result.
So, what exactly do you mean with the following?
I've tried simplified versions without the graphical output, and the numbers all seem to make perfect sense.

Having issues getting a percentage of a number in iOS 7.1 applicaion xcode 5.1

In my iOS 7.1 application that I'm trying to develop, I need to figure out percentages of a specific number which is entered in a UITextField. It would appear when executing the code I get the wrong percentage of that number entered.
I've tried two different ways to get the require percentage answer I'm looking for, however it keeps giving the wrong answer.
Below here is the two methods that I've tried.
For example I want to get 72% of 250. If you were to do this on a calculator or better yet a excel spreadsheet I get the right answer 250 x 1 - 72% = 70. This is the correct answer I want
Method1 (.m file) Not working
Values that are set the the specific .text parameters:
Entered in the UITextField _linuxOracleOnDiskw_oRTC.text = 250
Value set to UITextField _formulaNumber.text = 1
Percentage Value set to _linuxOracle_Percent.text = 0.72
_linuxOracleOnDiskwithRTC.text = [NSString stringWithFormat:#"%.2f", ([_linuxOracleOnDiskw_oRTC.text doubleValue])*([_formulaNumber.text doubleValue])-([_linuxOracle_Percent.text doubleValue])];
When executed I the answer or vale that gets entered in the UITextField _linuxOracleOnDiskwithRTC.text is 249.28. This is wrong should be 70
Second method tried is as follows:
float linuxOracleOnDiskw_oRTC = [_linuxOracleOnDiskw_oRTC.text floatValue];
_linuxOracleOnDiskwithRTC.text = [NSString stringWithFormat:#"%.2f", (linuxOracleOnDiskw_oRTC * 1 - 72/100.0f )];
If someone can tell me what I maybe doing wrong and point me in the right direction with calculating percentages of a specific number entered in a UITextField I would be extremely GREATFUL.
Don't omit your brackets when performing calculations with code. For "250 x 1 - 72%" to get 70, you need to do this:
250 x (1 - 0.72) = 250 x 0.28 = 70
Formulas in () will be calculated first, followed by multiplication and division (whichever first), then followed by addition and subtraction (whichever first). So, insert your brackets appropriately.
Your formula to calculate the percentage is incorrect. One correct way to calculate percentages is
250 / 100 x 72
This gives you 72% of 250. The result of that isn't 70, btw, but 180. If you want 70, then you don't want 72% but 28% (or 100% - 72%):
250 / 100 x (100 - 72)

How to move image with low values?

The problem is simple: I want to move (and later, be able to rotate) an image. For example, every time i press the right arrow on my keyboard, i want the image to move 0.12 pixels to the right, and every time i press the left arrow key, i want the image to move 0.12 pixels to the left.
Now, I have multiple solutions for this:
1) simply add the incremental value, i.e.:
image.x += 0.12;
this is of course assuming that we're going to the right.
2) i multiplicate the value of a single increment by the times i already went into this particular direction + 1, like this:
var result:Number = 0.12 * (numberOfTimesWentRight+1);
image.x = result;
Both of these approaches work but produce similiar, yet subtly different, results. If we add some kind of button component that simply resets the x and y coordinates of the image, you will see that with the first approach the numbers don't add up correctly.
it goes from .12, .24, .359999, .475 etc.
But with the second approach it works well. (It's pretty obvious as to why though, it seems like += operations with Numbers are not really precise).
Why not use the second approach then? Well, i want to rotate the image as well. This will work for the first attempt, but after that the image will jump around. Why? In the second approach we never took the original position of the image in account. So if the origin-point shifts a bit down or up because you rotated your image, and THEN you try to move the image again: it will move to the same position as if you hadn't rotated before.
Alright, to make this short:
How can i reliably move, scale and rotate images for 1/10 of a pixel?
Short answer: I don't know! You're fighting with floating point math!
Luckily, I have a workaround, if you don't mind.
You store the location (x and y) of the image in a separate variable... at a larger scale. Such as 100x. So 123.45 becomes 12345, and you then divide by 100 to set the attribute that flash uses to display.
Yes, there are limits to number sizes too, but if you're willing to accept some error rate, and the fact that you'll be limited to, I dunno, a million pixels in each direction, you can fit it in a regular int. The only rounding error you will encounter will be a single rounding error when you divide by 100 (or the factor you used). So instead of the compound rounding error which you described (0.12 * 4 = 0.475), you should see things like 0.47999999. Which doesn't matter because it's, well, so small.
To expand on #Pimgd answer a bit, you're probably hitting a floating point error (multiple +='s will exaggerate the error more than one *='s) - Numbers in Flash are 53-bit precision.
There's also another thing to keep in mind, which is probably playing a bigger role with such small movement values; Flash positions all objects using twips, which is roughly about 1/20th of a pixel, or 0.05, so all values are rounded to this. When you say image.x += 0.12, it's actually the equivalent of image.x += 0.10, hence which the different becomes apparent; you're losing 0.02 of a pixel with every move.
You should be able to get around it by moving to another scale, as #Pimgd says, or just storing your position separately - i.e. work from a property _x rather than image.x so you're not losing that precision everytime:
this._x += 0.12;
image.x = this._x;

Too much force in using function physics.addForce();

I want to add force to the grenade according to the touch positions of the user.
--this is the code
physics.addBody(grenade1,"dynamic",{density=1,friction=.9,bounce=0})
grenade1:applyForce(event.x,event.y,grenade1.x,grenade1.y)
Here more the x and y positions are the lower the force is. But the force here is too high that the grenade is up in the sky.
You must calibrate the force applied. Remember that F=ma so if x=250 then F=250, if the mass of the display object (set when added body, based on material density * object area) is 1 then acceleration a = 250, which is very large. So try:
local coef = 0.001
grenade1:applyForce(coef*event.x, coef*event.y, grenade1.x, grenade1.y)
and see what you get. If too small, increase coef until the response is what you are looking for. You may find that linear (i.e., constant coef) doesn't give you the effect you want, for example coef=0.01 might be fine for small y but for large y you might find that coef=0.001 works better. In this case you would have to make coef a function of event.y, for example
local coef = event.y < 100 and 0.001 or 0.01
You could also increase the mass of the display object, instead of using coeff.
Recall also that top-level corner is 0,0: force in top level corner will be 0,0. So if you want force to increase as you go up on the screen, you need to use display.contentHeight - event.x.

Resources