The coming of SVG
Mark Waddingham
mark at livecode.com
Sat Nov 11 04:57:11 EST 2017
On 2017-11-10 19:02, hh via use-livecode wrote:
> @David.
> You respond to my answer for jbv (relating SVG-animation).
>
> The answer for you is two paragraphs upwards, a LC stack:
> http://forums.livecode.com/viewtopic.php?p=129274#p129274
>
> The algorithm there allows you to get the clicked shape.
> That's all you need for setting clickregions of an image
> which are defined (whether SVG or not) by shapes (or their
> points/oulines). Just the same algorithm is used internally
> by the SVG tools.
And the engine (it hit-tests graphic objects in a similar fashion) -
although there are some flaws / issues as recently noted about oval
segments!
The geometric approach will always* work - but does require increasingly
complex math to do as fidelity requirements increase, indeed to
implement hit-testing correctly for a stroked path requires a lot of
care to numeric error and due to the end-caps and joins (round causes no
problems - as then its just the standard 'is within half the stroke
width away from the path - but miter and bevel are quite a bit more
complicated). Then you might have masks, clips, and raster images to
take into account too - not to mention fill rules, blend modes and
transparency layers.
Indeed, to do that kind of hit-testing you have to basically replicate
what the graphics engine is doing under the hood - so it would be best
to leverage all of that if possible...
A perfectly viable method is to actually use rasterization to perform
hit-testing:
1) Create an offscreen canvas 1x1 pixel in size
2) Translate the canvas so that the 1x1 pixel is aligned with the
mouse position
3) Make sure the canvas is cleared to transparent black (i.e. pixels
are 0).
4) Render the complex graphics will all paints as opaque white
5) If the single pixel in the canvas is white, then the complex
graphics has been hit, if it is transparent black it has not.
This way you can be guaranteed that the hit-testing is done against
precisely what the user sees - you can even easily give an expanded hit
area. If you want hit to be true if within N pixel radius of the mouse,
then render to a NxN canvas centered around the mouse location then
blur/spread the result with a radius of N and check the center pixel.
(or just check to see if any of the pixels in the NxN canvas are set -
slightly simpler!).
You can create offscreen canvas's with LCB, so this is all possible with
what already exists - indeed, I'm sure there was some code around
somewhere to show how to do it for an arbitrary path:
https://github.com/livecode/livecode/pull/4358
Warmest Regards,
Mark.
* 'always' assuming infinite precision numbers, which obviously don't
exist. There are lots of cases (particularly with paths) where
intersection math can 'blow up' and not give reasonable results -
particularly when arbitrary affine transforms, and self-intersecting
paths are involved.
--
Mark Waddingham ~ mark at livecode.com ~ http://www.livecode.com/
LiveCode: Everyone can create apps
More information about the use-livecode
mailing list