How to constrain position of dragged graphic to path of a circle?

LiveCode is the premier environment for creating multi-platform solutions for all major operating systems - Windows, Mac OS X, Linux, the Web, Server environments and Mobile platforms. Brand new to LiveCode? Welcome!

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, robinmiller

stam
Posts: 2679
Joined: Sun Jun 04, 2006 9:39 pm
Location: London, UK

How to constrain position of dragged graphic to path of a circle?

Post by stam » Mon Sep 20, 2021 2:28 am

Hi all,

I want the user to be able to drag a small graphic around the diameter a circular oval - in effect constrain the position of the small graphic so that when the user grabs it, i can only be dragged and positioned somewhere along the circle's diameter.

i presume this will require cos and sin functions but not quite managing this...

Any suggestions?

Many thanks
Stam

kdjanz
Posts: 300
Joined: Fri Dec 09, 2011 12:12 pm
Location: Fort Saskatchewan, AB Canada

Re: How to constrain position of dragged graphic to path of a circle?

Post by kdjanz » Mon Sep 20, 2021 4:24 am

Can you create a template circle the same colour as the background and check that the mouse is “within” the graphic?

Kelly

SparkOut
Posts: 2852
Joined: Sun Sep 23, 2007 4:58 pm

Re: How to constrain position of dragged graphic to path of a circle?

Post by SparkOut » Mon Sep 20, 2021 7:31 am

Malte's Animation Engine does this, check the store. I'm not sure how licensing will work going forward (it's dual licensed at present).
Otherwise a 99% transparent template to check the position is "within" as suggested by Kelly. (And a smaller template inside to check that it is "not within" to keep it at the edge.) But that might get somewhat tricky to keep a smooth movement going.

stam
Posts: 2679
Joined: Sun Jun 04, 2006 9:39 pm
Location: London, UK

Re: How to constrain position of dragged graphic to path of a circle?

Post by stam » Mon Sep 20, 2021 9:09 am

Thanks both,

the problem with this approach is that 'within the rect' and actually being on the circumference of the circle are two different things, since the rect is, well, a rect and not a circle ;)

Would probably need geometric/trigonometric math, but i'm not up to speed with that or how to transform that into coordinate data for the small graphic.

Will look at animation engine, but seems a bit heavyweight to have that whole lib just for this tiny function. I also looked at the radiaDialOmatic stack on revonline, but that wasn't easy to penetrate either...

I'll keep looking (although it's relatively low priority) - but if someone has any ideas please do reach out ;)

richmond62
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 9359
Joined: Fri Feb 19, 2010 10:17 am
Location: Bulgaria

Re: How to constrain position of dragged graphic to path of a circle?

Post by richmond62 » Mon Sep 20, 2021 10:27 am

