On 2015-10-15 19:42, hh wrote:
Not really, if you mean affine transform. Translation destroys the wonderful commutativity you have with my proposal: If you interchange objects in the owner path/message path before a target then this has no effect on the total scalefactor of this target. And you know the "inverse" operation as a function! Beside the usual rounding effects I can see no problem with that at the moment.

I'm not sure I follow - commutativity makes no difference in this instance - you only need invertibility and associativity. Affine transforms can be represented as matrices and matrix multiplication is associative, and non-degenerate matrices have inverses - thus you can replace any scale operation in your proposal with an arbitrary (invertible) matrix representing an affine transform.

Indeed, in that light, what you propose is precisely the same as the idea of every object being able to have a transform property (if not set it is the identity) - the total transform of a nested object is the multiplication of all the ancestor transforms. This is how most UI toolkits (which allow arbitrary affine transforms) work and from a rendering point of view poses no problem.

The stack (and it's view) is the global object and handles with the OS and
the hardware (you have a lot of pretty things already realized for us).
Everything in the stack is in local coords.

Yes - this is how it is at the moment - you can translate between local (card-relative) and global (screen-relative) using localLoc and globalLoc functions.

The mouseLoc etc. is scaled by TSF(mouse) = SF(stack)*SF(card)*SF(mouse).
We don't have to care about such things, you do in the engine.
And it is scripter's problem to ask for the total scalefactor ('TSF')
of objects.

Okay - so you suggest that any co-ordinates coming from the engine remain in card-space - where card-space is the top-level transform.

This does mean that script will have to explicitly deal with all co-ordinate transforms. So let's say you have a mouseMove handler in a graphic which uses the location of the mouse within itself to change its color:

on mouseMove pX, pY
  if pX < item 1 of the loc of me then
    if pY < item 2 of the loc of me then
      set the backColor of me to red
    else
      set the backColor of me to green
    end if
  else
    if pY < item 2 of the loc of me then
      set the backColor of me to blue
    else
      set the backColor of me to orange
    end if
  end if
end mouseMove

In an ideal world, this handler would still function regardless of the transform of the graphic containing it. Indeed, if co-ordinates are delivered to it in the target object's local co-ordinate system - then it does.

However, for arbitrary transforms where the pX, pY is kept in the card co-ordinate system it cannot - the reason for this is that under an arbitrary affine transform a rectangle which is parallel on both sides to the pixel grid may cease to be parallel to the pixel grid which means that geometry changes (when doing things extrinsically from the target object, at least).

Now, it is clear that if you restrict the transform to scale (and translation) then because such things preserve rectangles in both orientation and alignment relative to the pixel grid any non-size related geometry conditions you code remain correct - so the above handler would work fine.

However, here is a handler which would not work fine in this instance:

on mouseMove pX, pY
  if pY < the top of me + 20 then
    set the backColor of me to red
  else if pY > the bottom of me - 20 then
    set the backColor of me to green
  else
    set the backColor of me to blue
  end if
end mouseMove

Under a 'keep everything at the card-space' model - this code breaks as the scale of the target object changes. This is because the handler is dependent on a size (20) which is relative to the object's innate size rather than its scaled size. So, for this handler to work (even in a restricted, scale/translate only transform model) the script would need to be amended:

on mouseMove pX, pY
  if pY < the top of me + 20 * the effective yScale of me then
    set the backColor of me to red
  else if pY > the bottom of me - 20 * the effective xScale of me then
    set the backColor of me to green
  else
    set the backColor of me to blue
  end if
end mouseMove

Thus, in reality, keeping things in 'card-level' co-ordinate system and only allowing scale/translation makes no difference to the requirements on code. For general scripts which manipulate co-ordinates in anything other than very simple ways, you still have to explicitly take into account the potential effects of transformation thus, at the end of the day, you might as well allow arbitrary affine transforms since the code burden is identical. For example, the above modified code works if only scaling is allowing, however the code for the case of arbitrary transforms would be something like:

on mouseMove pX, pY
  local tY
  put item 2 of objectLoc(pX, pY) into tY
  if tY <  20 then
    set the backColor of me to red
  else if tY > the relative height of me - 20 then
    set the backColor of me to green
  else
    set the backColor of me to blue
  end if
end mouseMove

Here, I'm assuming a function 'objectLoc' which transforms a point from card-space to object-space (object-space being defined by the concatenation of transforms from itself up to the card). I'm also assuming that 'loc', 'left', 'top', 'right', 'bottom', 'width' and 'height' have 'relative' adjectives which return them in object-space, rather than card-space.

Perhaps an 'objectLoc' idea and arbitrary affine transforms are not something to be concerned about. If you use transforms you might have to do some co-ordinate juggling, if you are writing controls which you want to be used generally - again, you might have to do some co-ordinate juggling. The rule is just that if passing co-ordinates between objects (unless there is a prior agreement), you need to keep things in card-space and let the code in the target objects do the appropriate transform.

Of course there is a gulf between having an idea that might work and implementing it in the engine - the lack of floating point co-ordinates is going to be a huge issue here I think... The 'visibleRect' of a stack is at least feasible in the near term - which at least gives zoom and panning at the card-level if not at the individual object level.

Plenty to think about!

Warmest Regards,

Mark.

--
Mark Waddingham ~ m...@livecode.com ~ http://www.livecode.com/
LiveCode: Everyone can create apps

_______________________________________________
use-livecode mailing list
use-livecode@lists.runrev.com
Please visit this url to subscribe, unsubscribe and manage your subscription 
preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode

Reply via email to