Ich versuche schon seit einiger Zeit, eine Lösung für das Zeichnen von Pfaden zwischen Steuerelementen zu finden, die sich nicht überschneiden oder überlappen, aber es scheint, als hätte ich keine Ideen mehr. Ich habe versucht, MSAGL 1.1.6 zu verwenden und es von Grund auf zu implementieren.
Die grünen Pfade im Bild stellen die Pfade dar, die ich zeichnen möchte. Allerdings erhalte ich immer wieder Pfade wie die roten, die sich oder andere Steuerelemente schneiden oder teilweise überlappen.
Ich versuche schon seit einiger Zeit, eine Lösung für das Zeichnen von Pfaden zwischen Steuerelementen zu finden, die sich nicht überschneiden oder überlappen, aber es scheint, als hätte ich keine Ideen mehr. Ich habe versucht, MSAGL 1.1.6 zu verwenden und es von Grund auf zu implementieren. [img]https://i.sstatic.net/9nVsxDGK.png[/img]
Die grünen Pfade im Bild stellen die Pfade dar, die ich zeichnen möchte. Allerdings erhalte ich immer wieder Pfade wie die roten, die sich oder andere Steuerelemente schneiden oder teilweise überlappen. [code]private class Conn { public IIndicatorUser Src = null; public IIndicatorUser Dst = null; public Rectangle Rs; public Rectangle Rd; public GPoint SrcCenter; public GPoint DstCenter; public Side SrcSide; public Side DstSide; public int SrcIndex; public int SrcCount; public int DstIndex; public int DstCount; } private enum Side { Left, Right, Top, Bottom }
private static Side ChooseSideTowards(Rectangle rect,GPoint toward) { var center = new GPoint(rect.Left + (rect.Width / 2.0), rect.Top + (rect.Height / 2.0)); var dx = Math.Abs(toward.X - center.X); var dy = Math.Abs(toward.Y - center.Y); const double horizontalBias = 2.7; if(dx>dy*horizontalBias) return toward.X=center.Y ? Side.Bottom : Side.Top; }
private static GPoint AnchorOnSide(Rectangle r,Side side,int index,int count) { const int margin = 6; count=Math.Max(1,count); index=Math.Max(0,Math.Min(index,count-1)); if(side==Side.Left||side==Side.Right) { var x = side == Side.Left ? r.Left : r.Right; var span = Math.Max(0, r.Height - (2 * margin)); var y = r.Top + margin + (span * ((index + 1.0) / (count + 1.0))); return new GPoint(x,y); } else { var y = side == Side.Top ? r.Top : r.Bottom; var span = Math.Max(0, r.Width - (2 * margin)); var x = r.Left + margin + (span * ((index + 1.0) / (count + 1.0))); return new GPoint(x,y); } }
protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); using(var outPen = new Pen(Color.Black,3.5f)) using(var penGreen = new Pen(Color.LimeGreen,3.0f)) using(var penRed = new Pen(Color.Red,3.0f)) { if(_connections.Count==0) return;
var obstacles = new List(); var inflatedBounds = new Dictionary(); foreach(IIndicatorUser btn in Controls.OfType()) { if(btn.IsDisposed) continue; var r = new Rectangle(btn.Location, new Size(btn.Width, btn.Height)); r.Inflate(1,1); inflatedBounds[btn]=r;
var center = new GPoint(r.Left + (r.Width / 2.0), r.Top + (r.Height / 2.0)); ICurve boundary = CurveFactory.CreateRectangle(r.Width, r.Height, center); var shape = new Microsoft.Msagl.Routing.Shape(boundary); obstacles.Add(shape); }
var conns = new List(); foreach((IIndicatorUser Src, IIndicatorUser Dst) in _connections) { IIndicatorUser src = Src; IIndicatorUser dst = Dst; if(src.IsDisposed||dst.IsDisposed) continue; if(!Controls.Contains((Control)src)||!Controls.Contains((Control)dst)) continue;
Rectangle rs = inflatedBounds[src]; Rectangle rd = inflatedBounds[dst]; var srcCenter = new GPoint(rs.Left + (rs.Width / 2.0), rs.Top + (rs.Height / 2.0)); var dstCenter = new GPoint(rd.Left + (rd.Width / 2.0), rd.Top + (rd.Height / 2.0)); Side ss = ChooseSideTowards(rs, dstCenter); Side ds = ChooseSideTowards(rd, srcCenter);
var srcGroups = new Dictionary(); var dstGroups = new Dictionary(); foreach(Conn c in conns) { (IIndicatorUser Src, Side SrcSide) gs = (c.Src, c.SrcSide); (IIndicatorUser Dst, Side DstSide) gd = (c.Dst, c.DstSide); if(!srcGroups.TryGetValue(gs,out List l1)) { l1=new List(); srcGroups[gs]=l1; } if(!dstGroups.TryGetValue(gd,out List l2)) { l2=new List(); dstGroups[gd]=l2; } l1.Add(c); l2.Add(c); }
foreach(KeyValuePair kv in srcGroups) { Side side = kv.Key.Item2; List list = kv.Value; if(side==Side.Left||side==Side.Right) list.Sort((a,b) => a.DstCenter.Y.CompareTo(b.DstCenter.Y)); else list.Sort((a,b) => a.DstCenter.X.CompareTo(b.DstCenter.X));
for(var i = 0; i a.SrcCenter.Y.CompareTo(b.SrcCenter.Y)); else list.Sort((a,b) => a.SrcCenter.X.CompareTo(b.SrcCenter.X));
Ich habe ein 9 * 9-Raster in XAML, das unten rechts ein 8 * 8-Unterraster und eine Ersatzzeile und -spalte enthalten muss, um die Summen jeder Zahl im Unterraster anzuzeigen, dargestellt durch ein...
Ich habe eine Gruppe von Textbox -Steuerelementen, die ich aus Readonly ändern möchte. Mein Code -Snippet ist unten. Die Readonly -Zeile gibt Fehler Die Steuerung hat keine Definition von Readonly...
Ist es möglich, einen Liquid Glass-Effekt zu verwenden, wenn die Größe einer Sammlung von Schaltflächen geändert wird?
So etwas wie die Symbolleiste oben rechts hier? (Obwohl jede Glasanimation cool...
Ich mache eine Seite, um auf der ganzen Welt öffentliche Klaviere zu durchsuchen. Um darauf hinzuweisen, wo sich die Klaviere befinden und welche Bedingung sie in IM verwenden, verwenden sie...