检查模拟时钟的指针位置是否正确

发布于 2024-10-20 02:46:59 字数 3373 浏览 7 评论 0原文

我正在创建一种模拟时钟输入方法,用户可以使用它来选择时间。用户可以点击内圈设置短针(时),点击外圈设置长针(分)。

javascript Clock

问题是用户可以随意单击时钟上的任何点,因此可以选择无效的指针位置。有什么方法(算法)来检测这个吗?

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 >= 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();
}

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).

javascript clock

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 >= 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();
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

萌梦深 2024-10-27 02:46:59

当你设置了时针,你就可以算出分针了。三角函数来拯救!
设置分针时,假定分针前进至所选位置并相应地调整时针。

分针显示时针角度的函数,就像模运算符的工作原理一样……

反之亦然:给定分针角度,只有十二种可能的时针角度。只需选择最接近当前时针角度的一个即可...

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...

嗼ふ静 2024-10-27 02:46:59

只是将时针的位置四舍五入到最接近的小时并为当前分针位置添加相应的偏移量?

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文