/// <summary> /// 始点から終点に向かうエッジを作り、キャンバスに登録。 /// 一時的エッジ用。 /// エッジ確定追加の場合 new Edge(null, null, fromIdx, toIdx)をCommandDoする。 /// </summary> private Edge NewEdge(PointInf from, PointInf to, Brush brush) { var edge = new Edge(from.Idx, to.Idx); EdgeDrawablesCreate(edge, brush); return(edge); }
/// <summary> /// アースされている点。 /// idxに-1が指定されていたらどこもアースしない。 /// </summary> public PointInf EarthedPoint() { PointInf p = null; int idx = 0; if (!int.TryParse(mTextBoxEarthPointIdx.Text, out idx)) { // 文字ではない物が入力された。 MessageBox.Show( string.Format("Error: Earth Point idx parse error.")); } else { if (idx == -1) { // pIdx == -1が指定された:意図的にアース無し。 } else { p = mPP.FindPointByIdx(idx, PointProc.FindPointMode.FindFromPointList); if (p == null) { // 指定された番号のpが存在しない。 MessageBox.Show( string.Format("Error: Earth Point idx specified not found. idx={0}", idx)); } } } mPP.UpdateEarthedPoint(p); return(p); }
/// <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); }
/// <summary> /// 点の描画物をキャンバスから削除し、点の描画物自体も削除。 /// </summary> public void PointDrawableRemove(PointInf p) { if (p == null) { return; } if (p.tbIdx != null) { mDP.mCanvas.Children.Remove(p.tbIdx); p.tbIdx = null; } if (p.circle != null) { mDP.mCanvas.Children.Remove(p.circle); p.circle = null; } if (p.earthCircle != null) { mDP.mCanvas.Children.Remove(p.earthCircle); p.earthCircle = null; } Console.WriteLine("Point drawable removed"); }
/// <summary> /// 始点未決定状態で左クリック:始点を決定する。 /// </summary> private void SetFirstPointLeftClicked(WWVectorD2 pos) { mPP.TmpFromPointRemove(); // クリック地点に確定の点を作る。 var pInf = mPP.TestHit(pos, mDP.mPointSz); if (pInf == null) { // クリックした場所には点は未だ無い。 // 確定の始点を追加する → pInf。 pInf = new PointInf(pos); var cmd = new Command(Command.CommandType.AddPoint, pInf, null); CommandDo(cmd); AddCmdToUndoList(new CommandAtomic(cmd)); mPP.mFromPoint = pInf; } else { // クリック地点に確定の点あり。 mPP.mFromPoint = pInf; } // エッジ追加モードに遷移。 mMode = Mode.ModeAddEdge; UpdateDescription(); }
/// <summary> /// 新しいPointInfを作り、キャンバスに追加。 /// 一時的な点用。 /// </summary> public PointInf NewPoint(WWVectorD2 pos, Brush brush) { var pInf = new PointInf(pos); PointDrawableCreate(pInf, brush); return(pInf); }
/// <summary> /// 点と、点につながるエッジをすべて消す。 /// </summary> private void DeletePoint(PointInf p) { var ca = new CommandAtomic(); // 点番号idxに接続しているエッジをすべて消す。 foreach (var e in mEP.mEdgeList) { if (e.fromPointIdx == p.Idx || e.toPointIdx == p.Idx) { var cmd = new Command(Command.CommandType.DeleteEdge, null, e); ca.Add(cmd); } } { // 点idxを消す。 var cmd = new Command(Command.CommandType.DeletePoint, p, null); ca.Add(cmd); } CommandAtomicDo(ca); AddCmdToUndoList(ca); UpdateGraphStatus(); }
/// <summary> /// 点の係数が変更された。 /// </summary> public void PointParamChanged(PointInf pi, double newF) { pi.tbIdx.Text = CreateDescriptionText(pi, newF); // 表示位置を調整する。 pi.tbIdx.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); var tbWH = pi.tbIdx.DesiredSize; Canvas.SetLeft(pi.tbIdx, pi.xy.X - tbWH.Width / 2); Canvas.SetTop(pi.tbIdx, pi.xy.Y - tbWH.Height / 2); }
private string CreateDescriptionText(PointInf p, double f) { var sb = new StringBuilder(); sb.AppendFormat("p{0}", p.Idx); if (f != 0) { sb.AppendFormat("\nf={0}", f); } return(sb.ToString()); }
public void PointRemoved(PointInf p) { foreach (var item in mPointCollection) { if (item.p == p) { mPointCollection.Remove(item); return; } } }
/// <summary> /// 点pの描画色を変更。描画物がないときは作ってキャンバスに追加。 /// </summary> public void PointChangeColor(PointInf p, Brush brush) { if (p.circle == null) { PointDrawableCreate(p, brush); return; } // 点描画物有り。色を変える。 p.circle.Fill = brush; p.tbIdx.Background = brush; }
/// <summary> /// 点の描画物を作り、キャンバスに追加する。 /// </summary> public void PointDrawableCreate(PointInf pi, Brush brush) { { System.Diagnostics.Debug.Assert(pi.circle == null); pi.circle = new Ellipse(); pi.circle.Width = mDP.mPointSz; pi.circle.Height = mDP.mPointSz; pi.circle.Fill = brush; Canvas.SetLeft(pi.circle, pi.xy.X - mDP.mPointSz / 2); Canvas.SetTop(pi.circle, pi.xy.Y - mDP.mPointSz / 2); mDP.mCanvas.Children.Add(pi.circle); } if (pi.Earthed) { System.Diagnostics.Debug.Assert(pi.earthCircle == null); int margin = 3; pi.earthCircle = new Ellipse(); pi.earthCircle.Width = mDP.mPointSz + margin * 2; pi.earthCircle.Height = mDP.mPointSz + margin * 2; pi.earthCircle.Stroke = brush; Canvas.SetLeft(pi.earthCircle, pi.xy.X - mDP.mPointSz / 2 - margin); Canvas.SetTop(pi.earthCircle, pi.xy.Y - mDP.mPointSz / 2 - margin); mDP.mCanvas.Children.Add(pi.earthCircle); } { pi.tbIdx = new TextBlock(); pi.tbIdx.Text = CreateDescriptionText(pi, pi.F); pi.tbIdx.FontSize = mDP.mPointFontSz; pi.tbIdx.Foreground = mDP.mPointTextFgBrush; pi.tbIdx.Background = brush; pi.tbIdx.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); var tbWH = pi.tbIdx.DesiredSize; Canvas.SetLeft(pi.tbIdx, pi.xy.X - tbWH.Width / 2); Canvas.SetTop(pi.tbIdx, pi.xy.Y - tbWH.Height / 2); mDP.mCanvas.Children.Add(pi.tbIdx); } Console.WriteLine("Point drawable added"); }
public void UpdateEarthedPoint(PointInf ep) { foreach (var p in mPointList) { if (p == ep) { p.Earthed = true; } else { p.Earthed = false; } } RedrawPoints(); }
/// <summary> /// FromPointがTmp点のとき消す。 /// FromPointが確定点のとき確定色にする。 /// </summary> public void TmpFromPointRemove() { if (mFromPoint != null) { if (PointExists(mPointList, mFromPoint.xy)) { // mFromPoint地点に確定の点がある。 // 色を確定の色に変更。 PointChangeColor(mFromPoint, mDP.mBrush); } else { // mFromPointは仮の点で、確定の点は無い。 PointDrawableRemove(mFromPoint); } mFromPoint = null; } }
// ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ // イベント。 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> public void RedrawEdge(PointInf removedPoint, PointInf addedPoint) { foreach (var e in mEdgeList) { PointInf p1 = null; if (e.fromPointIdx == removedPoint.Idx) { p1 = addedPoint; } else { p1 = mPP.FindPointByIdx(e.fromPointIdx, PointProc.FindPointMode.FindAll); } PointInf p2 = null; if (e.toPointIdx == removedPoint.Idx) { p2 = addedPoint; } else { p2 = mPP.FindPointByIdx(e.toPointIdx, PointProc.FindPointMode.FindAll); } mDP.mCanvas.Children.Remove(e.line); e.line = null; mDP.mCanvas.Children.Remove(e.arrow); e.arrow = null; var l = DrawUtil.NewLine(p1.xy, p2.xy, mDP.mBrush); e.line = l; var poly = NewArrowPoly(p1.xy, p2.xy, mDP.mBrush); e.arrow = poly; mDP.mCanvas.Children.Add(l); mDP.mCanvas.Children.Add(poly); } }
/// <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> /// mToPointを消す。 /// mToPointは常に仮の点。 /// </summary> public void TmpToPointRemove() { PointDrawableRemove(mToPoint); mToPoint = null; }
// ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ // イベント。 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; }
/// <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; } }
/// <summary> /// 点の追加、削除コマンド。 /// CommandDo()で実行、CommandUndo()でアンドゥーする。 /// AddPoint: pは、描画物=nullで、xyを指定して作成し渡す。e=null。 /// AddEdge: p=null、eは描画物=nullで始点番号、終点番号を指定して作成し渡す。 /// </summary> public Command(CommandType c, PointInf p, Edge e) { cmd = c; point = p; edge = e; }
public PointProperty(PointInf aP) { p = aP; }
public void PointAdded(PointInf p) { mPointCollection.Add(new PointProperty(p)); }