Computer Science Canada

screen zooming and centering at the same time.

Author:  chopperdudes [ Thu Jan 01, 2009 11:27 pm ]
Post subject:  screen zooming and centering at the same time.

i have this rather complicated idea for my final ISU that includes zooming and centering at the same time. for example, i want to zoom in on (100, 100) on the screen to 2x its size, but also centering that location at the same time so that when the image reaches 2x its size, it will also be at the center.

so a practical example would be, i got a character located at 100,100 on the screen, and the background behind that character, i want to zoom the whole view to 2x the magnification, but also centering the character so that by the time it's 2x the size, it will also be positioned in the center of the screen.

i know this will be pretty math intensive, as everything is relative.
what i have thought up of so far:
i need to var background := Pic.New (0, 0, maxx, maxy)
the magnification step will have to be in proportional to the distance from x1 to midx, (total mag/abs (midx-x1))??
the hard part is knowing where the x and y cordinates of the scaled background.


can anyone help me out here? thx alot. if i get this done it will be a huge visual to my project.

Author:  Tony [ Fri Jan 02, 2009 1:02 am ]
Post subject:  RE:screen zooming and centering at the same time.

can you do both effects separately? You might be over-complicating things by trying to get both to work at the same time.

Implement one.
Then the other.
Then see how you can use a single loop to drive both animations.

Author:  chopperdudes [ Fri Jan 02, 2009 1:47 am ]
Post subject:  Re: screen zooming and centering at the same time.

well here is what i have worked out with. it works, but VERY memory intensive and anything over the mag of 2x will more than likely produce an "illegal picID" error saying probable cause: picture not created successfully. (since the orignaly screen picture will have to be x times as large as the mag)




Turing:


View.Set ("graphics:600;600,position:center;center,offscreenonly")


proc zoom (x, y : int, mag : real)
    const midx := maxx div 2
    const midy := maxy div 2


    var bg := Pic.New (0, 0, maxx, maxy)
    var tempMag : real := 1
    var tempMagStep : real

    if midx not= x then
        tempMagStep := mag / abs (midx - x)
    else
        tempMagStep := 0
    end if

    if abs (midx - x) > abs (midy - y) then
        if x < midx then
            var j, yStep : real
            j := y
            if midx not= x then
                yStep := (midy - y) / (midx - x)
            else
                yStep := 0
            end if

            for i : x .. midx


                j += yStep




                var scaledBG := Pic.Scale (bg, round (Pic.Width (bg) * tempMag), round (Pic.Height (bg) * tempMag))
                Pic.Draw (scaledBG, round (- (x * tempMag - i)), round (- (y * tempMag - j)), picCopy)

                tempMag += tempMagStep
                Pic.Free (scaledBG)
                View.Update

                %delay (100)
            end for
        else
            var j, yStep : real
            j := y
            if x not= midx then
                yStep := (midy - y) / (x - midx)
            else
                yStep := 0
            end if

            for decreasing i : x .. midx


                j += yStep


                var scaledBG := Pic.Scale (bg, round (Pic.Width (bg) * tempMag), round (Pic.Height (bg) * tempMag))
                Pic.Draw (scaledBG, round (- (x * tempMag - i)), round (- (y * tempMag - j)), picCopy)

                tempMag += tempMagStep
                Pic.Free (scaledBG)
                View.Update

                %delay (100)
            end for
        end if



    else
        if y < midy then
            var j, xStep : real
            j := x
            if midy not= y then
                xStep := (midx - x) / (midy - y)
            else
                xStep := 0
            end if

            for i : y .. midy


                j += xStep




                var scaledBG := Pic.Scale (bg, round (Pic.Width (bg) * tempMag), round (Pic.Height (bg) * tempMag))
                Pic.Draw (scaledBG, round (- (x * tempMag - j)), round (- (y * tempMag - i)), picCopy)

                tempMag += tempMagStep
                Pic.Free (scaledBG)
                View.Update

                %delay (100)
            end for
        else
            var j, xStep : real
            j := x
            if midy not= y then
                xStep := (midx - x) / (y - midy)
            else
                xStep := 0
            end if

            for decreasing i : y .. midy


                j += xStep


                var scaledBG := Pic.Scale (bg, round (Pic.Width (bg) * tempMag), round (Pic.Height (bg) * tempMag))
                Pic.Draw (scaledBG, round (- (x * tempMag - j)), round (- (y * tempMag - i)), picCopy)

                tempMag += tempMagStep
                Pic.Free (scaledBG)
                View.Update

                %delay (100)
            end for
        end if





    end if

