The angle between the hour and minute hands of an analog clock is always between 0 and 180 degrees, inclusive. For example, at 12:00 the angle between the hands is 0 degrees. At 6:00 the angle is 180 degrees, and at 3:00 the angle is 90 degrees.Adapted from the original found in the ACM ICPC Problem Set w/o a solution.
Write a function that given an arbitrary time in the form of two integers (the first representing an hour between 1 and 12 inclusive and the second as minutes between 0 and 59 inclusive) will return the angle between the hands accurate to at least one fractional digit.
e.g.
f(12, 0) = 0.0 degrees
f(6, 0) = 180.0 degrees
f(12, 30) = 165.0 degrees
Monday, November 19, 2007
Is it quit'n time yet?
Subscribe to:
Post Comments (Atom)
3 comments:
something to keep in mind:
as the hour progresses, the hour hand moves as well. so at 3:15, the hour hand is -not- pointing at the 3.
other than that it should be easy... minute number directly correlates to an angle (say, ThetaMinute or Tm), though the hour hand will be a fraction.
with 60 minutes, each minute is 6 degrees, so that part is set. assuming H is hour# and M is minute#, as in 3:15, H = 3, M = 15...
Tm = M*6deg;
Th = (H + M/60)*5*6deg;
where there are 5 6-degree tick marks in each number on the clock face.
then just abs(Th-Tm)
optionally, if you included seconds, it would be the same thing, except with an added layer
Ts = S*6deg;
Tm = (H + S/60)*5*6deg;
Th = (H + M/60)*5*6deg;
I got the following...
double timedDegrees(int hours, int minutes) {
double hourDegrees = (hours % 12) * 30.0 + minutes * 0.5;
double minutesDegrees = minutes * 6.0;
return degreesBetween(hourDegrees, minutesDegrees);
}
double degreesBetween(double deg1, double deg2) {
double oneWay = ((deg1 - deg2) + 360) % 360;
double otherWay = ((deg2 - deg1) + 360) % 360;
return Math.min(oneWay, otherWay);
}
Everything is a simple equation except determining the "smaller way around". Also, I had to add 360 prior to the modulus operation b/c in Java, it will keep negative numbers negative opposed to doing a congruency.
I was hoping to not have to use the min, but couldn't come up with a way to do it that was purely mathematical. Another method my dad mentioned which may get rid of it is using cos/sin which I hadn't thought of.
arcosine functions that I've seen return the smallest positive angle that has that cosine.
angles in quadrant III have the same cosine as if you flipped them over the x-axis into quadrant II into positive y territory. thus angles like 180+30 will give the same cosine as angles like 180-30
angles in quadrant IV have the same cosine as if you flipped them over the x-axis into quadrant I . . 360-45 has the same cosine as 0+45
when you take the arcosine, it only gives you the smaller angle
so
arcosine(cosine(theta)) should make it into the smaller way around
let theta be the difference between the two hands, regardless of exceeding 360 (for example one way I calc'd the hour hand position for times like 12:30 gave it as >360)
of course you must be conscious of plugging in the angle in the appropriate units (some require radians NOT degrees) and also of re-converting to degrees if the arcosine in your language returns an answer in radians
degrees * pi / 180 = radians
Post a Comment