using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Media; using AIStudio.Wpf.DiagramDesigner.Geometrys; using AIStudio.Wpf.DiagramDesigner.Models; namespace AIStudio.Wpf.DiagramDesigner { public class BlockConnectorInfo : FullyCreatedConnectorInfo { public BlockConnectorInfo(DesignerItemViewModelBase dataItem, ConnectorOrientation orientation) : this(null, dataItem, orientation) { } public BlockConnectorInfo(IDiagramViewModel root, DesignerItemViewModelBase dataItem, ConnectorOrientation orientation) : base(root, dataItem, orientation) { if (Orientation == ConnectorOrientation.Left || Orientation == ConnectorOrientation.Right) { ConnectorWidth = 4; ConnectorHeight = double.NaN; } else if (Orientation == ConnectorOrientation.Top || Orientation == ConnectorOrientation.Bottom) { ConnectorWidth = double.NaN; ConnectorHeight = 4; } } public BlockConnectorInfo(IDiagramViewModel root, DesignerItemViewModelBase dataItem, SerializableItem serializableItem, string serializableType) : base(root, dataItem, serializableItem, serializableType) { } public BlockConnectorInfo(IDiagramViewModel root, DesignerItemViewModelBase dataItem, SelectableItemBase designer) : base(root, dataItem, designer) { } protected override void InitNew() { base.InitNew(); ColorViewModel.LineColor.Color = Colors.Transparent; ColorViewModel.FillColor.Color = Colors.Transparent; } public new BlockDesignerItemViewModel DataItem { get { return Parent as BlockDesignerItemViewModel; } } public override bool CanAttachTo(ConnectorInfoBase port) { if (port is BlockConnectorInfo blockConnectorInfo) { return port != this && !port.IsReadOnly && DataItem != blockConnectorInfo.DataItem; } else { return false; } } public PointBase LeftPosition { get { return new PointBase(MiddlePosition.X - DataItem.GetItemWidth() / 2, MiddlePosition.Y); } } public PointBase RightPosition { get { return new PointBase(MiddlePosition.X + DataItem.GetItemWidth() / 2, MiddlePosition.Y); } } public double DistanceTo(BlockConnectorInfo port) { PointBase p0 = port.LeftPosition; PointBase p1 = port.RightPosition; PointBase p2 = LeftPosition; PointBase p3 = RightPosition; var distance1 = DistanceTo(p0, p1, p2); var distance2 = DistanceTo(p0, p1, p3); var distance3 = DistanceTo(p2, p3, p0); var distance4 = DistanceTo(p2, p3, p1); return Math.Min(Math.Min(distance1, distance2), Math.Min(distance3, distance4)); } double DistanceTo(PointBase A, PointBase B, PointBase P) //点P到线段AB的最短距离 { double r = ((P.X - A.X) * (B.X - A.X) + (P.Y - A.Y) * (B.Y - A.Y)) / DistanceToPow(A, B); if (r <= 0) return Math.Sqrt(DistanceToPow(A, P)); else if (r >= 1) return Math.Sqrt(DistanceToPow(B, P)); else { double AC = r * Math.Sqrt(DistanceToPow(A, B)); return Math.Sqrt(DistanceToPow(A, P) - AC * AC); } } double DistanceToPow(PointBase a, PointBase b) //点a、b距离的平方 { return (a.X - b.X) * (a.X - b.X) + (a.Y - b.Y) * (a.Y - b.Y); } } }