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$
  • $\begingroup$ Which hand? The minute hand? $\endgroup$ – Karsten 7. May 13 '16 at 19:45
  • $\begingroup$ the seconds hand $\endgroup$ – bebrave May 13 '16 at 19:46
  • 3
    $\begingroup$ To get you started, try {Dynamic[Graphics[Refresh[ClockGauge[], UpdateInterval -> 1]]], Dynamic[MousePosition["Graphics"]]}. $\endgroup$ – Karsten 7. May 13 '16 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$ – bebrave May 13 '16 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$ – Karsten 7. May 13 '16 at 21:44
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$
  • $\begingroup$ Thank you for your help! Works fine! $\endgroup$ – bebrave May 13 '16 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$ – Karsten 7. May 13 '16 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$ – bebrave Jun 13 '16 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$ – Karsten 7. Jun 13 '16 at 22:01
  • 1
    $\begingroup$ @bebrave I added an example for each of these approaches. $\endgroup$ – Karsten 7. Jun 13 '16 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, privacy policy and cookie policy

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