|
針を動かす実装は次の通りです。
Form_Loaded イベントを追加します。
注意: フォームをダブルクリックして、Windows_Loaded イベントを追加すると、Windows1.xaml.cs に
追加されます。しかし、ZAM 3D から Visual Studio のプロジェクトをExport
するたびにファイルがオーバーライトされてしまいます。そこで、時計を動かす部分はWindows1 の Partial Class
のファイルを追加して、そこに実装するとオーバーライトされずに済みます。
class1.cs というファイルを追加して、Window1
のパーシャルクラスとして、フォームがロードされたときにタイマーを追加してあげます。
注意: WPF ではツールボックスにタイマーコントロールがないので、System.Windows.Forms.Timer
を参照設定に追加します。手書きで追加します。
タイマーは、1秒に1回TickEventHandler を呼び出します。TickEventHandler では、各針の角度をGetAngle()
で求めて、各針のオブジェクトに、時間に対応する回転を加えてあげます。
このとき、各針のオブジェクトは、ZAM3D で、SecHand、MinHand、HourHand
と名前を付けましたが、自動生成される際にそれぞれ SecHandOR37
のように、名前が変更されており、適切に修正しないといけません。ただし、Visual Studio
のインテリセンス機能で、比較的簡単に名前を見つけることができます。このため、オブジェクトにわかりやすい名前を付けることが重要です。
注意: XY座標でいうと右方向が0度です。このため、針の角度は90度左に回転させています。また、座標系は左手系であり、AxisAngleRotation3DのVector
は Z方向ベクターはマイナスにする必要があります。
注意: どうやって回転されたら良いのかと思ってあれこれ調べてみたところ、Transformマトリックスが4つの配列に回転成分、トランスレート成分など、自動的に構成しているようです。針の回転には、Transform
マトリックスのChildren[2]
を置き換えていますが、もうちょっとましな方法があるかもしれません。このあたりの座標変換は厄介ですね。
using System;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Media.Media3D;
namespace clock
{
public partial class Window1 : System.Windows.Window
{
System.Windows.Forms.Timer timer = new Timer();
private void Window_Loaded(object sender, RoutedEventArgs e)
{
this.ZAM3DViewport3D.Visibility = Visibility.Hidden;
TickEventHander(null, null);
this.ZAM3DViewport3D.Visibility = Visibility.Visible;
timer.Interval = 1000;
timer.Tick += new EventHandler(TickEventHander);
timer.Enabled = true;
}
private void GetAngle(ref double hourAng, ref double minAng, ref double secAng)
{
DateTime time = DateTime.Now;
secAng = 360 * time.Second / 60.0 - 90f;
minAng = 360 * (time.Minute + time.Second / 60.0) / 60.0 - 90f;
hourAng = 360 * (time.Hour + time.Minute / 60.0) / 12.0 - 90f;
}
private void TickEventHander(object obj, EventArgs arg)
{
double hourAng = 0f, minAng = 0f, secAng = 0f;
GetAngle(ref hourAng, ref minAng, ref secAng);
Transform3DGroup tg = (Transform3DGroup)this.SecHandOR37.Transform;
tg.Children[2] = new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 0, -1), secAng));
this.SecHandOR37.Transform = tg;
Transform3DGroup tgMin = (Transform3DGroup)this.MinHandOR27.Transform;
tgMin.Children[2] = new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 0, -1), minAng));
this.MinHandOR27.Transform = tgMin;
Transform3DGroup tgHour = (Transform3DGroup)this.HourHandOR32.Transform;
tgHour.Children[2] = new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 0, -1), hourAng));
this.HourHandOR32.Transform = tgHour;
}
}
}
|