Canvas Transform Goes Haywire if Scaled

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
11 messages Options
Reply | Threaded
Open this post in threaded view
|

Canvas Transform Goes Haywire if Scaled

Sean P. DeNigris
Administrator
The following works as I expect:

        morph := Morph new
                topLeft: 200@400;
                openInWorld.

        outputRect := morph fullBounds.
        canvas := Display defaultCanvasClass extent: outputRect extent depth: Display depth.
        scale := 1.
        t := MorphicTransform offset: outputRect topLeft angle: 0 scale: scale.
        clipRect := outputRect translateBy: outputRect topLeft negated.
        canvas transformBy: t clippingTo: clipRect during: [ :aCanvas |
                aCanvas fullDrawMorph: morph ].
        canvas form asMorph openInWindow.

        "morph delete."

but if I change scale even a little bit (e.g. 0.95), things quickly go south.
Check out scale = 1 vs scale = 0.95 below:

Obviously they differ by more than I expected. If I change scale to 0.5, the morph disappears from view in the canvas completely.

I had both translation and scale working in a spike by translating with FormCanvas>>#translateBy:during: and then magifying with "canvas form magnifyBy: 0.5", but I want to do this in my morph's drawing method, so I want to do both with the canvas.

Where am I going wrong here?



Cheers,
Sean
Reply | Threaded
Open this post in threaded view
|

Re: Canvas Transform Goes Haywire if Scaled

wernerk
On 02/05/2015 06:29 AM, Sean P. DeNigris wrote:
> I had both translation and scale working in a spike by translating with
> FormCanvas>>#translateBy:during: and then magifying with "canvas form
> magnifyBy: 0.5", but I want to do this in my morph's drawing method, so I
> want to do both with the canvas.

"(morph transformedBy: t)openInWorld." obviously works as expected. but
judging from your question, doing a "self transformedBy:" somewhere
later in your morphs code wouldnt work?
werner

Reply | Threaded
Open this post in threaded view
|

Re: Canvas Transform Goes Haywire if Scaled

Nicolai Hess
In reply to this post by Sean P. DeNigris


2015-02-05 6:29 GMT+01:00 Sean P. DeNigris <[hidden email]>:
The following works as I expect:

        morph := Morph new
                topLeft: 200@400;
                openInWorld.

        outputRect := morph fullBounds.
        canvas := Display defaultCanvasClass extent: outputRect extent depth:
Display depth.
        scale := 1.
        t := MorphicTransform offset: outputRect topLeft angle: 0 scale: scale.
        clipRect := outputRect translateBy: outputRect topLeft negated.
        canvas transformBy: t clippingTo: clipRect during: [ :aCanvas |
                aCanvas fullDrawMorph: morph ].
        canvas form asMorph openInWindow.

        "morph delete."

but if I change scale even a little bit (e.g. 0.95), things quickly go
south.
Check out scale = 1 vs scale = 0.95 below:
<http://forum.world.st/file/n4803830/Screenshot_2015-02-05_00.png>
Obviously they differ by more than I expected. If I change scale to 0.5, the
morph disappears from view in the canvas completely.

I had both translation and scale working in a spike by translating with
FormCanvas>>#translateBy:during: and then magifying with "canvas form
magnifyBy: 0.5", but I want to do this in my morph's drawing method, so I
want to do both with the canvas.

Where am I going wrong here?



The scaling factor changes the effective coordinates of the morph
Morph topLeft 200@400
scale 0.5
Morph draws itself at 100@200
Therefore your MorphicTransform translates to far away (or not far enough?)

      morph := EllipseMorph new
                topLeft: 200@400;
                openInWorld.

        outputRect := morph fullBounds.
        canvas := Display defaultCanvasClass extent: outputRect extent depth: Display depth.
        scale := 0.5.

        "scale the offset of the translation too"
        t := MorphicTransform offset: outputRect topLeft * scale angle: 0 scale: scale.
        clipRect := outputRect translateBy: outputRect topLeft negated.
        canvas transformBy: t clippingTo: clipRect during: [ :aCanvas |
                aCanvas fullDrawMorph: morph ].
        canvas form asMorph openInWindow.
        morph delete.


What do you want to achieve?
Both
magnifyBy: and
transformBy:clippingTo:during:  (with non-pure-translation)

actually do the same, they warp-blitting a form.




 





-----
Cheers,
Sean
--
View this message in context: http://forum.world.st/Canvas-Transform-Goes-Haywire-if-Scaled-tp4803830.html
Sent from the Pharo Smalltalk Users mailing list archive at Nabble.com.


Reply | Threaded
Open this post in threaded view
|

