private void drawLinesFromModelsToAttachmentCenter(LinkType linkType, Vec attachmentCenter, Canvas c) { var filterLinkViewModel = DataContext as FilterLinkViewModel; foreach ( var incomingModel in filterLinkViewModel.FromOperationViewModels.Where( vvm => vvm.OperationModel is IFilterProviderOperationModel).Where( vvm => filterLinkViewModel.FilterLinkModels.Where(lvm => lvm.LinkType == linkType) .Select(lvm => lvm.FromOperationModel) .Contains(vvm.OperationModel as IFilterProviderOperationModel))) { var incomingCenter = new Vec( (incomingModel.Position + incomingModel.Size / 2.0).X, (incomingModel.Position + incomingModel.Size / 2.0).Y); var incomingRct = new Rct(incomingModel.Position, new Vec(incomingModel.Size.X, incomingModel.Size.Y)); var isInverted = filterLinkViewModel.FilterLinkModels.Where(lm => lm.IsInverted) .Select(lm => lm.FromOperationModel) .Contains(incomingModel.OperationModel as IFilterProviderOperationModel); var inter = incomingRct.GetLineString() .Intersection( new Windows.Foundation.Point[] { attachmentCenter.GetCoord().GetPt(), incomingCenter.GetCoord().GetPt() } .GetLineString()); var incomingStart = new Vec(); if (inter.IsEmpty) { incomingStart = incomingCenter; } else { incomingStart = new Vec(inter.Centroid.X, inter.Centroid.Y); } var distanceVec = attachmentCenter - incomingStart; if (distanceVec.Length > 0) { var cutOff = distanceVec.Normalized() * (distanceVec.Length - _attachmentRectHalfSize); /* var l1 = new Line(); * l1.X1 = incomingStart.X; * l1.Y1 = incomingStart.Y; * l1.X2 = incomingStart.X + cutOff.X; * l1.Y2 = incomingStart.Y + cutOff.Y; * if ( * filterLinkViewModel.FilterLinkModels.Where(lm => lm.IsInverted) * .Select(lm => lm.FromOperationModel) * .Contains(incomingModel.OperationModel as IFilterProviderOperationModel)) * l1.StrokeDashArray = new DoubleCollection {2}; * l1.Stroke = new SolidColorBrush(Colors.Red); * l1.StrokeThickness = 2; * c.Children.Add(l1);*/ var n = distanceVec.Perp().Normalized(); var trianglePos = distanceVec.Normalized() * (distanceVec.Length * 0.3) + incomingStart; var start = incomingStart + distanceVec.Normalized() * 4; var end = incomingStart + cutOff; var thinkness = 4; var arrowWidth = 8; var arrowLength = 20; var poly = new Polygon(); if (!isInverted) { poly.Points.Add((start - (n * thinkness / 2.0)).GetWindowsPoint()); poly.Points.Add((start + (n * thinkness / 2.0)).GetWindowsPoint()); } poly.Points.Add((trianglePos + (n * thinkness / 2.0)).GetWindowsPoint()); poly.Points.Add((trianglePos + (n * ((thinkness / 2.0) + arrowWidth))).GetWindowsPoint()); poly.Points.Add((trianglePos + (distanceVec.Normalized() * arrowLength) + (n * ((thinkness / 2.0)))).GetWindowsPoint()); if (!isInverted) { poly.Points.Add((end + (n * thinkness / 2.0)).GetWindowsPoint()); poly.Points.Add((end - (n * thinkness / 2.0)).GetWindowsPoint()); } poly.Points.Add((trianglePos + (distanceVec.Normalized() * arrowLength) - (n * ((thinkness / 2.0)))).GetWindowsPoint()); poly.Points.Add((trianglePos - (n * ((thinkness / 2.0) + arrowWidth))).GetWindowsPoint()); poly.Points.Add((trianglePos - (n * thinkness / 2.0)).GetWindowsPoint()); if (!isInverted) { poly.Points.Add((start - (n * thinkness / 2.0)).GetWindowsPoint()); } /*poly.Points.Add(new Windows.Foundation.Point(trianglePos.X + n.X*8, trianglePos.Y + n.Y*8)); * poly.Points.Add(new Windows.Foundation.Point(trianglePos.X - n.X*8, trianglePos.Y - n.Y*8)); * poly.Points.Add(new Windows.Foundation.Point(trianglePos.X + distanceVec.Normalized().X*20, * trianglePos.Y + distanceVec.Normalized().Y*20)); * poly.Points.Add(new Windows.Foundation.Point(trianglePos.X + n.X*8, trianglePos.Y + n.Y*8));*/ poly.Fill = _lightBrush; poly.StrokeThickness = 1; //poly.StrokeDashArray = new DoubleCollection { 2 }; poly.Stroke = _backgroundBrush; c.Children.Add(poly); if (isInverted) { drawDashedLine(start, trianglePos, n, thinkness, c); drawDashedLine(trianglePos + (distanceVec.Normalized() * arrowLength), end, n, thinkness, c); } if (!_visualizationViewModelCenterGeometries.ContainsKey(incomingModel)) { _visualizationViewModelCenterGeometries.Add(incomingModel, poly.Points.GetPolygon().Buffer(3)); _visualizationViewModelGeometries.Add(incomingModel, new Windows.Foundation.Point[] { incomingStart.GetCoord().GetPt(), (incomingStart + cutOff).GetCoord().GetPt() } .GetLineString()); } } } }
private Vec updateAttachmentCenter(LinkType linkType, Canvas canvas) { var filterLinkViewModel = DataContext as FilterLinkViewModel; var destinationRct = new Rct(filterLinkViewModel.ToOperationViewModel.Position, new Vec(filterLinkViewModel.ToOperationViewModel.Size.X, filterLinkViewModel.ToOperationViewModel.Size.Y)); var destinationGeom = destinationRct.GetLineString(); var midPoints = new List <Pt>(); var sourceCount = 0; foreach ( var from in filterLinkViewModel.FromOperationViewModels.Where( vvm => vvm.OperationModel is IFilterProviderOperationModel).Where( vvm => filterLinkViewModel.FilterLinkModels.Where(lvm => lvm.LinkType == linkType) .Select(lvm => lvm.FromOperationModel) .Contains(vvm.OperationModel as IFilterProviderOperationModel))) { sourceCount++; var fromCenterToCenter = new Windows.Foundation.Point[] { filterLinkViewModel.ToOperationViewModel.Position + filterLinkViewModel.ToOperationViewModel.Size / 2.0, from.Position + from.Size / 2.0 }.GetLineString(); var sourceRct = new Rct(from.Position, new Vec(from.Size.X, from.Size.Y)).GetLineString(); var interPtSource = sourceRct.Intersection(fromCenterToCenter); var interPtDestination = destinationGeom.Intersection(fromCenterToCenter); var midPoint = new Vec(); if (interPtDestination.IsEmpty || interPtSource.IsEmpty) { midPoint = (filterLinkViewModel.ToOperationViewModel.Position + filterLinkViewModel.ToOperationViewModel.Size / 2.0 + (from.Position + from.Size / 2.0)).GetVec() / 2.0; } else { midPoint = (new Vec(interPtSource.Centroid.X, interPtSource.Centroid.Y) + new Vec(interPtDestination.Centroid.X, interPtDestination.Centroid.Y)) / 2.0; } midPoints.Add(new Pt(midPoint.X, midPoint.Y)); } if (sourceCount == 0) { if (linkType == LinkType.Brush) { return(new Vec( destinationRct.Left + _attachmentRectHalfSize, destinationRct.Bottom + _attachmentRectHalfSize - 2)); } else if (linkType == LinkType.Filter) { return(new Vec( destinationRct.Right - _attachmentRectHalfSize, destinationRct.Bottom + _attachmentRectHalfSize - 2)); } } var tempAttachment = midPoints.Aggregate((p1, p2) => p1 + p2).GetVec() / midPoints.Count; var destinationVec = new Vec( (filterLinkViewModel.ToOperationViewModel.Position + filterLinkViewModel.ToOperationViewModel.Size / 2.0) .X, (filterLinkViewModel.ToOperationViewModel.Position + filterLinkViewModel.ToOperationViewModel.Size / 2.0) .Y); var inter = destinationGeom.Intersection( new Windows.Foundation.Point[] { tempAttachment.GetCoord().GetPt(), destinationVec.GetCoord().GetPt() }.GetLineString()); var attachmentCenter = new Vec(); if (inter.IsEmpty) { var dirVec = tempAttachment - destinationVec; dirVec = dirVec.Normal() * 40000; dirVec += tempAttachment; inter = destinationGeom.Intersection( new Windows.Foundation.Point[] { dirVec.GetCoord().GetPt(), destinationVec.GetCoord().GetPt() } .GetLineString()); attachmentCenter = new Vec(inter.Centroid.X, inter.Centroid.Y); } else { attachmentCenter = new Vec(inter.Centroid.X, inter.Centroid.Y); } var attachmentLocation = getAttachmentLocation(destinationRct, attachmentCenter); // left if (attachmentLocation == AttachmentLocation.Left) { attachmentCenter = new Vec( attachmentCenter.X - _attachmentRectHalfSize + 2, Math.Min(Math.Max(attachmentCenter.Y, destinationRct.Top + _attachmentRectHalfSize), destinationRct.Bottom - _attachmentRectHalfSize)); } // right else if (attachmentLocation == AttachmentLocation.Right) { attachmentCenter = new Vec( attachmentCenter.X + _attachmentRectHalfSize - 2, Math.Min(Math.Max(attachmentCenter.Y, destinationRct.Top + _attachmentRectHalfSize), destinationRct.Bottom - _attachmentRectHalfSize)); } // top else if (attachmentLocation == AttachmentLocation.Top) { attachmentCenter = new Vec( Math.Min(Math.Max(attachmentCenter.X, destinationRct.Left + _attachmentRectHalfSize), destinationRct.Right - _attachmentRectHalfSize), attachmentCenter.Y - _attachmentRectHalfSize + 2); } // bottom else if (attachmentLocation == AttachmentLocation.Bottom) { attachmentCenter = new Vec( Math.Min(Math.Max(attachmentCenter.X, destinationRct.Left + _attachmentRectHalfSize), destinationRct.Right - _attachmentRectHalfSize), attachmentCenter.Y + _attachmentRectHalfSize - 2); } return(attachmentCenter); }