public static Point GetEndPoint(ClockHand clockHand, int handLength, DateTime dateTime, Point origin, bool is24HourClock = true) { var hour = dateTime.Hour; var minute = dateTime.Minute; var second = dateTime.Second; switch (clockHand) { case ClockHand.Hour: var degreesPerHour = is24HourClock ? DEGREES_PER_HOUR_ON_A_24_HOUR_CLOCK : DEGREES_PER_HOUR_ON_A_12_HOUR_CLOCK; var degreesPerMinute = is24HourClock ? DEGREES_OF_HOUR_HAND_PER_MINUTE_ON_A_24_HOUR_CLOCK : DEGREES_OF_HOUR_HAND_PER_MINUTE_ON_A_12_HOUR_CLOCK; return(AddXYOffset(origin, GetEndPoint(handLength, HOUR_HAND_ANGLE_AT_MIDNIGHT - (hour * degreesPerHour + minute * degreesPerMinute)))); case ClockHand.Minute: return(AddXYOffset(origin, GetEndPoint(handLength, HOUR_HAND_ANGLE_AT_MIDNIGHT - minute * DEGREES_PER_MINUTE))); case ClockHand.Second: return(AddXYOffset(origin, GetEndPoint(handLength, HOUR_HAND_ANGLE_AT_MIDNIGHT - second * DEGREES_PER_SECOND))); default: throw new ArgumentException("Invalid clock hand selection"); } }
private void runAnimation() { Rectangle outerBox = new Rectangle(50, 50, 250, 400); Rectangle innerBox = new Rectangle(60, 60, 240, 210); Circle clockFace = new Circle(150, 300, 80); RectangleF innerBoxBound = new RectangleF(60, pnlMain.Height - 210, 180, 150); string[] clockNumbers = new string[] { "12", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11" }; DrawString[] strs = new DrawString[12]; for (int k = 0; k < 12; k++) { strs[k] = new DrawString(clockNumbers[k], clockFace.getCenter().x, clockFace.getCenter().y); strs[k].translate(0, clockFace.getRadius() - 10.0f); strs[k].fixedRotate(-(Math.PI * 2.0f * (k / 12.0f)), clockFace.getCenter()); } ClockHand hourHand = new ClockHand(clockFace.getCenter().x, clockFace.getCenter().y, 50, 10); ClockHand minuteHand = new ClockHand(clockFace.getCenter().x, clockFace.getCenter().y, 70, 7.5); ClockHand secondHand = new ClockHand(clockFace.getCenter().x, clockFace.getCenter().y, 70, 5); double theta = -Math.PI / 10.0f; const float gravity = 10.0f; const float pendConst = 70.0f; Pendulum pendulum = new Pendulum(clockFace.getCenter().x, clockFace.getCenter().y, 200, 10, 20, Color.Black); pendulum.rotate(theta); float angularAcceleration = -(gravity / 200.0f) * (float)Math.Sin(theta); float angularVelocity = 0; float dT = 1.0f / 10.0f; int frameRate = (int)(dT * 1000.0f); float dS = -(float)(2 * Math.PI) / 60; float dM = -(float)(2 * Math.PI) / (60 * 60); float dH = -(float)(2 * Math.PI) / (60 * 60 * 12); float dHH = -(float)(2 * Math.PI) / 12; int hh = DateTime.Now.Hour; if (hh > 12) { hh -= 12; } int mm = DateTime.Now.Minute; int ss = DateTime.Now.Second; secondHand.rotate(ss * dS); minuteHand.rotate(mm * dS + ss * dM); hourHand.rotate(hh * dHH + (mm * ss) * dH); bool dir = true; while (mDrawing) { mGraphics.Clear(SystemColors.Control); drawPolygon(outerBox); drawPolygon(innerBox); drawCircle(clockFace); drawPoint(clockFace.getCenter()); fillPolygon(hourHand); fillPolygon(minuteHand); fillPolygon(secondHand); mGraphics.SetClip(innerBoxBound); fillPolygon(pendulum); mGraphics.ResetClip(); for (int k = 0; k < 12; k++) { drawString(strs[k]); } secondHand.rotate(dS * dT); minuteHand.rotate(dM * dT); hourHand.rotate(dH * dT); angularVelocity += angularAcceleration * dT; theta += angularVelocity * dT * pendConst; pendulum.rotate(angularVelocity * dT * pendConst); angularAcceleration = -(gravity / 200.0f) * (float)Math.Sin(theta); Console.WriteLine(angularAcceleration + " " + angularVelocity + " " + theta); Thread.Sleep(frameRate); } }