private void Draw(TEdge edge, D2dBrush brush, D2dGraphics g) { Vec2F startPoint = new Vec2F(); Vec2F endPoint = new Vec2F(); CircleF c = new CircleF(); bool moreThan180 = false; Vec2F endTangent; Vec2F textPoint; int route = edge.FromRoute.Index; if (GetEdgeGeometry(edge, route, ref startPoint, ref endPoint, ref c, ref moreThan180)) { g.DrawLine(new PointF(startPoint.X, startPoint.Y), new PointF(endPoint.X, endPoint.Y), brush, m_theme.StrokeWidth); endTangent = endPoint - startPoint; textPoint = (endPoint + startPoint) * 0.5f; } else { // prepare to draw arc RectangleF rect = new RectangleF(c.Center.X - c.Radius, c.Center.Y - c.Radius, 2 * c.Radius, 2 * c.Radius); double angle1 = Math.Atan2(startPoint.Y - c.Center.Y, startPoint.X - c.Center.X); double angle2 = Math.Atan2(endPoint.Y - c.Center.Y, endPoint.X - c.Center.X); const double twoPi = 2 * Math.PI; // swap so we always go clockwise if (angle1 > angle2) { double temp = angle1; angle1 = angle2; angle2 = temp; } double startAngle = angle1; double sweepAngle = angle2 - angle1; if (moreThan180) { if (sweepAngle < Math.PI) { sweepAngle = -(twoPi - sweepAngle); } } else { if (sweepAngle > Math.PI) { sweepAngle = -(twoPi - sweepAngle); } } const double RadiansToDegrees = 360 / twoPi; startAngle *= RadiansToDegrees; sweepAngle *= RadiansToDegrees; g.DrawArc((D2dEllipse)rect, brush, (float)startAngle, (float)sweepAngle, m_theme.StrokeWidth); endTangent = endPoint - c.Center; endTangent = endTangent.Perp; textPoint = (endPoint + startPoint) * 0.5f; CircleF.Project(textPoint, c, ref textPoint); if (moreThan180) { textPoint -= 2 * (textPoint - c.Center); } } DrawArrow(endPoint, endTangent, brush, g); string label = edge.Label; if (!string.IsNullOrEmpty(label)) { RectangleF textBox = new RectangleF(textPoint.X - 512, textPoint.Y, 1024, m_theme.TextFormat.FontHeight); g.DrawText(label, m_theme.TextFormat, textBox, m_theme.TextBrush); } }