private void btn3DLinksBrainInput_Click(object sender, RoutedEventArgs e) { try { PrepFor3D(); ClearTempVisuals(); LinkItem[] items1 = _inputs3D. Select(o => new LinkItem(o.Position.Value, o.Size)). ToArray(); LinkItem[] items2 = _brains3D. Select(o => new LinkItem(o.Position.Value, o.Size)). ToArray(); ItemLinker_OverflowArgs overflowArgs = new ItemLinker_OverflowArgs() { LinkResistanceMult = trk3DLinkResistMult.Value, }; Tuple<int, int>[] links = ItemLinker.Link_1_2(items1, items2, overflowArgs); // Draw _linksIO3D.AddRange(DrawBrainIOLinks3D(_viewportFull, links, _inputs3D.ToArray(), _brains3D.ToArray(), _ioLinkColor, chk3DRainbowLinks.IsChecked.Value)); } catch (Exception ex) { MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error); } }
private static DistributeDistances GetDistances(LinkItem[] items1, LinkItem[] items2, ItemLinker_OverflowArgs overflowArgs) { // Distances between all item1s (not just delaunay, but all pairs) Tuple<int, double>[][] resistancesItem1 = ItemItemResistance(items1, overflowArgs == null ? 1 : overflowArgs.LinkResistanceMult); // Figure out the distances between 2s and 1s var distances2to1 = Enumerable.Range(0, items2.Length). Select(o => new Distances2to1 ( o, Enumerable.Range(0, items1.Length). Select(p => Tuple.Create(p, (items1[p].Position - items2[o].Position).Length)). //Item1=items1 index, Item2=distance to item1 OrderBy(p => p.Item2). // first item1 needs to be the shortest distance ToArray() )). OrderBy(o => o.DistancesTo1.First().Item2). ToArray(); return new DistributeDistances(resistancesItem1, distances2to1); }
private void btn3DLinksBrainIO_Click(object sender, RoutedEventArgs e) { try { PrepFor3D(); ClearTempVisuals(); LinkItem[] brains = _brains3D. Select(o => new LinkItem(o.Position.Value, o.Size)). ToArray(); LinkItem[] io = _inputs3D. Concat(_outputs3D). Select(o => new LinkItem(o.Position.Value, o.Size)). ToArray(); ItemLinker_OverflowArgs overflowArgs = new ItemLinker_OverflowArgs() { LinkResistanceMult = trk3DLinkResistMult.Value, }; ItemLinker_ExtraArgs extraArgs = null; if (!trk3DExtraLinkPercent.Value.IsNearZero()) { extraArgs = new ItemLinker_ExtraArgs() { Percent = trk3DExtraLinkPercent.Value / 100d, BySize = chk3DExtraLinkBySize.IsChecked.Value, EvenlyDistribute = chk3DExtraLinkEvenDistribute.IsChecked.Value, }; } Tuple<int, int>[] links = ItemLinker.Link_1_2(brains, io, overflowArgs, extraArgs); // Draw _linksIO3D.AddRange(DrawBrainIOLinks3D(_viewportFull, links, _brains3D.ToArray(), _inputs3D.Concat(_outputs3D).ToArray(), _ioLinkColor, chk3DRainbowLinks.IsChecked.Value)); } catch (Exception ex) { MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error); } }
/// <summary> /// Every item in 2 will have at least one link to a 1. There could be some item1s that don't have a link /// </summary> /// <param name="overflowArgs"> /// Item2s get matched to the nearest Item1. /// If this args is null then, it stays that way. /// If this is populated, then links will move from burdened item1s to less burdened /// </param> /// <returns> /// Item1=index into item1 list /// Item2=index into item2 list /// </returns> public static Tuple<int, int>[] Link_1_2(LinkItem[] items1, LinkItem[] items2, ItemLinker_OverflowArgs overflowArgs = null, ItemLinker_ExtraArgs extraArgs = null) { if (items1 == null || items2 == null || items1.Length == 0 || items2.Length == 0) { return new Tuple<int, int>[0]; } Tuple<int, int>[] retVal = null; if (overflowArgs == null) { // Just link to the closest retVal = Link12_Closest(items1, items2); } if (overflowArgs == null && extraArgs == null) { // Nothing special to do, exit early return retVal; } DistributeDistances distances = GetDistances(items1, items2, overflowArgs); if (overflowArgs != null) { // Consider item1s burden when linking them retVal = Link12_Distribute(items1, items2, distances); } if (extraArgs != null) { // Add more links retVal = Link12_Extra(retVal, items1, items2, distances, extraArgs); } return retVal; }