Re: Canvas Transform Goes Haywire if Scaled

wernerk
Hi Sean,
the thing is clipped. as you can see here:
morph := Morph new
                topLeft: 200@400;
                openInWorld.
outputRect := (0@0) corner: (250.0@220.0).
        canvas := Display defaultCanvasClass extent: outputRect extent depth:
Display depth.
        scale := 0.5.
        t := MorphicTransform offset: outputRect topLeft angle: 0 scale: scale.
        clipRect := outputRect translateBy: outputRect topLeft negated.
        canvas transformBy: t clippingTo: clipRect during: [ :aCanvas |
                aCanvas fullDrawMorph: morph ].
        canvas form asMorph openInWindow.

werner

Reply | Threaded
Open this post in threaded view
|

Re: Canvas Transform Goes Haywire if Scaled

Sean P. DeNigris
Administrator
Thank you Werner and Nicolai! You were both right :) The transform offset needed to be scaled and the clipping needed to be both translated and scaled, too.

The final code was:
        morph := Morph new
                        topLeft: 200@400;
                        openInWorld.
        outputRect := morph fullBounds.
        scale := 0.2.
        canvas := Display defaultCanvasClass extent: outputRect extent * scale depth:
Display depth.  
        t := MorphicTransform offset: outputRect topLeft * scale angle: 0 scale: scale. "*** must scale offset"
        clipRect := (outputRect translateBy: outputRect topLeft negated) scaleBy: scale. "*** must translate and scale clip rect"
        canvas transformBy: t clippingTo: clipRect during: [ :aCanvas |
                aCanvas fullDrawMorph: morph ].

This seems so complicated. I would naively think that the API should do much of this for you. For example, why doesn't it know that when there's an offset AND a scale, the transform's offset should be adjusted by the scale?
        canvas form asMorph openInWindow.
Cheers,
Sean
Reply | Threaded
Open this post in threaded view
|

Re: Canvas Transform Goes Haywire if Scaled

wernerk
On 02/05/2015 03:27 PM, Sean P. DeNigris wrote:
> This seems so complicated. I would naively think that the API should do much
> of this for you. For example, why doesn't it know that when there's an
> offset AND a scale, the transform's offset should be adjusted by the scale?
Hi Sean,
i guess i wouldnt agree; if you look at MorphicTransform>>transform: it
very much looks to me like the natural way of first doing a translation
and then a scaling. for me they are independent transformations and
mixing them up only complicates things if you are doing more involved
things.
werner

Reply | Threaded
Open this post in threaded view
|

RadarMorph (was Re: Canvas Transform Goes Haywire if Scaled)

Sean P. DeNigris
Administrator
In reply to this post by Nicolai Hess
Nicolai Hess wrote
What do you want to achieve?
I've created an infinite desktop a la Self. To make things manageable, I'm currently writing a RadarView (also just like Self) to show a map of all the objects on the desktop, and the position of the current viewport. It's working now thanks to your help!

