private Strand ExpandStrand(int level, int density, List <TrammelMark> trammel) { Strand strand = new Strand((uint)level); SortedList <uint, TrammelMark> expansion = new SortedList <uint, TrammelMark>(); // First add each trammel mark's distance to its current position... for (int i = 0; i < trammel.Count; i++) { trammel[i].Position += trammel[i].Distance; uint positionKey = trammel[i].PositionKey; while (expansion.ContainsKey(positionKey)) { positionKey += 1; // resolves positions which would otherwise be identical } expansion.Add(positionKey, trammel[i]); } // Now construct the strand. for (int i = 0; i < density; i++) { TrammelMark tm = expansion.Values[0]; strand.Values.Add((uint)tm.Value); expansion.RemoveAt(0); tm.Position += tm.Distance; uint positionKey = tm.PositionKey; while (expansion.ContainsKey(positionKey)) { positionKey += 1; // resolves positions which would otherwise be identical } expansion.Add(positionKey, tm); } // The strand is complete. // Now reset the trammel so that the smallest trammel mark position is 0. // First, remove unused distances... expansion.Clear(); for (int i = 0; i < trammel.Count; i++) { trammel[i].Position -= trammel[i].Distance; uint positionKey = trammel[i].PositionKey; while (expansion.ContainsKey(positionKey)) { positionKey += 1; // resolves positions which would otherwise be identical } expansion.Add(positionKey, trammel[i]); } // Second, subtract the first trammel mark position from all trammel marks. uint minPos = expansion.Values[0].Position; foreach (TrammelMark tm in trammel) { tm.Position -= minPos; } return(strand); }
private void Expand(List <StrandNode> strandNodeList, Expander expander) { #region preparation List <PointGroup> fixedInputPointGroups = expander.InputGamete.FixedPointGroups; List <PointGroup> fixedOutputPointGroups = expander.OutputGamete.FixedPointGroups; List <Planet> inputPlanets = expander.InputGamete.Planets; List <Planet> outputPlanets = expander.OutputGamete.Planets; List <TrammelMark> trammel = new List <TrammelMark>(); foreach (int value in expander.OutputGamete.Values) { TrammelMark tm = new TrammelMark(value); trammel.Add(tm); } uint[,] distances = new uint[expander.InputGamete.NumberOfValues, expander.OutputGamete.NumberOfValues]; CalculateFixedDistances(distances, fixedInputPointGroups, fixedOutputPointGroups); #endregion preparation #region expand strands int momentIndex = 0; foreach (StrandNode strandNode in strandNodeList) { int level = strandNode.strandLevel; int density = strandNode.strandDensity; int iPointValue = strandNode.strandPoint; int iPointIndex = iPointValue - 1; // the input point's index in the distances array #region calculate distances for planets where necessary. PointF?iPointPosition = null; if (inputPlanets.Count > 0) { iPointPosition = InputPlanetPosition(momentIndex, iPointValue, inputPlanets); } // iPointPosition == null if the current input point is not a planet // If the current input point is a planet, calculate distances to the fixed output points. if (iPointPosition != null && fixedOutputPointGroups.Count > 0) { CalculateInputPlanetDistances(distances, iPointIndex, (PointF)iPointPosition, fixedOutputPointGroups); } if (outputPlanets.Count > 0) { // If there are output planets, it is necessary to calculate their distances from the input point if (iPointPosition == null) // the input point is not a planet, so its a fixed point { iPointPosition = FixedInputPointPosition(iPointValue, fixedInputPointGroups); } if (iPointPosition == null) { throw new ApplicationException("Error finding the position of an input point."); } // There are output planets, so calculate their distances from the (planet or fixed)input point. CalculateOutputPlanetsDistances(momentIndex, distances, iPointIndex, (PointF)iPointPosition, outputPlanets); } #endregion calculate distances for planets where necessary foreach (TrammelMark tm in trammel) { tm.Distance = distances[iPointIndex, tm.DistancesIndex]; } Strand strand = ExpandStrand(level, density, trammel); _strands.Add(strand); momentIndex++; } #endregion expand strands }
private void Expand(List<StrandNode> strandNodeList, Expander expander) { #region preparation List<PointGroup> fixedInputPointGroups = expander.InputGamete.FixedPointGroups; List<PointGroup> fixedOutputPointGroups = expander.OutputGamete.FixedPointGroups; List<Planet> inputPlanets = expander.InputGamete.Planets; List<Planet> outputPlanets = expander.OutputGamete.Planets; List<TrammelMark> trammel = new List<TrammelMark>(); foreach(int value in expander.OutputGamete.Values) { TrammelMark tm = new TrammelMark(value); trammel.Add(tm); } uint[,] distances = new uint[expander.InputGamete.NumberOfValues, expander.OutputGamete.NumberOfValues]; CalculateFixedDistances(distances, fixedInputPointGroups, fixedOutputPointGroups); #endregion preparation #region expand strands int momentIndex = 0; foreach(StrandNode strandNode in strandNodeList) { int level = strandNode.strandLevel; int density = strandNode.strandDensity; int iPointValue = strandNode.strandPoint; int iPointIndex = iPointValue - 1; // the input point's index in the distances array #region calculate distances for planets where necessary. PointF? iPointPosition = null; if(inputPlanets.Count > 0) iPointPosition = InputPlanetPosition(momentIndex, iPointValue, inputPlanets); // iPointPosition == null if the current input point is not a planet // If the current input point is a planet, calculate distances to the fixed output points. if(iPointPosition != null && fixedOutputPointGroups.Count > 0) CalculateInputPlanetDistances(distances, iPointIndex, (PointF) iPointPosition, fixedOutputPointGroups); if(outputPlanets.Count > 0) { // If there are output planets, it is necessary to calculate their distances from the input point if(iPointPosition == null) // the input point is not a planet, so its a fixed point iPointPosition = FixedInputPointPosition(iPointValue, fixedInputPointGroups); if(iPointPosition == null) throw new ApplicationException("Error finding the position of an input point."); // There are output planets, so calculate their distances from the (planet or fixed)input point. CalculateOutputPlanetsDistances(momentIndex, distances, iPointIndex, (PointF) iPointPosition, outputPlanets); } #endregion calculate distances for planets where necessary foreach(TrammelMark tm in trammel) tm.Distance = distances[iPointIndex, tm.DistancesIndex]; Strand strand = ExpandStrand(level, density, trammel); _strands.Add(strand); momentIndex++; } #endregion expand strands }