Here's how that could be done with Beziers:
private void fc_ArrowCreated(object sender, MindFusion.FlowChartX.ArrowEventArgs e)
{
ArrowCollection commonArrows = getCommonArrows(e.Arrow.Origin, e.Arrow.Destination);
PointF pt1 = e.Arrow.ControlPoints[0];
PointF pt2 = e.Arrow.ControlPoints[e.Arrow.ControlPoints.Count - 1];
if (commonArrows.Count > 1)
{
for (int c = 0; c < commonArrows.Count; ++c)
{
Arrow arrow = commonArrows[c];
arrow.Style = ArrowStyle.Bezier;
arrow.SegmentCount = 1;
PointF cp1 = new PointF(pt1.X + 1 * (pt2.X - pt1.X) / 3, pt1.Y + 1 * (pt2.Y - pt1.Y) / 3);
PointF cp2 = new PointF(pt1.X + 2 * (pt2.X - pt1.X) / 3, pt1.Y + 2 * (pt2.Y - pt1.Y) / 3);
float angle = 0, radius = 0;
cartesianToPolar(pt1, pt2, ref angle, ref radius);
int pairOffset = (c / 2 + 1) * 5;
if (commonArrows.Count % 2 == 0)
{
polarToCartesian(cp1, c % 2 == 0 ? angle - 90 : angle + 90, pairOffset, ref cp1);
polarToCartesian(cp2, c % 2 == 0 ? angle - 90 : angle + 90, pairOffset, ref cp2);
if (arrow.ControlPoints[0] == pt1)
{
arrow.ControlPoints[1] = cp1;
arrow.ControlPoints[2] = cp2;
}
else
{
arrow.ControlPoints[1] = cp2;
arrow.ControlPoints[2] = cp1;
}
arrow.UpdateFromPoints();
}
}
}
}
ArrowCollection getCommonArrows(Node box1, Node box2)
{
ArrowCollection commonArrows = new ArrowCollection();
foreach (Arrow arrow in box1.OutgoingArrows)
if (arrow.Destination == box2)
commonArrows.Add(arrow);
foreach (Arrow arrow in box1.IncomingArrows)
if (arrow.Origin == box2)
commonArrows.Add(arrow);
return commonArrows;
}
void polarToCartesian(PointF coordCenter, float a, float r, ref PointF cartesian)
{
if (r == 0)
{
cartesian = coordCenter;
return;
}
cartesian.X = (float)(coordCenter.X + Math.Cos(a * Math.PI / 180) * r);
cartesian.Y = (float)(coordCenter.Y - Math.Sin(a * Math.PI / 180) * r);
}
void cartesianToPolar(PointF coordCenter, PointF cartesian, ref float a, ref float r)
{
if (coordCenter == cartesian)
{
a = 0;
r = 0;
return;
}
float dx = cartesian.X - coordCenter.X;
float dy = cartesian.Y - coordCenter.Y;
r = (float)(Math.Sqrt(Math.Pow(dx, 2) + Math.Pow(dy, 2)));
a = (float)(Math.Atan(-dy / dx) * 180 / Math.PI);
if (dx < 0)
a += 180;
}
Now if anyone can think up a nice property name, we might add this a standard feature in the next version of the control