3
$\begingroup$

I have a moving clock

Dynamic[Refresh[ClockGauge[], UpdateInterval -> 1]]

which should be clickable.

Program should make a sound when hand of a clock will touch the point where I clicked before.

I found something like this:

EventHandler[
Framed@"Play", {"MouseClicked" :> 
EmitSound[Sound@SoundNote["C", 10*^10, "Flute"]],
"MouseExited" :> EmitSound[Sound@SoundNote[SoundVolume -> 0]]}] 

to make a sound on click.

But I don't know how to get the position of clicked point.

$\endgroup$
5
  • $\begingroup$ Which hand? The minute hand? $\endgroup$
    – Karsten7
    Commented May 13, 2016 at 19:45
  • $\begingroup$ the seconds hand $\endgroup$
    – user40113
    Commented May 13, 2016 at 19:46
  • 3
    $\begingroup$ To get you started, try {Dynamic[Graphics[Refresh[ClockGauge[], UpdateInterval -> 1]]], Dynamic[MousePosition["Graphics"]]}. $\endgroup$
    – Karsten7
    Commented May 13, 2016 at 19:55
  • $\begingroup$ @Karsten7. Thank you! Do you have a idea how can I relate to the second hand in code? If[secondHandPosition, ..., ...] $\endgroup$
    – user40113
    Commented May 13, 2016 at 21:18
  • 1
    $\begingroup$ I think directly accessing the position of the second hand is more troublesome than using DateValue["Second"] and converting the point where you clicked into seconds. But you could also use FullForm@ClockGauge[] to get the second hand. $\endgroup$
    – Karsten7
    Commented May 13, 2016 at 21:44

2 Answers 2

2
$\begingroup$

Here is a quick first draft:

DynamicModule[{s = 0, pt = {0, 1}}, 
 Column@{ClickPane[
    Dynamic[Show[Refresh[Graphics[ClockGauge[]], UpdateInterval -> 1],
       Graphics[{Red, Point[pt]}]]], 
      (pt = #; s = 30*(1 + ArcTan[-pt[[2]], -pt[[1]]]/Pi)) &], 
   DynamicWrapper[Dynamic@s, 
    If[DateValue["Second"] == Round[s], 
     EmitSound[Sound@SoundNote["C", 0.5, "Flute"]]], 
    UpdateInterval -> 1]}]

I'll leave the further refinement to you.


In response to a comment.
Using the value of Clock:

DynamicModule[{pt = {0, 1}, secondHand = Line[{{0, 0}, {0, 55}}], clock = 0}, 
 Column@{ClickPane[
    Dynamic[Show[Graphics[Circle[{0, 0}, 60]], 
      Graphics[
       Dynamic[{Rotate[secondHand, (clock = Clock[{0, 59, 1}])*-Pi/30, {0, 0}]}]], 
      Graphics[{Red, Point[pt]}]]], 
    (pt = #; s = 30*(1 + ArcTan[-pt[[2]], -pt[[1]]]/Pi)) &], 
   DynamicWrapper[Dynamic@s, 
    If[clock == Round[s], 
     EmitSound[Sound@SoundNote["C", 0.5, "Flute"]]], 
    UpdateInterval -> 1]}]

Using the rotated secondHand:

DynamicModule[{pt = {0, 1}, secondHand = Line[{{0, 0}, {0, 55}}], rSH}, 
 Column@
  {ClickPane[
    Dynamic[Show[Graphics[Circle[{0, 0}, 60]], 
      Graphics[
       Dynamic[{rSH = Rotate[secondHand, Clock[{0, 59, 1}]*-Pi/30, {0, 0}]}]], 
      Graphics[{Red, Point[pt]}]]], 
    (pt = #; s = 30*(1 + ArcTan[-pt[[2]], -pt[[1]]]/Pi)) &], 
   DynamicWrapper[Dynamic@s, 
    If[rSH[[2]]*-30/Pi == Round[s], 
     EmitSound[Sound@SoundNote["C", 0.5, "Flute"]]], 
    UpdateInterval -> 1]}]
$\endgroup$
6
  • $\begingroup$ Thank you for your help! Works fine! $\endgroup$
    – user40113
    Commented May 13, 2016 at 21:55
  • 1
    $\begingroup$ @bebrave In your code you are using a duration of 10*^10. If you like to play a sound until you click something to make it stop, you can use RunScheduledTask as shown in this answer. $\endgroup$
    – Karsten7
    Commented May 13, 2016 at 22:13
  • $\begingroup$ I had to change ClockGauge to Circle and rotating Line: DynamicModule[{s = 0, pt = {0, 1}, secondHand = Line[{{0, 0}, {0, 55}}]}, Column@{ClickPane[Dynamic[Show[Graphics[Circle[{0, 0}, 60]], Graphics[Dynamic[{Rotate[secondHand, Clock[{0, 59, 1}]*-Pi/30, {0, 0}]}]], Graphics[{Red, Point[pt]}]]], (pt = #; s = 30*(1 - Sign[pt[[1]]] ArcCos[-pt[[2]]/Sqrt[pt[[1]]^2 + pt[[2]]^2]]/ Pi)) &], DynamicWrapper[Dynamic@s, If[secondHand == Round[s], EmitSound[Sound@SoundNote["C", 0.5, "Flute"]]], UpdateInterval -> 1]}] $\endgroup$
    – user40113
    Commented Jun 13, 2016 at 21:41
  • 1
    $\begingroup$ @bebrave The secondHand never changes. You could use the value of the Clock directly or use a rotated secondHand. $\endgroup$
    – Karsten7
    Commented Jun 13, 2016 at 22:01
  • 1
    $\begingroup$ @bebrave I added an example for each of these approaches. $\endgroup$
    – Karsten7
    Commented Jun 13, 2016 at 22:07
4
$\begingroup$

Here is my take on that:

EventHandler[Dynamic@Refresh[
   If[0 < handAngle - clickAngle < \[Pi]/30, 
    EmitSound[Sound@SoundNote["C"]]]; 
   handAngle = N@Mod[15 - DateValue[Now, "Second"], 60, -30] \[Pi]/30;
    Show[ClockGauge[], Graphics[Point[clickPoint]]], 
   UpdateInterval -> 
    1], {"MouseClicked" :> (clickPoint = MousePosition["Graphics"]; 
    clickAngle = ArcTan @@ clickPoint)}]
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.