开发者

Check if the hands of an analog clock are positioned correctely

开发者 https://www.devze.com 2023-02-14 04:27 出处:网络
I\'m creating an analog clock input method that users can use to pick a time. Users can click on the inner circle to set the short hand (hour) and can click on the outer circle to set the long hand (m

I'm creating an analog clock input method that users can use to pick a time. Users can click on the inner circle to set the short hand (hour) and can click on the outer circle to set the long hand (minute).

Check if the hands of an analog clock are positioned correctely

The problem is that users are free to click any point on the clock and therefor can pick an invalid position of the hands. Is there any way (algoritm) to detect this?

window.addEvent('domready', function()
{
  var handLong = [10, 20, 30, 40, 50, 60, 70, 80];
  var handShort = [10, 20, 30, 40, 50];

  injectHands('clock', handShort, handLong);

  $('clock').addEvent('click', function(e)
  {
    var x = correctX(e.page.x - e.target.getPosition().x, true);
    var y = correctY(e.page.y - e.target.getPosition().y, true);

    var angle = calculateAngle(x, y);

    // grote wijzer positioneren
    if (insideOuter(x, y))
    {
      moveHand(handLong, 'Long', angle);
    }
    // kleine wijzer positioneren
    else if (insideInner(x, y))
    {
      moveHand(handShort, 'Short', angle);
    }
  });
});

// Valt punt (x, y) binnen een cirkel met middenpunt (x, y) en radius r
function insideCircle(pointX, pointY, circleX, circleY, radius)
{
  dX = pointX - circleX;
  dY = pointY - circleY;

  return ((dX * dX) + (dY * dY)) <= (radius * radius);
}

// Valt punt (x, y) (enkel) binnen de buitenste cirkel (grote wijzer)
function insideOuter(pointX, pointY)
{
  return !insideInner(pointX, pointY) && insideCircle(pointX, pointY, 0, 0, 100);
}

// Valt punt (x, y) (enkel) binnen de binnenste cirkel (grote wijzer)
function insideInner(pointX, pointY)
{
  return insideCircle(pointX, pointY, 0, 0, 50);
}

// corrigeer x as (100 => 0) (0 => 100)
function correctX(x, nn)
{
  if (nn)
  {
    return x - 100;
  }
  return x + 100;
}

// corrigeer y as (100 => 0) (0 => 100)
function correctY(y, nn)
{
  if (nn)
  {
    return -y + 100;
  }
  return Math.abs(y - 100);
}

function calculateAngle(x, y)
{
  if ((x >= 0) && (y >= 0))
  {
    return Math.atan(x / y) * (180 / Math.PI);
  }
  else if (((x >= 0) && (y < 0)) || ((x < 0) && (y < 0)))
  {
    return 180 + Math.atan(x / y) * (180 / Math.PI);
  }
  else if ((x < 0) && (y >开发者_JS百科= 0))
  {
    return 360 - Math.abs(Math.atan(x / y) * (180/ Math.PI));
  }
}

function roundAngleByMinute(angle)
{
}

function calculateX(angle, hypotenuse)
{
  return Math.sin((Math.PI / 180) * angle) * hypotenuse;
}

function calculateY(angle, hypotenuse)
{
  return Math.cos((Math.PI / 180) * angle) * hypotenuse;
}

function injectHands(div, handShort, handLong)
{
  for (var i = 0; i < handShort.length; i++)
  {
    $(div).grab(new Element('img', {src: 'images/red_8x8.png', class: 'hands handShort', id: 'handShort-' + handShort[i]}));
  }
  for (var i = 0; i < handLong.length; i++)
  {
    $(div).grab(new Element('img', {src: 'images/blue_8x8.png', class: 'hands handLong', id: 'handLong-' + handLong[i]}));
  }

  $(div).grab(new Element('img', {src: 'images/black_8x8.png', class: 'hands', id: 'hand-center'}));

  $$('img.hands').hide();
  $('hand-center').show();
}

function moveHand(hand, whichHand, angle)
{
  for (var i = 0; i < hand.length; i++)
  {
    var hypotenuse = hand[i];
    var x = calculateX(angle, hypotenuse) - 5;
    var y = calculateY(angle, hypotenuse) + 5;
    var left = correctX(x);
    var top = correctY(y);

    $('hand' + whichHand + '-' + hypotenuse).set('styles', {'left': left + 'px', 'top': top + 'px'});
  }
  $$('img.hand' + whichHand).show();
}


When you set the hour hand, you can figure out the minute hand. trigonometry to the rescue! When you set the minute hand, assume the minute hand forwards to the selected position and adjust hour hand accordingly.

The minute hand shows a function of the hour hands angle, much like the modulo operator works...

The other way round works too: Given a minute hand angle, there are only twelve possible hour hand angles. Just choose the one closest to the current hour hand angle...


Just round the position of the hour hand to the nearest hour and add the corresponding offset for the current minute hand position?

0

精彩评论

暂无评论...
验证码 换一张
取 消