/// <summary> /// 始点がfromで終点がtoのエッジを戻す。 /// </summary> private Edge FindEdge(PointInf from, PointInf to, FEOption opt) { switch (opt) { case FEOption.SamePointIdx: foreach (var e in mEdgeList) { if (e.fromPointIdx == from.Idx && e.toPointIdx == to.Idx) { return(e); } } break; case FEOption.SamePosition: { foreach (var e in mEdgeList) { var e1 = mPP.FindPointByIdx(e.fromPointIdx, PointProc.FindPointMode.FindAll); if (WWVectorD2.Distance(e1.xy, from.xy) < 1) { var e2 = mPP.FindPointByIdx(e.toPointIdx, PointProc.FindPointMode.FindAll); if (WWVectorD2.Distance(e2.xy, to.xy) < 1) { return(e); } } } } break; } return(null); }
/// <returns>既存の点と当たったら既存点のPointInfを戻す。</returns> public PointInf TestHit(WWVectorD2 xy, double threshold) { foreach (var p in mPointList) { if (WWVectorD2.Distance(p.xy, xy) < threshold) { return(p); } } return(null); }
/// <summary> /// リストに点xyが存在するか。 /// </summary> private bool PointExists(List <PointInf> points, WWVectorD2 xy) { foreach (var p in points) { if (WWVectorD2.Distance(p.xy, xy) < 1) { return(true); } } return(false); }
/// <summary> /// マウス移動イベントハンドラー。 /// </summary> private void mCanvas_MouseMove(object sender, MouseEventArgs e) { var posExact = e.GetPosition(mCanvas); if (mPrevPos != null && WWVectorD2.Distance(mPrevPos, new WWVectorD2(posExact.X, posExact.Y)) < 1.0) { // マウス移動量が小さい場合、何もしない。 return; } mPrevPos = new WWVectorD2(posExact.X, posExact.Y); CanvasMouseMove(e); }
/// <summary> /// 始点か終点がposのエッジを戻す。 /// </summary> private Edge FindEdge(WWVectorD2 pos) { foreach (var e in mEdgeList) { var p1 = mPP.FindPointByIdx(e.fromPointIdx, PointProc.FindPointMode.FindAll); var p2 = mPP.FindPointByIdx(e.toPointIdx, PointProc.FindPointMode.FindAll); if (WWVectorD2.Distance(pos, p1.xy) < 1) { return(e); } if (WWVectorD2.Distance(pos, p2.xy) < 1) { return(e); } } return(null); }
private void DeletePointEdgeMouseMove(WWVectorD2 pos) { // 選択状態色を一旦通常色に戻します。 DeletePointEdgeCancel(); var e = mEP.FindNearestEdge(pos); var p = mPP.TestHit(pos, mDP.mPointSz); if (e != null) { if (p != null) { // 近いほうがヒット。 if (mEP.EdgeDistanceFromPos(e, pos, 1.0, PointProc.FindPointMode.FindFromPointList) < WWVectorD2.Distance(p.xy, pos)) { // eのほうが近い。 mEP.EdgeChangeColor(e, mDP.mBrightBrush); mEP.mTmpEdge = e; } else { // pのほうが近い。 mPP.PointChangeColor(p, mDP.mBrightBrush); mPP.mFromPoint = p; } } else { // エッジ。 mEP.EdgeChangeColor(e, mDP.mBrightBrush); mEP.mTmpEdge = e; } } else if (p != null) { // p。 mPP.PointChangeColor(p, mDP.mBrightBrush); mPP.mFromPoint = p; } }
// ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ // イベント。 public void MouseMoveUpdateTmpPoint(WWVectorD2 pos) { if (mFromPoint == null) { // 始点が無い。 Console.WriteLine("MMP FP none"); return; } // 始点有り。 Console.WriteLine("MMP ({0:0.0} {0:0.0})", pos.X, pos.Y); var toPoint = TestHit(pos, mDP.mPointSz); if (toPoint == null) { // 始点が存在し、マウスポインタ位置に確定の終点が無い。 if (mToPoint != null && WWVectorD2.Distance(mToPoint.xy, pos) < 1) { // マウスポインタ位置に仮の終点mToPointが存在。 Console.WriteLine("MMP already toPoint"); } else { // 仮の終点位置が異なるので作り直す。 PointDrawableRemove(mToPoint); mToPoint = null; mToPoint = NewPoint(pos, mDP.mBrightBrush); Console.WriteLine("MMP create toPoint"); } } else { // マウスポインタ位置に確定の終点が存在する。 // 仮の終点は不要。 PointDrawableRemove(mToPoint); mToPoint = null; } }
/// <summary> /// 削除モード:点またはエッジを消す /// </summary> private void DeletePointEdgeLeftClicked(WWVectorD2 pos) { DeletePointEdgeCancel(); var e = mEP.FindNearestEdge(pos); var p = mPP.TestHit(pos, mDP.mPointSz); if (e != null) { if (p != null) { // 近いほうがヒット。 if (mEP.EdgeDistanceFromPos(e, pos, 1.0, PointProc.FindPointMode.FindFromPointList) < WWVectorD2.Distance(p.xy, pos)) { // eのほうが近い。 DeleteEdge(e); } else { // pのほうが近い。 DeletePoint(p); } } else { // エッジ。 DeleteEdge(e); } } else if (p != null) { // p。 DeletePoint(p); } }
/// <summary> /// 始点がidxFromで終点がidxToのエッジを戻す。 /// </summary> public Edge FindEdge(int idxFrom, int idxTo, FEOption opt) { switch (opt) { case FEOption.SamePointIdx: foreach (var e in mEdgeList) { if (e.fromPointIdx == idxFrom && e.toPointIdx == idxTo) { return(e); } } break; case FEOption.SamePosition: { var p1 = mPP.FindPointByIdx(idxFrom, PointProc.FindPointMode.FindAll); var p2 = mPP.FindPointByIdx(idxTo, PointProc.FindPointMode.FindAll); foreach (var e in mEdgeList) { var e1 = mPP.FindPointByIdx(e.fromPointIdx, PointProc.FindPointMode.FindAll); if (WWVectorD2.Distance(e1.xy, p1.xy) < 1) { var e2 = mPP.FindPointByIdx(e.toPointIdx, PointProc.FindPointMode.FindAll); if (WWVectorD2.Distance(e2.xy, p2.xy) < 1) { return(e); } } } } break; } return(null); }
/// <summary> /// 始点決定状態で左クリック:終点を決定する。始点から終点に向かうエッジを追加。終点が新たに始点となる。 /// 既存点を左クリックしたとき、点の追加を行わずエッジを追加する。 /// </summary> private void PointAddLeftClicked(WWVectorD2 pos) { if (pos.X < 0 || mCanvas.ActualWidth <= pos.X || pos.Y < 0 || mCanvas.ActualHeight <= pos.Y) { // Canvas外のクリック。 return; } // 始点決定状態。 System.Diagnostics.Debug.Assert(mPP.mFromPoint != null); // 始点決定状態で左クリック:終点を決定する。始点から終点に向かうエッジを追加。終点が新たに始点となる。 // 既存点を左クリックしたとき、点の追加を行わずエッジを追加する。 var ca = new CommandAtomic(); // クリック地点に確定点が存在するか? var pInf = mPP.TestHit(pos, mDP.mPointSz); if (pInf == null) { // クリックした場所には確定点は未だ無い。 // 仮の終点を削除。 TmpDrawablesRemove((int)TmpDrawablesRemoveOpt.RemoveToPoint); mPP.mToPoint = null; // 確定の終点を追加する。 pInf = new PointInf(pos); var cmd = new Command(Command.CommandType.AddPoint, pInf, null); CommandDo(cmd); ca.Add(cmd); } else if (WWVectorD2.Distance(pInf.xy, mPP.mFromPoint.xy) < 0.5) { // クリックした点が、始点と同じ点。 // 特に何もしないで戻る。 return; } // クリック地点に始点とは異なる終点pInfが存在する状態。 // 始点の色を通常色にする。 mPP.PointChangeColor(mPP.mFromPoint, mDP.mBrush); var edge = mEP.FindEdge(mPP.mFromPoint.Idx, pInf.Idx, EdgeProc.FEOption.SamePosition); if (edge == null) { // 始点→終点のエッジが無いので追加。 var cmd = new Command(Command.CommandType.AddEdge, null, new Edge(mPP.mFromPoint.Idx, pInf.Idx)); CommandDo(cmd); ca.Add(cmd); } // コマンドが集まったのでアンドゥーリストに足す。 if (0 < ca.commandList.Count) { AddCmdToUndoList(ca); } // クリックした点を新たな始点にする。 mPP.mFromPoint = pInf; mPP.PointChangeColor(mPP.mFromPoint, mDP.mBrightBrush); }
/// <summary> /// 始点が未決定の状態でマウスがホバーしている。 /// </summary> public void SetFirstPointMouseMove(WWVectorD2 pos) { var point = TestHit(pos, mDP.mPointSz); if (mFromPoint == null) { // 始点が無い。 Console.WriteLine("SFPMM FP none"); if (point == null) { // 始点mFromPointが無く、マウスホバー位置に確定の点も無い。 // マウスポインタ位置に仮の始点を作る。 mFromPoint = NewPoint(pos, mDP.mBrightBrush); Console.WriteLine("SFPMM create fromPoint"); return; } // 始点が無く、マウスホバー位置に確定の点が有る。 // 確定の点の色をハイライト色に変更。 // mFromPointをセットする。 mFromPoint = point; PointChangeColor(mFromPoint, mDP.mBrightBrush); return; } // 始点mFromPoint有り。 Console.WriteLine("SFPMM ({0:0.0} {0:0.0})", pos.X, pos.Y); if (point == null) { // 始点mFromPointが存在し、マウスポインタ位置に確定の点が無い。 if (WWVectorD2.Distance(mFromPoint.xy, pos) < 1) { // マウスポインタ位置に仮の始点mFromPointが存在。 Console.WriteLine("SFPMM no need to change tmp FromPoint"); } else { // 仮の始点位置が異なるので作り直す。 TmpFromPointRemove(); mFromPoint = NewPoint(pos, mDP.mBrightBrush); Console.WriteLine("SFPMM create FromPoint"); } } else { // 始点mFromPointが存在し、マウスホバー位置に確定の始点pointが存在する。 Console.WriteLine("SFPMM remove tmp drawable and set point"); // 始点mFromPointが仮の点のときは消す。 TmpFromPointRemove(); // マウスホバー位置の確定の点をmFromPointにセットする。 // 確定の点の色をハイライト色に変更。 // mFromPointをセットする。 mFromPoint = point; PointChangeColor(mFromPoint, mDP.mBrightBrush); return; } }
// ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ // イベント。 public void MouseMoveUpdateTmpEdge(WWVectorD2 pos) { if (mPP.mFromPoint == null) { // 始点が無い。 Console.WriteLine("MME FP none"); return; } // 始点mFromPoint有り。 Console.WriteLine("MME ({0:0.0} {0:0.0})", pos.X, pos.Y); // TmpEdgeの始点p1と終点p2 PointInf p1 = null; PointInf p2 = null; if (mTmpEdge != null) { p1 = mPP.FindPointByIdx(mTmpEdge.fromPointIdx, PointProc.FindPointMode.FindAll); p2 = mPP.FindPointByIdx(mTmpEdge.toPointIdx, PointProc.FindPointMode.FindAll); } // マウスポインタ位置に確定の終点toPointがあるか。 var toPoint = mPP.TestHit(pos, mDP.mPointSz); if (toPoint == null) { // マウスポインタ位置に確定の終点が無い。 // この場合、確定のエッジは無い。 if (mPP.mToPoint != null && WWVectorD2.Distance(mPP.mToPoint.xy, pos) < 1) { // マウスポインタ位置に仮の終点mToPointが存在する。 Console.WriteLine("MME already toPoint"); if (p1 == mPP.mFromPoint && p2 == mPP.mToPoint) { // mFromPoint → mToPoint // 仮のエッジが既に引かれている。 return; } // mFromPoint → mToPointのエッジを引く必要がある。 p1 = mPP.mFromPoint; p2 = mPP.mToPoint; } else { // マウスポインタ位置に確定の終点も仮の終点も無い。 // 画面外にマウスが行った場合? // 仮のエッジがあれば消す。 EdgeDrawablesRemove(mTmpEdge); return; } } else { // 確定の終点toPointがある。 if (null != FindEdge(mPP.mFromPoint.Idx, toPoint.Idx, FEOption.SamePosition)) { // 確定のエッジが既に引かれている。 // 仮のエッジがあれば消す。 EdgeDrawablesRemove(mTmpEdge); return; } if (p1 == mPP.mFromPoint && p2 == toPoint) { // mFromPoint → toPoint // 仮のエッジが既に引かれている。 return; } // mFromPoint → toPointのエッジを引く必要がある。 p1 = mPP.mFromPoint; p2 = toPoint; } // Edgeを作り直す。 EdgeDrawablesRemove(mTmpEdge); mTmpEdge = NewEdge(p1, p2, mDP.mBrightBrush); Console.WriteLine("MME created edge"); return; }