There is now only 1 major bug, and 3 little glitches:
1. (BUG): Every once in a while (can't figure out how to reproduce), it displays the Red X of Death like so:



2. When the container window is moved, the contents temporarily jump out of the radar screen
3. when the radar is dragged over another morph in the Self World, the clipping gets very weird
4. One side of the blue highlight rectangle sometimes disappears on resize

#2, #3, and #4 can be seen in this screencast: https://vimeo.com/118826521

Cheers,
Sean
Reply | Threaded
Open this post in threaded view
|

Re: RadarMorph (was Re: Canvas Transform Goes Haywire if Scaled)

nacho
awesome!
question, the UI was made completely in Morphic? or did you use Spec?
thanks


Lic. Ignacio Sniechowski, MBA
Prosavic SRL

Tel: (011) 4542-6714





















On Thu, Feb 5, 2015 at 3:06 PM, Sean P. DeNigris <[hidden email]> wrote:
Nicolai Hess wrote
> What do you want to achieve?

I've created an infinite desktop a la Self. To make things manageable, I'm
currently writing a RadarView (also just like Self) to show a map of all the
objects on the desktop, and the position of the current viewport. It's
working now thanks to your help!

There is now only 1 major bug, and 3 little glitches:
1. (BUG): Every once in a while (can't figure out how to reproduce), it
displays the Red X of Death like so:

<http://forum.world.st/file/n4804025/Screenshot_2015-02-05_11.png>

2. When the container window is moved, the contents temporarily jump out of
the radar screen
3. when the radar is dragged over another morph in the Self World, the
clipping gets very weird
4. One side of the blue highlight rectangle sometimes disappears on resize

#2, #3, and #4 can be seen in this screencast: https://vimeo.com/118826521





-----
Cheers,
Sean
--
View this message in context: http://forum.world.st/Canvas-Transform-Goes-Haywire-if-Scaled-tp4803830p4804025.html
Sent from the Pharo Smalltalk Users mailing list archive at Nabble.com.


Nacho Smalltalker apprentice. Buenos Aires, Argentina.
Reply | Threaded
Open this post in threaded view
|

Re: RadarMorph (was Re: Canvas Transform Goes Haywire if Scaled)

Sean P. DeNigris
Administrator
nacho wrote
question, the UI was made completely in Morphic? or did you use Spec?
Both. The standard parts (e.g. window, toolbars) were Spec, and everything inside the World window is pretty much straight Morphic.
Cheers,
Sean
Reply | Threaded
Open this post in threaded view
|

Re: RadarMorph (was Re: Canvas Transform Goes Haywire if Scaled)

Nicolai Hess
In reply to this post by Sean P. DeNigris


2015-02-05 19:06 GMT+01:00 Sean P. DeNigris <[hidden email]>:
Nicolai Hess wrote
> What do you want to achieve?

I've created an infinite desktop a la Self. To make things manageable, I'm
currently writing a RadarView (also just like Self) to show a map of all the
objects on the desktop, and the position of the current viewport. It's
working now thanks to your help!

Looks great. (And it will look even better if it (and Morphic) is working with Athens:) ).
 

There is now only 1 major bug, and 3 little glitches:
1. (BUG): Every once in a while (can't figure out how to reproduce), it
displays the Red X of Death like so:

<http://forum.world.st/file/n4804025/Screenshot_2015-02-05_11.png>

drawRadarViewOn: aCanvas

    | terrainRect transform scale clipRect viewRect offset |
    terrainRect := self radarCoverageArea.
    terrainRect isZero ifTrue: [ ^ self ].   

    "the viewRect scale must not depend on the clipRect extent"
    " you want to have the scale based on the radarmorph extent. But now, if something occludes
    " the radarmorph partially, the clipRect is smaller than your radarmorph and the scaling is wrong"
    viewRect := terrainRect scaledAndCenteredIn: aCanvas clipRect.

 

2. When the container window is moved, the contents temporarily jump out of
the radar screen

That one is tricky. If you grab the self world morph with the mouse, the morph is
not drawn in the morphic WorldMorph anymore, instead the handmorph creates a
form and a new canvas for drawing on this form. For this canvas the offset (or origin?)
is not the same as for the WorldMorph.


 
3. when the radar is dragged over another morph in the Self World, the
clipping gets very weird


 

There are some artefacts too, related to issue
12330 Rendering artifacts with scaled ImageMorph
(still unresolved)

 
4. One side of the blue highlight rectangle sometimes disappears on resize

#2, #3, and #4 can be seen in this screencast: https://vimeo.com/118826521





-----
Cheers,
Sean
--
View this message in context: http://forum.world.st/Canvas-Transform-Goes-Haywire-if-Scaled-tp4803830p4804025.html
Sent from the Pharo Smalltalk Users mailing list archive at Nabble.com.


Reply | Threaded
Open this post in threaded view
|

Re: RadarMorph (was Re: Canvas Transform Goes Haywire if Scaled)

Tudor Girba-2
In reply to this post by Sean P. DeNigris
Hi,

Nice. I see your environment is advancing nicely. Keep it up!

Doru

On Thu, Feb 5, 2015 at 7:06 PM, Sean P. DeNigris <[hidden email]> wrote:
Nicolai Hess wrote
> What do you want to achieve?

I've created an infinite desktop a la Self. To make things manageable, I'm
currently writing a RadarView (also just like Self) to show a map of all the
objects on the desktop, and the position of the current viewport. It's
working now thanks to your help!

There is now only 1 major bug, and 3 little glitches:
1. (BUG): Every once in a while (can't figure out how to reproduce), it
displays the Red X of Death like so:

<http://forum.world.st/file/n4804025/Screenshot_2015-02-05_11.png>

2. When the container window is moved, the contents temporarily jump out of
the radar screen
3. when the radar is dragged over another morph in the Self World, the
clipping gets very weird
4. One side of the blue highlight rectangle sometimes disappears on resize

#2, #3, and #4 can be seen in this screencast: https://vimeo.com/118826521





-----
Cheers,
Sean
--
View this message in context: http://forum.world.st/Canvas-Transform-Goes-Haywire-if-Scaled-tp4803830p4804025.html
Sent from the Pharo Smalltalk Users mailing list archive at Nabble.com.




--

"Every thing has its own flow"