Use sine and cosine to populate a list field [let's call it "SHOPPING"] with locations of points on the circumference of a circle.

Set a graphic object's points to the lines of the list field.

Set up a circular graphic [let's call it "BALL"] containing this sort of script:

Code: Select all

on mouseDown
drag me
end mouseDown

on mouseUp
 put (the left of grc "BALL" + ((the width of grc "BALL")/2) into LAT
 put (the bottom of grc "BALL" + ((the height of grc "BALL")/2) into VERT
 put (LAT & "," & VERT) into HERE
 put 1 into CHEAP
 repeat until line CHEAP of fld "SHOPPING" is empty
 if line CHEAP of fld "SHOPPING" = HERE then
 set the loc of grc "BALL" to HERE
 end if
 add 1 to CHEAP
 end repeat
 end mouseUp

stam
Posts: 2679
Joined: Sun Jun 04, 2006 9:39 pm
Location: London, UK

Re: How to constrain position of dragged graphic to path of a circle?

Post by stam » Mon Sep 20, 2021 1:20 pm

Thanks Richmond... I'm not sure i understand the code however - probably my old brain struggles with incongruous variable names as well. I don't know that it helps callings stuff random names (well if i'm honest it's blindingly confusing ;) )
Did you actually get this to work, or is it a thought experiment? (if you did get this to work, could you post a stack please?)


I've been experiementing with a different take on this, mainly to get my understanding of trigonometric functions in coding up to to speed.

The first impediment i found is that you have to convert angles from degrees to radians (radian = angle * pi / 180) before using in sin() or cos() functions.

As a test, i created a simple stack with a circle called "circle", a small marker graphic (another small circle called 'knob'). I added a slider (min 0, max 360) to change the arcAngle of 'circle' and wanted the 'knob' to move with the moving arc.

To calculate the centre location of the marker graphic based on the arcAngle of a given circular oval:

Code: Select all

function getXYfromAngleOfCircle pCircle // the long id of the CIRCULAR oval
    local tAngle, tRadius, x, y, tLoc 
    
    put the width of pCircle/2  into tRadius
    put item 1 of the loc of pCircle into x
    put item 2 of the loc of pCircle into y
    put (360 -  the arcAngle of pCircle) * (pi/180) into tAngle
    
    put x + cos(tAngle) * tRadius into item 1 of tLoc
    put y + sin(tAngle)  * tRadius into item 2 of tLoc
    return tLoc
end getXYfromAngleOfCircle
There is a great explanation of the trigonometric functions used to calculate the x,y on stackExchange: https://gamedev.stackexchange.com/quest ... cular-path


From the slider, i change the arcAngle and pass the long id of the circle to getXYfromAngleOfCircle to get the loc for the marker graphic:

Code: Select all

on scrollbarDrag pNewPosition  
    lock screen
    set the arcAngle of grc "circle" to the thumbposition of me
    set the location of grc "knob" to getXYfromAngleOfCircle(the long id of grc "circle")
end scrollbarDrag
Moving the slider changes the arc showing and moves the graphic 'knob' exactly across the circumference.

I'm trying to get clear in my head if and how this can be used to constrain dragging of the small graphic...
Anyway, my tiny stack attached.
Attachments
radial.livecode.zip
(1.11 KiB) Downloaded 140 times

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 9647
Joined: Wed May 06, 2009 2:28 pm
Location: New York, NY

Re: How to constrain position of dragged graphic to path of a circle?

Post by dunbarx » Mon Sep 20, 2021 2:13 pm

This has been a topic before. I made a demo that used a regular polygon of hundreds of sides. This looks exactly like a circle, and can be sized to match any desired actual circle. The, point is that such a polygon contains lots of actual points, and the loc of any other object can be set to any series of adjacent points as required. Timing of the setting process is up to you.

If you need me to, I will try to find that demo, but perhaps you get the point. :wink:

Craig

stam
Posts: 2679
Joined: Sun Jun 04, 2006 9:39 pm
Location: London, UK

Re: How to constrain position of dragged graphic to path of a circle?

Post by stam » Mon Sep 20, 2021 2:21 pm

dunbarx wrote:
Mon Sep 20, 2021 2:13 pm
This has been a topic before. I made a demo that used a regular polygon of hundreds of sides. This looks exactly like a circle, and can be sized to match any desired actual circle. The, point is that such a polygon contains lots of actual points, and the loc of any other object can be set to any series of adjacent points as required. Timing of the setting process is up to you.

If you need me to, I will try to find that demo, but perhaps you get the point. :wink:

Craig
Thanks Craig - getting the points isn't hard; after all:

Code: Select all

get the effective points of graphic "circle"
will give a list of all points of the oval - I'm not sure if there is a gain to using a poly with hundreds of sides? (but i'll defer to your long experience).

The question that i still haven't quite got is how, when dragging a small marker graphic, to constrain it's movements so that in only moves along the circumference of said circle.

I know it should be possible (after all, there is a bit of a masterclass on this in the stack RadialDialOmatic available in sample stacks - but i don't understand it ;) )

Grateful for any suggestions (or if you have a stack showing this please do share!)
Stam

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 9647
Joined: Wed May 06, 2009 2:28 pm
Location: New York, NY

Re: How to constrain position of dragged graphic to path of a circle?

Post by dunbarx » Mon Sep 20, 2021 2:27 pm

Stam.

Check out this stack I just made. Perhaps I am not understanding?
MoveAlongOval.livecode.zip
(904 Bytes) Downloaded 161 times
Craig

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 9647
Joined: Wed May 06, 2009 2:28 pm
Location: New York, NY

Re: How to constrain position of dragged graphic to path of a circle?

Post by dunbarx » Mon Sep 20, 2021 2:50 pm

Stam.

I see that I did not pick out "oval" when you said "circular oval". Anyway, let me know what still need to do with the "effective points" sequencing thingie.

Craig

stam
Posts: 2679
Joined: Sun Jun 04, 2006 9:39 pm
Location: London, UK

Re: How to constrain position of dragged graphic to path of a circle?

Post by stam » Mon Sep 20, 2021 3:47 pm

dunbarx wrote:
Mon Sep 20, 2021 2:27 pm
MoveAlongOval.livecode.zip
Craig
Thanks Craig - i appreciate it but it was not quite what i was looking for.
I can make the graphic move programmatically along predefined points, but that's not the question.

The question is that is the users grabs the maker graphic and moves it, how to make sure it stays on the circle and just moves around it's circumference while the user is dragging it. More like a radial dial?
Or am i missing the obvious? (fully possible)

Anyway it occurred to me that i had already figured out above how to position the marker based on the arcAngle of the circle. Then it dawned on me that all i needed to do was calculate the angle between the marker (mouseLoc) and the x axis, in the same fashion arcAngle would work and pass that angle to my previous handler.

This solution works.
It works fantastically in 9.6.2 RC2 - super quick.

Unfortunately from 9.6.2 RC3 onwards, including the illustrious and premium priced 9.6.4, there has been a significant slowing of anything involving graphics (bug reported). This can be mitigated with frivolous use of 'lock screen' but doesn't quite make it as good as on 9.6.2 RC2.
This means that using LC more recent that 9.6.2 RC2 is slower, and a slight 'ghost' of the marker appears transiently as the user is dragging the marker.
Not sure what to do about that...


For the curious, to calculate the angle between the dragged marker and the horizontal plane in the same way as an arcAngle, i found helpful advice on StackOverflow
The handler is to calculate the angle is:

Code: Select all

function getAngleFromMouselocForCircle pCircle
    local  x1, y1, x2, y2, x3, y3, tAngle
    put item 1 of the loc of pCircle into x1
    put item 2 of the loc of pCircle into y1
    put item 1 of the loc of pCircle + the width of pCircle/2 into x2 
    put item 2 of the loc of pCircle into y2
    put item 1 of the mouseLoc into x3
    put item 2 of the mouseLoc into y3
    
    put atan2(y3- y1, x3 - x1) - atan2(y2 - y1, x2 - x1) into tAngle // in radians, needs transform
    
    put 180 + round ( tAngle * (180 / pi), 0) into tAngle // 1st transform to make it suitable for arcAngle
    if tAngle <= 180 then // 2nd transform to make it suitable for arcAngle
        put  180 - tAngle into tAngle
    else
        put  360 - (tAngle - 180) into tAngle
    end if
    
    return  tAngle
end getAngleFromMouselocForCircle
in the script for the marker graphic ("knob"), i calculate the angle of the centre of the graphic the user is dragging to the x-axis of the circle, assign this to the arcAngle of the circle and then change it's location based on this:

Code: Select all

on mouseDown
    lock screen
    grab me
end mouseDown

on mouseMove
    if the mouse is up then pass mouseMove
    lock screen
    setMarkerPosition
end mouseMove

on mouseUp
    setMarkerPosition
end mouseUp

command setMarkerPosition
    lock screen
    set the arcAngle of grc "circle" to getAngleFromMouselocForCircle(the long id of grc "circle")
    set the loc of me to getXYfromAngleOfCircle(the long id of grc "circle")
    set the thumbPosition of scrollbar "scrollbar" to the arcAngle of graphic "circle" // cosmetic	
end setMarkerPosition
It's quite possible i've gone about this the wrong way - please do point out if there are easier/simpler/faster ways! (i'm sure there are...).
My test stack is attached - drag the little blue circle ;)
Attachments
radial.livecode.zip
(1.61 KiB) Downloaded 141 times

elanorb
Livecode Staff Member
Livecode Staff Member
Posts: 516
Joined: Fri Feb 24, 2006 9:45 am

Re: How to constrain position of dragged graphic to path of a circle?

Post by elanorb » Mon Sep 20, 2021 4:10 pm

This question inspired me to try out the trig I have not used for a long time! Is this the kind of thing you are looking for?

Click on the small circle and drag it and it, it should follow the large circle.

Elanor
Attachments
circle.livecode.zip
(1.12 KiB) Downloaded 149 times
Elanor Buchanan
Software Developer
LiveCode

stam
Posts: 2679
Joined: Sun Jun 04, 2006 9:39 pm
Location: London, UK

Re: How to constrain position of dragged graphic to path of a circle?

Post by stam » Mon Sep 20, 2021 4:37 pm

elanorb wrote:
Mon Sep 20, 2021 4:10 pm
This question inspired me to try out the trig I have not used for a long time! Is this the kind of thing you are looking for?

Click on the small circle and drag it and it, it should follow the large circle.

Elanor
Wow thanks Elanor - that does perform much better!

I was looking at changing the arc as well but can work on that.

One minor issue with the code - if you swirl the mouse around a lot and near the centre you can trigger a crash (divide by zero error)
I think this relates to the line

Code: Select all

put atan(tDeltaY/tDeltaX) into tAngle  
where presumably tDeltaX is 0, but easy to guard against.

elanorb
Livecode Staff Member
Livecode Staff Member
Posts: 516
Joined: Fri Feb 24, 2006 9:45 am

Re: How to constrain position of dragged graphic to path of a circle?

Post by elanorb » Mon Sep 20, 2021 4:44 pm

Oh yes! That is probably when the mouse is on the centre line, so deltaX is 0, I must not have swirled my mouse enough to catch it!

Elanor
Elanor Buchanan
Software Developer
LiveCode

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 9647
Joined: Wed May 06, 2009 2:28 pm
Location: New York, NY

Re: How to constrain position of dragged graphic to path of a circle?

Post by dunbarx » Mon Sep 20, 2021 11:40 pm

Lovely, Elanor.

There is a slight issue with the handler, though. If you run roughshod with the cursor, the variable tDeltaX can now and then be 0, and that throws an error at line 19. It is an issue with hard coding a value into tCentreX (275) , where the mouseH can also be that value.

I only mention this because I am a sloppy tester of my own work, and I suspect you are not. :wink:

Craig

Post Reply

Return to “Getting Started with LiveCode - Experienced Developers”