end zoom



const zoomx := 200
const zoomy := 100



drawfillbox (0, 0, maxx, maxy, black)
for i : 1 .. 100
    drawfilloval (Rand.Int (0, maxx), Rand.Int (0, maxy), Rand.Int (1, 20), Rand.Int (1, 20), Rand.Int (1, maxcolor))
end for




Draw.ThickLine (zoomx, 0, zoomx, maxy, 5, brightred)
drawfilloval (zoomx, zoomy, 15, 15, brightblue)
View.Update
delay (1000)

zoom (zoomx, zoomy, 2)









so is there a more efficient way to do it?
and yes i do notice the pixelization but that should be okay with me.

Author:  Tony [ Fri Jan 02, 2009 3:05 am ]
Post subject:  RE:screen zooming and centering at the same time.

Actually it didn't seem to hit the memory too badly, though it was fairly brutal on the CPU. It takes processing power to scale a full image to be that large, that many times.

There are a couple of things you could do:
- you don't need to scale the full image, just the portion that is going to be displayed. So instead of
code:
var bg := Pic.New (0, 0, maxx, maxy)

you could take a snapshot of a smaller area and scale that.

- you could try to have less steps in the animation. The flow will be less smooth (though at this level of pixalation it shouldn't really matter)

- if it's still slow, you could try pre-loading some of the work into memory, when you have a chance before the animation is to begin.

Author:  chopperdudes [ Fri Jan 02, 2009 11:29 am ]
Post subject:  RE:screen zooming and centering at the same time.

at some places on the screen it's better than others, for example at 300, 100, it'll most likely crash.

i was thinking, because i need to make an effect of actually zooming in on the whole window, i need the Pic.New (0, 0, maxx, maxy). But however, instead of always scaling that, each time through the loop, i take a new picture of the screen and scale that instead.

however that would be more math intensive as i'd need to keep track of where to zoom after each loop.

Author:  The_Bean [ Fri Jan 02, 2009 4:29 pm ]
Post subject:  Re: screen zooming and centering at the same time.

Will you be using Turing Draw commands for your final project or importing real pictures?

If your only drawing with Turing Draw commands, there's a way of doing it without having everything pixalized.

Author:  Tony [ Fri Jan 02, 2009 6:07 pm ]
Post subject:  Re: RE:screen zooming and centering at the same time.

chopperdudes @ Fri Jan 02, 2009 11:29 am wrote:
however that would be more math intensive as i'd need to keep track of where to zoom after each loop.

sounds like an interesting problem to solve.

Although, wouldn't you pan your zoom by the same amount each time?

Author:  chopperdudes [ Fri Jan 02, 2009 6:22 pm ]
Post subject:  Re: screen zooming and centering at the same time.

yeah i will be importing pictures, but i just don't want the hassel of including them here.

and i found out why sometimes the original way doesn't work. so i fixed that and is using hte original way, if any1 come up with a better solution, feel free to post it here.

code:



View.Set ("graphics:700;550,position:center;center,nobuttonbar,offscreenonly")


proc zoom (x1, y1, x2, y2 : int, mag : real)

    var bg := Pic.New (0, 0, maxx, maxy)
    var tempMag : real := 1
    var tempMagStep : real
    var step : int


    if abs (x2 - x1) > abs (y2 - y1) then

        step := abs (x2 - x1) div 30
        if step = 0 then
            step := 1
        end if

        if x2 not= x1 then
            tempMagStep := mag / abs (x2 - x1) * step
        else
            tempMagStep := 0
        end if



        if x1 < x2 then
            var j, yStep : real
            j := y1
            if x2 not= x1 then
                yStep := (y2 - y1) / (x2 - x1) * step
            else
                yStep := 0
            end if

            for i : x1 .. x2 by step


                j += yStep




                var scaledBG := Pic.Scale (bg, round (Pic.Width (bg) * tempMag), round (Pic.Height (bg) * tempMag))
                Pic.Draw (scaledBG, round (- (x1 * tempMag - i)), round (- (y1 * tempMag - j)), picCopy)

                tempMag += tempMagStep
                Pic.Free (scaledBG)
                View.Update
                delay (round (1000 / (mag / tempMagStep)))

                %delay (100)
            end for
        else
            var j, yStep : real
            j := y1
            if x1 not= x2 then
                yStep := (y2 - y1) / (x1 - x2) * step
            else
                yStep := 0
            end if

            for decreasing i : x1 .. x2 by step


                j += yStep


                var scaledBG := Pic.Scale (bg, round (Pic.Width (bg) * tempMag), round (Pic.Height (bg) * tempMag))
                Pic.Draw (scaledBG, round (- (x1 * tempMag - i)), round (- (y1 * tempMag - j)), picCopy)

                tempMag += tempMagStep
                Pic.Free (scaledBG)
                View.Update
                delay (round (1000 / (mag / tempMagStep)))

                %delay (100)
            end for
        end if



    else

        step := abs (y2 - y1) div 30
        if step = 0 then
            step := 1
        end if


        if y2 not= y1 then
            tempMagStep := mag / abs (y2 - y1) * step
        else
            tempMagStep := 0
        end if


        if y1 < y2 then
            var j, xStep : real
            j := x1
            if y2 not= y1 then
                xStep := (x2 - x1) / (y2 - y1) * step
            else
                xStep := 0
            end if

            for i : y1 .. y2 by step


                j += xStep




                var scaledBG := Pic.Scale (bg, round (Pic.Width (bg) * tempMag), round (Pic.Height (bg) * tempMag))
                Pic.Draw (scaledBG, round (- (x1 * tempMag - j)), round (- (y1 * tempMag - i)), picCopy)

                tempMag += tempMagStep
                Pic.Free (scaledBG)
                View.Update
                delay (round (1000 / (mag / tempMagStep)))

                %delay (100)
            end for
        else
            var j, xStep : real
            j := x1
            if y2 not= y1 then
                xStep := (x2 - x1) / (y1 - y2) * step
            else
                xStep := 0
            end if

            for decreasing i : y1 .. y2 by step


                j += xStep


                var scaledBG := Pic.Scale (bg, round (Pic.Width (bg) * tempMag), round (Pic.Height (bg) * tempMag))
                Pic.Draw (scaledBG, round (- (x1 * tempMag - j)), round (- (y1 * tempMag - i)), picCopy)

                tempMag += tempMagStep
                Pic.Free (scaledBG)
                View.Update
                delay (round (1000 / (mag / tempMagStep)))

                %delay (100)
            end for
        end if





    end if

end zoom





const zoomx := 300
const zoomy := 100



drawfillbox (0, 0, maxx, maxy, black)
for i : 1 .. 100
    drawfilloval (Rand.Int (0, maxx), Rand.Int (0, maxy), Rand.Int (1, 20), Rand.Int (1, 20), Rand.Int (1, maxcolor))
end for




Draw.ThickLine (zoomx, 0, zoomx, maxy, 5, brightred)
drawfilloval (zoomx, zoomy, 15, 15, brightblue)
View.Update
delay (1000)

zoom (zoomx, zoomy, maxx, maxy, 2)





Author:  chopperdudes [ Fri Jan 02, 2009 6:26 pm ]
Post subject:  RE:screen zooming and centering at the same time.

and yes tony when i was trying to do it that way i was planning the zoom each time to be the same, however, each time the target would more more toward the center, so the next loop the starting cordinate would be different already.

sounds more like a recursive problem lol.

Author:  The_Bean [ Fri Jan 02, 2009 8:08 pm ]
Post subject:  Re: screen zooming and centering at the same time.

If your going to be in a zoomed in state most of the time, then why not try doing the reverse of what you are doing. Instead of creating your images for a standard view level, make them at the 2x view level, then you don't need to scale everything in the new position after each run of the loop. You can just draw them normally. To make the zoom in feature you can scale everything to be smaller then bring it to normal size. This will also remove the pixalizing problem.


: