Page 1 of 2
Which objects are at a given screen location
Posted: Fri Nov 25, 2016 5:13 am
by KimD
Sorry, I'm having a brain freeze. I've got about 50 movable objects on my card. I want to be able to test which of these 50 are at screen location X,Y.
I'm pretty sure that I could achieve this by:
- creating a new (tiny) object at location X,Y; and then
- Repeat for each object testObject on the card
-- If intersect(newObject, testObject) then Answer "Found one"
- End Repeat
but this sounds like it might have performance implications.
Is there a way that I can identify which of my 50 movable objects overlap with a given screen location, without having to test all objects 50 individually?
Thanks in advance
Kim
Re: Which objects are at a given screen location
Posted: Fri Nov 25, 2016 11:07 am
by MaxV
Behaviour is what you need (
http://livecode.wikia.com/wiki/Behavior ).
Moreover you can chain behaviours!
Re: Which objects are at a given screen location
Posted: Fri Nov 25, 2016 9:35 pm
by KimD
Thanks. How are you suggesting I use Behavior? I have used the Behavior property in another app, but I can't think how it would help me solve this problem.
Regards
Kim
Re: Which objects are at a given screen location
Posted: Fri Nov 25, 2016 11:45 pm
by dunbarx
Hi.
If you mean which of those objects occupies that point, then I would do as you suggested. It would take no time at all to check. I assume you do not simply mean to check the locs of those controls, but in any case the idea is the same.
If you want to divide and conquer, you could use whatever means you allow the change of loc to perform a similar test on an individual basis. Update a custom property somewhere that keeps a record. In this way you do not ever need to test all at once, simply check the current inventory of objects that met that criterion.
Craig Newman
Re: Which objects are at a given screen location
Posted: Sat Nov 26, 2016 12:03 am
by Jeanne DeVoto
Try using the "within" function:
Code: Select all
put "120,140" into testPoint
repeat with x = 1 to 50
if within (control 50,testPoint) then answer "Found one!"
end repeat
(The within function has some subtleties for graphics and images, so make sure to check the dictionary entry for it.)
Re: Which objects are at a given screen location
Posted: Sat Nov 26, 2016 12:24 am
by KimD
Thanks Craig and Jeanne
What I was wondering was whether there was already a built-in function that, if it was passed a pair of screen coordinates, would return a list of objects that overlapped this point. I realized that I could easily write such a function, but just:
a) thought that it would be slow; and
b) thought that it might already exist.
I think that what I'll do is create a 2d array that tracks the approximate area of the screen that each of my 50 movable objects are in, then limit my INTERSECT or WITHIN query to only that subset of the objects which I know are in the right approximate area.
Regards
Kim
Re: Which objects are at a given screen location
Posted: Sat Nov 26, 2016 10:14 am
by jmburnod
Hi Kim,
a) thought that it would be slow
You have 50 movable objects but how many objects do you have in the current card.
Why not a simple function. Something like this that take 0 milliseconds
Code: Select all
function getMyControlInSR
put 120,140 into tTestPoint
put the milliseconds into tOld
put empty into rMyControlInSR
repeat with i = 1 to 50
if within (btn i, tTestPoint) then
put the short name of control i & cr after rMyControlInSR
end if
end repeat
delete char -1 of rMyControlInSR
return the milliseconds - tOld & cr & rMyControlInSR
end getMyControlInSR
Best regards
Jean-Marc
Re: Which objects are at a given screen location
Posted: Sat Nov 26, 2016 12:31 pm
by Klaus
Hi all,
we have a controlatloc() function in LC***!
...
put controlatloc((100,100))
...
will return something like -> control 5, from which you can derive the ID or NAME of that object.
So no need for any repeat loop in this case!
***It is never a bad idea to read the "Release Notes" for every new version!
OK, the "downside":
This function will only return the control with the higehst layer at that location !
Best
Klaus
P.S.
Just added an enhancement request for extending this function:
http://quality.livecode.com/show_bug.cgi?id=18921
Re: Which objects are at a given screen location - SOLVED
Posted: Sat Nov 26, 2016 8:49 pm
by KimD
Thanks Klaus. That's it. It "felt" like something that should already exist, but I wasn't having any luck finding it by googling. Thanks also for adding the enhancement request.
Everyone - Thanks for all of the alternative ideas. I picked up a fair bit of "Collateral Knowledge"
Regards
Kim
Re: Which objects are at a given screen location
Posted: Sat Nov 26, 2016 11:43 pm
by rkriesel
KimD wrote:Is there a way that I can identify which of my 50 movable objects overlap with a given screen location, without having to test all objects 50 individually?
Hi, Kim. Here's recursive function controlsAtLoc that applies function controlAtLoc. It can digest a five-control pile on a card with a hundred buttons in about a fifth of a millisecond in LC 8.1.1 on macOS Sierra.
Code: Select all
function controlsAtLoc pLoc
local tControls
get controlAtLoc( pLoc )
if it is not empty then
hide it -- the caller should already have locked the screen
put controlsAtLoc( pLoc ) & it & cr into tControls
show it
return tControls
end if
end controlsAtLoc
Here's a way to test it:
Code: Select all
on mouseUp
local tMilliseconds
repeat 5
create button
set the loc of it to 200,100
end repeat
lock screen
subtract the long milliseconds from tMilliseconds
get controlsAtLoc ( "200,100" )
add the long milliseconds to tMilliseconds
breakpoint
end mouseUp
Does that work well for you, Kim?
By the way, in case you're looking for the release note, function controlAtLoc appeared in LC 6.0 four years ago.
-- Dick
Re: Which objects are at a given screen location
Posted: Sun Nov 27, 2016 1:58 am
by FourthWorld
KimD wrote:What I was wondering was whether there was already a built-in function that, if it was passed a pair of screen coordinates, would return a list of objects that overlapped this point. I realized that I could easily write such a function, but just:
a) thought that it would be slow; and
b) thought that it might already exist.
I think that what I'll do is create a 2d array that tracks the approximate area of the screen that each of my 50 movable objects are in, then limit my INTERSECT or WITHIN query to only that subset of the objects which I know are in the right approximate area.
With 50 objects it won't matter much. I just ran this function on a 3GHz Haswell running LC 9, and it takes only about 45 milliseconds to find matches for 1000 controls, and a little over 1 millisecond to check 50 controls:
Code: Select all
function ControlsAtLoc pLoc
put empty into tList
repeat with i = 1 to the number of controls
if within(control i, pLoc) then
put the long id of control i &cr after tList
end if
end repeat
delete last char of tList
return tList
end ControlsAtLoc
Dick's may be faster (his code usually is), but in this case since you're testing against moving objects you may not be able to rely on locking the screen when testing for intersections.
Re: Which objects are at a given screen location
Posted: Sun Nov 27, 2016 2:47 am
by rkriesel
FourthWorld wrote:... since you're testing against moving objects you may not be able to rely on locking the screen when testing for intersections.
How do objects move while a function runs (assuming it does not "wait .. with messages")? In other words, what can go wrong?
-- Dick
Re: Which objects are at a given screen location
Posted: Sun Nov 27, 2016 3:56 am
by FourthWorld
rkriesel wrote:FourthWorld wrote:... since you're testing against moving objects you may not be able to rely on locking the screen when testing for intersections.
How do objects move while a function runs (assuming it does not "wait .. with messages")? In other words, what can go wrong?
Functionally it should work. I was thinking of the additional redraw time from lock/unlock and how it might affect the smoothness of the animation.
Re: Which objects are at a given screen location
Posted: Sun Nov 27, 2016 11:40 pm
by MaxV
KimD wrote:Thanks. How are you suggesting I use Behavior? I have used the Behavior property in another app, but I can't think how it would help me solve this problem.
Regards
Kim
For example use the
rect2 (or loc2) property to move objects and the use this behavior:
########CODE#######
setprop rect2 newValue
set the rect of me to newValue
if intersect(me,testobject) then
answer "I am " the long ID of me & "and I'm on the target zone!"
end if
end rect2
#####END OF CODE#####
Re: Which objects are at a given screen location
Posted: Tue Nov 29, 2016 8:08 am
by rkriesel
FourthWorld wrote:I was thinking of the additional redraw time from lock/unlock and how it might affect the smoothness of the animation.
Appropriately including the lock screen and unlock screen within the timed section of code makes the technique I suggested take a millisecond, eliminating its speed advantage, for the pile of five within a hundred on a card. Thanks for the insight, Richard.
Kim, do you see an affect on the smoothness of the animation?
-- Dick