Zeichnen von Pfaden zwischen Steuerelementen, die sich nicht schneiden und nicht überlappenC#

Ein Treffpunkt für C#-Programmierer
Anonymous
 Zeichnen von Pfaden zwischen Steuerelementen, die sich nicht schneiden und nicht überlappen

Post by Anonymous »

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.
Image

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: Select all

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);

conns.Add(new Conn {
Src=src,
Dst=dst,
Rs=rs,
Rd=rd,
SrcCenter=srcCenter,
DstCenter=dstCenter,
SrcSide=ss,
DstSide=ds,
});
}

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));

for(var i = 0; i

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post