Hello @Simeon. I am working through some of the open issues on the Issue Tracker in connection with beta 1.5(12).
####Issue No. 217
I find that os.time() does change from one value to another as time passes, but about once every two minutes.
--
-- os.time
--
function setup()
timeCheck()
end
local trialCount = 0
function timeCheck()
local timeValue = os.time()
local dateString = os.date("%c", timeValue)
trialCount = trialCount + 1
print(trialCount..": "..dateString)
end
function draw() background(0) end
function touched(touch)
if touch.state == BEGAN then timeCheck() end
end
.@mpilgrem this is due to Codea using 32 bit floats for the Lua “number” type instead of the default 64 bit double-precision float (“double”). This is because there are performance benefits to using single-precision floats on the newer iPad ARM CPUs.
So what is happening is the value from os.time() is getting truncated, and small changes are lost.
.@Simeon, in the past you have explained (here) that Codea’s use of a version of Lua that uses singles rather than doubles for Lua’s number type is to accommodate the performance of first generation iPads. Do you see a time where you might have an ‘enhanced’ version of Codea that is not intended to work well on first generation iPads?
This is almost certainly not on any critical path for Codea version 1.5, but I see from the Lua reference that the meaning of the value returned by os.time([table]) (and understood by os.date()) is allowed to vary from system to system.
Perhaps the Codea ‘system’ could change (behind the scenes) the start of the ‘epoch’ (update: from the 1 January 1970 GMT used by iOS) so that the number of seconds since that start fell within the precision of a 32 bit float?
(Further update): A little knowledge is a dangerous thing, but I think it would involve something like this patch in loslib.c:
(1) deducting some offset value (say, CODEA_EPOCH_OFFSET) from these lines:
static int os_time (lua_State *L) {
time_t t;
if (lua_isnoneornil(L, 1)) /* called without args? */
t = time(NULL) - CODEA_EPOCH_OFFSET; /* get current time */
else {
...
t = mktime(&ts) - CODEA_EPOCH_OFFSET
}
...
(2) adding back the same offset value in this line:
What the code below allows you to explore is (1) the odd behaviour of line() when smooth is set and strokeWidth is less than 2.5; and (2) that the line width does not scale if noSmooth is set.
--
-- Scale-Stroke-Smooth Explorer
--
function setup()
red = color(255, 0, 0)
green = color(0, 255, 0)
parameter.number("scaleValue", 1, 20, 10)
parameter.number("strokeWidthValue", 1, 10, 5)
parameter.boolean("isSmooth", true)
rectMode(CENTER)
stroke(255)
end
function drawPattern()
fill(green)
strokeWidth(strokeWidthValue)
if isSmooth then
smooth()
else
noSmooth()
end
line(-20, 10, 20, 10)
rect(0, -20, 40, 20)
end
function draw()
background(0)
translate(WIDTH / 2, HEIGHT * 0.9)
noStroke()
fill(red) ellipse(0, 0, 5) -- Mark origin
drawPattern()
translate(0, - HEIGHT * 0.45)
noStroke()
fill(red) ellipse(0, 0, 5) -- Mark origin
scale(scaleValue) -- Scale up
drawPattern()
end
.@mpilgrem that’s a great demo — I’ve used it to improve the line shader with round end caps in the next build (though it’s probably a bit slower now).
The reason noSmooth() lines don’t scale in width is because they use the GL_LINE primitive. This primitive is not affected the same way by vertex transforms because it only has two vertices. We could change to drawing a rect (internally) for noSmooth() lines, this would allow all four vertices to scale but would be slower.
CODEA_EPOCH_OFFSET is an interesting idea. It would make os.time() a lot more useful, and we could disable it in case we do move to double precision numbers in the future.
.@tnlogy I can’t recreate this — is it causing the text input to become misaligned on your device?
.@Mark not for version 1.5, but I am keeping that one in mind.
Hello @Simeon. The following is an Editor bug, but the solution may lie with changing the color() function.
The argument pop-up ‘tips’ in the Editor suggest that when color() has a single argument, it is a ‘Gray Value’, and when color() has two arguments, the first is ‘Gray’ and the second ‘Alpha’.
However, color() only allows for color(red, green, blue, alpha) with red, green and blue assumed to be 0 if they are not supplied and alpha assumed to be 255 if it is not supplied.
Perhaps it would be better if color() behaved more like fill() does, in terms of its arguments? - although that would be a change in the Codea API.
myBody.linearDamping and myBody.angularDamping still return boolean values, in error, and are not documented in the in-app reference for ‘physics.body’.
--
-- Dampner
--
function setup()
physics.gravity(0, 0)
myBody = physics.body(CIRCLE, 30)
-- number, used to reduce the velocity of the body. The
-- default, 0, is no damping. Damping is usually less
-- than 1, but can be greater.
myBody.linearDamping = 0.5
-- number, used to reduce the angular velocity of the body.
-- The default, 0, is no damping. Damping is usually less
-- than 1, but can be greater.
myBody.angularDamping = 0.5
-- Codea bug:
print(myBody.linearDamping) -- Output: false
print(myBody.angularDamping) -- Output: false
myBody.linearVelocity = vec2(1, 2)
myBody.angularVelocity = 1
myBody.sleepingAllowed = false
fill(255)
fontSize(32)
title = "time: (v_x, v_y), w"
end
function draw()
background(0)
s = string.format("%.1f: (%.2f, %.2f), %.2f",
ElapsedTime, myBody.linearVelocity.x,
myBody.linearVelocity.y, myBody.angularVelocity)
text(title, WIDTH / 2, HEIGHT / 2 + 50)
text(s, WIDTH / 2, HEIGHT / 2)
end
.@tnlogy thanks, I was able to reproduce the issue. I can’t actually fix this bug without rewriting the editor (which is currently in the works — just probably not for 1.5). Is it a common occurrence for you?
Small bug with setContext. Don’t know if anyone else has seen it. In this example the image drawn into setContext it cut at 493x120 instead of 560x120 which is the image size. But it is rendered correct when created from the touch event.
function setup()
displayMode(FULLSCREEN)
createColorImage()
end
function draw()
background(40, 40, 50)
spriteMode(CENTER)
sprite(colorImage, WIDTH/2, HEIGHT/2)
end
function touched()
createColorImage()
end
function createColorImage()
colorImage = image(560,120)
setContext(colorImage)
background()
spriteMode(CORNER)
sprite("Documents:ColorPicker", 0,0, 560)
setContext()
end
.@mpilgrem thank you for the detailed corrections. I’ve used your descriptions for categories and mask for now, and sent them to @John so he can review them (he’s the physics guy).
.@tnlogy I am trying this with other images and can’t seem to reproduce. Perhaps you should try changing your createColorImage function to the following:
function createColorImage()
colorImage = image(560,120)
setContext(colorImage)
background(0,0,0,0) -- Use a transparent background
spriteMode(CORNER)
sprite("Documents:ColorPicker", 0,0, 560)
setContext()
end
Maybe the black background just makes it look as if your image is getting cut off?
Thanks @tnlogy — I’ll give it a try on iPad 2 and see how your code goes. I’ve added your example to my bug list, so I’ll check it out before the next build.