Wierd behavior with translate

Tried to make a small program drawing to an image with setContext. But when I use translate in draw() the first sprite I draw is misplaced. Maybe someone can explain why?


function setup()
    viewer.mode = FULLSCREEN
    buf = image(WIDTH,HEIGHT)
end

function draw()
    spriteMode(CENTER)
    translate(WIDTH/2,HEIGHT/2)
    tint(233, 226, 80)
    sprite(buf,0,0) — this is misplaced
    translate(0,60) — but translate is after??
    tint(131, 80, 233)
    sprite(buf,0,0)
end

function touched(touch)
    setContext(buf)
    ellipse(touch.x-WIDTH/2,touch.y-HEIGHT/2,50)
    setContext()
end

@tnlogy Translate is additive. The second translate is added to the first translate. What are you trying to do anyways.

Yes, that it is additive is expected, but not that the first sprite is moved 60 from center and the second 120 from center. Which I haven’t figured out why? This is just a small example to exemplify the bug. If I remove the statement translate(0,60) the first sprite is centered correctly.

Seems like it’s the draw in setContext(buf) that is misplaced. Tried with translate(0,-60) in touched() and then it works. Tried with resetMatrix() or with pushMatrix and pop, but that doesnt work, so something is strange?

@tnlogy Are both circles supposed to be directly under your finger as you move it. Or just one of them. I guess I’m just not understanding what you’re trying to do and what you’re say isn’t working.

PS. Playing with you code again. If I move my finger horizontally across the screen, one circle is above where my finger is and the second one is above that circle. Are you asking why the first circle isn’t under your finger and the second circle above your finger.

@tnology - not sure what you are trying to achieve, tried to add something to resolve this. Try running with and without the second translate.


viewer.mode = FULLSCREEN
function setup()
    buf = image(WIDTH,HEIGHT)
    setContext(buf)
        rectMode(CENTER)
        stroke(231, 236, 67)
        noFill()
        strokeWidth(4)
        rect(1,1,WIDTH,HEIGHT)
    setContext()
end

function draw()
    spriteMode(CENTER)
    translate(WIDTH/2,HEIGHT/2)
    tint(233, 226, 80)
    sprite(buf,0,0) -- this is misplaced
    translate(0,60) -- try with and without this translate
    tint(131, 80, 233)
    sprite(buf,0,0)
end

function touched(touch)
    setContext(buf)
        ellipseMode(CENTER)
        ellipse(touch.x-WIDTH/2,touch.y-HEIGHT/2,50)
    setContext()
end

Note: with second transpose present both circles are above the touch.

Interesting to know. For me, none of the circles are where my finger is, so maybe it’s a bug in Codea related to running it on an iPhone8?

Thanks for debugging!

@tnlogy If you want the circle to be under your finger, try this. This works just fine on my iPhone 8.

viewer.mode = FULLSCREEN

function setup()
    buf = image(WIDTH,HEIGHT)
    fill(255)
end

function draw()
    sprite(buf,WIDTH/2,HEIGHT/2)
end

function touched(touch)
    setContext(buf)
    ellipse(touch.x,touch.y,50)
    setContext()
end

Yes, but if you want to draw something else using translate, Codea bugs out with positioning.

For example this in your code


function draw()
    sprite(buf,WIDTH/2,HEIGHT/2)
    translate(0,60)
    rect(0,0,50,50)
end

@tnlogy OK, the translate after the sprite is shifting the sprite but shouldn’t. Is that what you’re saying.

If so, you need to undo all the translates that have been done. So in this case, you do translate(0,-60) when you’re done. You do that for every translate to nullify each translate before doing another translate unless you want them to add…

No, the bug is that translate() in draw() makes the ellipse() inside setContext(buf) being misplaced. This happens even when using pushMatrix and popMatrix in draw()

@tnlogy Did you read my update to the above answer in the above post, or did I post it too late.

Here’s an example with multiple translates.

viewer.mode = FULLSCREEN

function setup()
    buf = image(WIDTH,HEIGHT)
end

function draw()
    sprite(buf,WIDTH/2,HEIGHT/2)
    
    translate(WIDTH/2,HEIGHT/2)
    fill(255,0,0)
    rect(0,0,50,50)
    translate(-WIDTH/2,-HEIGHT/2)
    
    translate(100,100)
    fill(0,255,0)
    rect(0,0,50,50)
    translate(-100,-100)
end

function touched(touch)
    setContext(buf)
    fill(255)
    ellipse(touch.x,touch.y,50)
    setContext()
end

Yes, thats essentially what popMatrix should do, remove the translations, but it doesnt work. And something drawn in setContext shouldnt be affected by translations in draw() or that is what I would think is the correct behaviour.

Thanks for the help and chat. I will report this as a bug in the runtime.

@tnlogy I don’t think it’s a bug. Sometimes if you have a lot of translates, you don’t want them totally zeroed out. You might want some translates offset from previous translates so you can subtract from any previous translates.

All,

This isn’t because you are making a sprite of screen size is it? That was my thought behind showing the screen rectangle?

@Bri_G No, it was the translate. It took me awhile to figure out what the issue was.

that last script works fine on my iPad and my iPhone.

Thanks for making me understand. I think my original misunderstanding was that my touch function was incorrect by using touch.x - WIDTH/2 instead of touch.x. But since it worked (due to the fact that the translate in draw() fixed my bug in the touched-function) I got really confused. With daves correct code it works fine using push and popmatrix to make sure that setContext draws correctly.

A normal day in debugging code. :slight_smile: