private static void SetPlantHullPoints(RootBase r)
        {
            List <Int32Point> samplePoints = new List <Int32Point>();

            foreach (RootBase child in r.Children)
            {
                samplePoints.AddRange(child.ConvexHullPoints);
            }

            r.convexHullPoints = RootNav.Core.DataStructures.ConvexHull.FindHull(samplePoints);
        }
 private static void MarkStartReferences(List <PlantComponent> roots)
 {
     foreach (RootBase r in roots)
     {
         RootBase parentRoot = r.Parent as RootBase;
         if (r.Parent != null)
         {
             r.startReference = parentRoot.Spline.GetPositionReference(r.Start);
         }
         if (r.Children.Count > 0)
         {
             MarkStartReferences(r.Children);
         }
     }
 }
        public static Dictionary <string, string> GetDataAsStrings(RootBase root)
        {
            Dictionary <string, string> outputData = new Dictionary <string, string>();
            Dictionary <string, object> data       = GetData(root);

            bool isPlant   = data["Order"].ToString() == "-1";
            bool isPrimary = data["Order"].ToString() == "0";

            outputData.Add("ID", data["ID"].ToString());
            outputData.Add("Parent", data["Parent Relative ID"] == null ? "" : data["Parent Relative ID"].ToString());
            outputData.Add("Order", data["Order"].ToString());
            outputData.Add("Length", isPlant ? "" : data["Length"].ToString());
            outputData.Add("Label", root.Label);
            outputData.Add("Emergence Angle", isPlant ? "" : data["Emergence Angle"].ToString());
            outputData.Add("Tip Angle", isPlant ? "" : data["Tip Angle"].ToString());
            outputData.Add("Hull Area", data["Hull Area"] == null ? "" : data["Hull Area"].ToString());
            outputData.Add("Start Distance", isPlant || isPrimary ? "" : data["Start Distance"].ToString());
            outputData.Add("Lateral Count", data["Lateral Count"].ToString());

            return(outputData);
        }
        public static Dictionary <string, object> GetData(RootBase root)
        {
            Dictionary <string, object> outputData = new Dictionary <string, object>();

            outputData.Add("ID", root.RelativeID);
            outputData.Add("Start", root.Order >= 0 ? root.Start.ToRoundString() : null);
            outputData.Add("End", root.Order >= 0 ? root.End.ToRoundString() : null);
            outputData.Add("Order", root.Order);
            outputData.Add("Length", (double?)Math.Round(root.Length, 2));
            outputData.Add("Label", root.Label);
            outputData.Add("Emergence Angle", root.Order == -1 ? null : (double?)Math.Round(root.EmergenceAngle, 1));
            outputData.Add("Tip Angle", root.Order == -1 ? null : (double?)Math.Round(root.TipAngle, 1));
            outputData.Add("Start Reference", root.Order > 0 ? ObjectToBinary(root.StartReference) : null);
            outputData.Add("Start Distance", root.StartDistance <= 0 ? null : (double?)Math.Round(root.StartDistance, 2));
            outputData.Add("Spline", root.Order >= 0 ? ObjectToBinary(root.Spline) : null);
            outputData.Add("Hull Area", root.Order > 0 ? null : (double?)Math.Round(root.ConvexHullArea, 2));

            outputData.Add("Primary Parent Relative ID", root.PrimaryParent == null ? null : root.PrimaryParent.RelativeID);
            outputData.Add("Parent Relative ID", root.Parent == null ? null : root.Parent.RelativeID);

            outputData.Add("Lateral Count", root.Children.Count);

            return(outputData);
        }
        public static RootCollection CreateRootSystem(LiveWirePathCollection pathCollection, RootTerminalCollection terminals, List <Color> colors, int splineResolution, double unitConversion)
        {
            Dictionary <int, Tuple <RootBase, int, int> > indexedRoots = new Dictionary <int, Tuple <RootBase, int, int> >();
            double        tension       = 0.5;
            HashSet <int> sourceIndexes = new HashSet <int>();

            for (int index = 0; index < pathCollection.Count; index++)
            {
                LiveWirePath currentPath = pathCollection[index];

                if (currentPath is LiveWirePrimaryPath)
                {
                    LiveWirePrimaryPath primaryLiveWire = currentPath as LiveWirePrimaryPath;

                    RootBase primary = new PrimaryRoot()
                    {
                        UnitConversionFactor = unitConversion
                    };
                    primary.RootIndex = index;

                    primary.Spline = new SampledSpline()
                    {
                        ControlPointSeparation = splineResolution, Tension = tension
                    };
                    primary.Spline.Initialise(primaryLiveWire.Path);

                    primary.Color = colors[index];

                    indexedRoots.Add(index, new Tuple <RootBase, int, int> (primary, primaryLiveWire.SourceIndex, -1));

                    sourceIndexes.Add(primaryLiveWire.SourceIndex);
                }
                else if (currentPath is LiveWireLateralPath)
                {
                    LiveWireLateralPath lateralLiveWire = currentPath as LiveWireLateralPath;

                    RootBase lateral = new LateralRoot()
                    {
                        UnitConversionFactor = unitConversion
                    };
                    lateral.RootIndex = index;
                    List <Point> path = lateralLiveWire.Path.ToList();
                    path.Reverse();
                    lateral.Spline = new SampledSpline()
                    {
                        ControlPointSeparation = splineResolution, Tension = tension
                    };
                    lateral.Spline.Initialise(path);

                    lateral.Color = colors[lateralLiveWire.TargetPoint.ParentIndex];

                    indexedRoots.Add(index, new Tuple <RootBase, int, int> (lateral, -1, lateralLiveWire.TargetPoint.ParentIndex));
                }
            }

            Dictionary <int, RootBase> plants = new Dictionary <int, RootBase>();

            foreach (int i in sourceIndexes)
            {
                RootBase plant = new RootGroup()
                {
                    UnitConversionFactor = unitConversion
                };
                plants.Add(i, plant);
            }

            // Create tree structure based on references
            List <RootBase> primaryRoots = new List <RootBase>();

            foreach (var pair in indexedRoots)
            {
                RootBase r = pair.Value.Item1;
                int      plantSourceIndex = pair.Value.Item2;
                int      parentIndex      = pair.Value.Item3;

                if (parentIndex == -1)
                {
                    // Add primary root to main list
                    plants[plantSourceIndex].Children.Add(r);
                }
                else
                {
                    // Add lateral to parent's children
                    indexedRoots[parentIndex].Item1.Children.Add(r);
                    r.Parent = indexedRoots[parentIndex].Item1;
                }
            }

            List <RootBase> plantList = plants.Values.ToList();

            int plantIndex = 1;

            foreach (RootBase plant in plantList)
            {
                plant.ID = plantIndex++;

                // Lateral angles can now be calculated
                MarkStartReferences(plant.Children);

                // Calculate IDs
                MarkIDs(plant.Children);

                // Mark primary parents
                MarkPrimaryParents(plant, plant.Children);

                // Mark convex hulls
                MarkConvexHulls(plant.Children);

                // Plant settings
                plant.Color = Color.FromArgb(255, 200, 200, 200);

                // Plant hull
                SetPlantHullPoints(plant);
            }

            // Create plant systems
            return(new RootCollection {
                RootTree = plantList
            });
        }