mirror of
https://gitee.com/akwkevin/aistudio.-wpf.-diagram
synced 2026-04-08 10:16:36 +08:00
画线优化基本完成
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using AIStudio.Wpf.DiagramDesigner.Geometrys;
|
||||
|
||||
namespace AIStudio.Wpf.DiagramDesigner
|
||||
{
|
||||
public static partial class PathGenerators
|
||||
{
|
||||
public static PathGeneratorResult Boundary(IDiagramViewModel _, ConnectorViewModel link, PointBase[] route, PointBase source, PointBase target)
|
||||
{
|
||||
route = ConcatRouteAndSourceAndTarget(route, source, target);
|
||||
|
||||
if (route.Length > 2)
|
||||
return CurveThroughPoints(route, link);
|
||||
|
||||
route = GetRouteWithMiddlePoints(_, link, route);
|
||||
double? sourceAngle = null;
|
||||
double? targetAngle = null;
|
||||
|
||||
sourceAngle = SourceMarkerAdjustement(route, link.ColorViewModel.LeftArrowPathStyle == ArrowPathStyle.None ? 0d : (double)link.ColorViewModel.LeftArrowSizeStyle);
|
||||
targetAngle = TargetMarkerAdjustement(route, link.ColorViewModel.RightArrowPathStyle == ArrowPathStyle.None ? 0d : (double)link.ColorViewModel.RightArrowPathStyle);
|
||||
|
||||
DoShift(route, link);
|
||||
|
||||
var paths = new string[route.Length - 1];
|
||||
for (var i = 0; i < route.Length - 1; i++)
|
||||
{
|
||||
paths[i] = FormattableString.Invariant($"M {route[i].X} {route[i].Y} L {route[i + 1].X} {route[i + 1].Y}");
|
||||
}
|
||||
|
||||
return new PathGeneratorResult(paths, sourceAngle, route[0], targetAngle, route[route.Length - 1]);
|
||||
}
|
||||
|
||||
private static PointBase[] GetRouteWithMiddlePoints(IDiagramViewModel _, ConnectorViewModel link, PointBase[] route)
|
||||
{
|
||||
var middle = GetMiddlePoints(
|
||||
link.SourceConnectorInfo.Location.Position,
|
||||
link.SourceConnectorInfo.Orientation,
|
||||
link.SinkConnectorInfo.Location.Position,
|
||||
link.IsFullConnection ? link.SinkConnectorInfoFully.Orientation : (link.SinkConnectorInfo.Location.Position.Y >= link.SourceConnectorInfo.Location.Position.Y ? ConnectorOrientation.Top : ConnectorOrientation.Bottom),
|
||||
_.GridCellSize,
|
||||
_.GridMargin);
|
||||
|
||||
middle.Insert(0, route[0]);
|
||||
middle.Add(route[1]);
|
||||
|
||||
return middle.ToArray();
|
||||
}
|
||||
|
||||
private static List<PointBase> GetMiddlePoints(PointBase source, ConnectorOrientation sourceOrientation, PointBase sink, ConnectorOrientation sinkOrientation, SizeBase gridCellSize, double gridMargin)
|
||||
{
|
||||
var points = new List<PointBase>();
|
||||
|
||||
var p0 = GetFirstSegment(source, sourceOrientation, gridCellSize, gridMargin);
|
||||
var p1 = GetFirstSegment(sink, sinkOrientation, gridCellSize, gridMargin);
|
||||
|
||||
if (p0 == p1)
|
||||
return points;
|
||||
|
||||
var p2 = new PointBase(GetNearestCross(p0.X, p1.X, gridCellSize.Width, gridMargin), GetNearestCross(p0.Y, p1.Y, gridCellSize.Height, gridMargin));
|
||||
var p3 = new PointBase(GetNearestCross(p1.X, p0.X, gridCellSize.Width, gridMargin), GetNearestCross(p1.Y, p0.Y, gridCellSize.Height, gridMargin));
|
||||
if (p2 == p3)
|
||||
{
|
||||
points.Add(p0);
|
||||
points.Add(p2);
|
||||
points.Add(p1);
|
||||
}
|
||||
else
|
||||
{
|
||||
points.Add(p0);
|
||||
points.Add(p2);
|
||||
if (!(Math.Abs(p2.X - p3.X) < 0.0001) && !(Math.Abs(p2.Y - p3.Y) < 0.0001))
|
||||
points.Add(new PointBase(p2.X, p3.Y));
|
||||
points.Add(p3);
|
||||
points.Add(p1);
|
||||
}
|
||||
|
||||
return points;
|
||||
}
|
||||
|
||||
private static PointBase GetFirstSegment(PointBase point, ConnectorOrientation orientation, SizeBase cellSize, double margin)
|
||||
{
|
||||
double x = ((int)((point.X - margin) / cellSize.Width) + 0.5) * cellSize.Width + margin;
|
||||
double y = ((int)((point.Y - margin) / cellSize.Height) + 0.5) * cellSize.Height + margin;
|
||||
if (orientation == ConnectorOrientation.Top)
|
||||
return new PointBase(x, y - 0.5 * cellSize.Height);
|
||||
else if (orientation == ConnectorOrientation.Bottom)
|
||||
return new PointBase(x, y + 0.5 * cellSize.Height);
|
||||
else if (orientation == ConnectorOrientation.Left)
|
||||
return new PointBase(x - 0.5 * cellSize.Width, y);
|
||||
else
|
||||
return new PointBase(x + 0.5 * cellSize.Width, y);
|
||||
}
|
||||
|
||||
public static double GetNearestCross(double a, double b, double cellSize, double margin)
|
||||
{
|
||||
if (Math.Abs(a - b) < 0.0001 && (int)((a - margin)/ cellSize) == ((a - margin) / cellSize))
|
||||
return a;
|
||||
else if (a < b)
|
||||
return Math.Ceiling((a - margin) / cellSize) * cellSize + margin;
|
||||
else
|
||||
return Math.Floor((a - margin) / cellSize) * cellSize + margin;
|
||||
}
|
||||
|
||||
public static PointBase SegmentMiddlePoint(PointBase p1, PointBase p2)
|
||||
{
|
||||
return new PointBase((p1.X + p2.X) / 2, (p1.Y + p2.Y) / 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user