読者です 読者をやめる 読者になる 読者になる

ikarosの作業場

C#でWindows Store Appsやったり、Phunいじったり

物理シミュレーターづくり:第一回WPF上でドラッグ&ドロップで図形を描画する

エアレース行ってきました。ものすごく飛行機が近い!非常に楽しかったです。

さてさて物理シミュレーターづくりですが、ある程度運動方程式の実装などを行いました。
その中で役に立ちそうなWPF上でドラッグで図形の描画についてやります

今回は円ついてやります

0.下準備

最初にマウスの移動量を管理するための変数を作っておきましょう

int[] CursorPos = new int[2];

void MouseMove(object sender, MouseEventArgs e)
{
    Point point = e.GetPosition(this);
    
    CursorPos[0] = (int)point.X;
    CursorPos[1] = (int)point.Y;
}

そしてマウスの状態は
1.On
クリックされた状態に行う処理を書く
2.Drag
ドラッグ状態で図形を描画させる処理を書く
3.Off
ドラッグ状態が解除された時の処理を書く


の3つの状態に区別して考えたいと思います。
以後マウスの状態は string型 MouseStatusという変数で管理します

string MouseStatus = null;
//マウスがクリックされたときは"On"にする
private void MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    MouseStatus = "On";
}
//マウスのドラッグ状態が解除されたら"Off"にする
private void MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
    MouseStatus = "Off";
}
//それ以外のステートについては他の関数で管理

1.円の描画
最初にクリックしたポイントを記録してMarginに突っ込み
マウスからの距離分円を拡大します

public void GenerateMaterial()
{
     //マウスがクリックしたところを保存しておくための変数
     int[] InitialPos = new int[2];
     switch (MouseStatus)
     {
         case "On":
         MouseStatus = "Drag";
         var circle = new Ellipse();
         circle.VerticalAlignment = VerticalAlignment.Center;
         circle.HorizontalAlignment = HorizontalAlignment.Center;
         circle.Margin(CursorPos[0],CursorPos[1],0,0);
         InitialPos=CursorPos;
         //ここで表示するGridなりWindowなりにコントロール(今回はcircle)を追加しないと表示されないので注意!
         //今回はCanvasAreaというCanvasに入れるコードを書きますがその辺は適時自分で似たようなコード書いてください
         CanvasArea.Children.Add(circle);
         break;

         case "Drag":
         //最初にクリックした点からのマウスカーソルとの距離を求めます
         decimal xdis = (InitialPos[0] - CursorPos[0]) * (InitialPos[0] - CursorPos[0]);
         decimal ydis = (InitialPos[1] - CursorPos[1]) * (InitialPos[1] - CursorPos[1]);
         //dis=円の半径
         int dis = (int)Math.Sqrt((long)xdis + (long)ydis);
                            
         circle.Width = pcircle.Radius * 2;
         circle.Height = pcircle.Radius * 2;
         break;

         case "Off":
         //いろいろ物理的な後処理をやりますが今回は必要ないです
     }
}

こんな感じで書けると思います

まずは円について終わり
次回は長方形について書いていきたいと思います

当サイトのソースコード及びその他の情報は個人・商用問わず自由に使っていただいてかかまいませんが、当サイトの情報が元で発生したいかなる結果・不利益については責任を負いかねますのでご了承ください