I have a clock model with separate hands and I want these hands to be synchronized with the clock on the system. I can now get the values with the help of system.DateTime
but I need a formula to make this clock work properly.
The coverage Z angles of the clocks are as follows:
- 00:00 : -90 degress
- 03:00 : 0 degress
- 06:00 : 90 degress
- 09:00 : 180 degress
void Update()
{
var hourAngle = new Vector3(0f, 0f, DateTime.Now.Hour /* some formula here */ -90);
hourPointer.transform.eulerAngles = hourAngle;
var minuteAngle = new Vector3(0f, 0f, DateTime.Now.Minute /* some formula here */ -90);
minutePointer.transform.eulerAngles = minuteAngle;
var secondAngle = new Vector3(0f, 0f, DateTime.Now.Second /* some formula here */ -90);
secondPointer.transform.eulerAngles = secondAngle;
}
Please provide your guides and suggestions for making this formula. Thanks all.
CodePudding user response:
You have values
3 --- 6 --- 9 --- 12 --- 3
0° --- 90° --- 180° --- 270° --- 360°
If you add 90° to each value, you get
12 --- 3 --- 6 --- 9 --- 12
0° --- 90° --- 180° --- 270° --- 360°
which you can interpolate, where 0/12 o'clock becomes 0°/360°, 6 o'clock 180°, etc. Since you have only 12 hours on the face of the clock, but 24 hours in a day, you should subtract 12 hours in the afternoon. Also to have the hour hand point to the correct value, you should add the fraction of the minutes.
var hours= (float)DateTime.Now.Hour DateTime.Now.Minute / 60f;
if (hours > 12) hours -= 12;
var hourHandAngle = Mathf.LerpAngle(0, 360, hours / 12f) - 90f;
If you want your minute/second hands to "jump", you can use the value of the current time:
var minuteHandAngle = Mathf.LerpAngle(0, 360, DateTime.Now.Minute / 60f) - 90f;
var secondHandAngle = Mathf.LerpAngle(0, 360, DateTime.Now.Second / 60f) - 90f;
If you want the hands to move smoothly, you must add the seconds to the minute, and the milliseconds to the seconds value like with the hour hand.
CodePudding user response:
I was able to solve this question after a while, if we ignore -90
and -90
degress at the end of the vector (for some transform issue), the value of x
is the main answer. For values of seconds and minutes, just multiply the value of dateTime by 6. The logic of these numbers is equivalent to dividing it by 60 units and multiplying them by 360 degrees.
var minuteAngle = new Vector3(DateTime.Now.Minute * 6, -90, -90);
minutePointer.transform.localEulerAngles = minuteAngle;
var secondAngle = new Vector3(DateTime.Now.Second * 6, -90, -90);
secondPointer.transform.localEulerAngles = secondAngle;
But the hour option was a little different, since the hour pointer can't tick like a second pointer, the formula must be streamed, for this purpose I used DateTime.Now.TimeOfDay.TotalMinutes
to calculate the result of the minutes of the day factor To grade.
var hourAngle = new Vector3( (int) DateTime.Now.TimeOfDay.TotalMinutes / 2, -90, -90);
hourPointer.transform.localEulerAngles = hourAngle;
In the above code, the int
conversion is performed because TotalMinutes
is type of double
. The problem is split in two but due to the presence of 1440 minutes during the day. These minutes are a 24-hour period, which in the old hours is only 12 hours is enough, so in principle 720 minutes are needed, the conversion of 720 minutes to 360 degrees is obtained by dividing by two.