internal static Neuron_SensorPosition[] CreateNeurons(ShipPartDNA dna, ItemOptions itemOptions, double neuronDensity, bool hasHoleInMiddle, bool ignoreSetValue) { var count = GetNeuronCount(dna.Scale, itemOptions.Sensor_NeuronGrowthExponent, neuronDensity); Point3D[] staticPositions = null; if (hasHoleInMiddle) { staticPositions = new Point3D[] { new Point3D(0, 0, 0) }; } // Place them evenly within a circle. // I don't want a neuron in the center, so placing a static point there to force the neurons away from the center Vector3D[] positions = NeuralUtility.GetNeuronPositions_Circular_Even(dna.Neurons, staticPositions, 1d, count.neuronCount, count.radius); return(positions. Select(o => new Neuron_SensorPosition(o.ToPoint(), true, ignoreSetValue)). ToArray()); }
private static NeuronLayer[] CreateNeurons_Layers(SensorVisionDNA dna, ItemOptionsArco itemOptions) { if (dna.Filters == null || dna.Filters.Length == 0) { throw new ApplicationException("This method requires filters to be populated"); } var count = GetNeuronCount(dna.Scale, itemOptions.Sensor_NeuronGrowthExponent, itemOptions.VisionSensor_NeuronDensity); //TODO: SensorVisionFilterType.Bot will need two layers var neuronZs = GetNeuron_Zs(dna.Filters.Length, count.radius); Point3D[] staticPositions = new Point3D[] { new Point3D(0, 0, 0) }; Point3D[] singlePlate = null; if (dna.Neurons != null && dna.Neurons.Length > 0) { var byLayer = NeuralUtility.DivideNeuronLayersIntoSheets(dna.Neurons, neuronZs.z, count.neuronCount); // Just use one of the layer's positions to re evenly distribute (first layer with the correct number of neurons - or closest number). // Could try to find the nearest between each layer and use the average of each set, but that's a lot of expense with very little payoff singlePlate = GetBestNeuronSheet(byLayer, count.neuronCount); } // Make sure there is a correct number of neurons and apply an even distribution singlePlate = NeuralUtility.GetNeuronPositions_Circular_Even(singlePlate, staticPositions, 1d, count.neuronCount, count.radius). Select(o => o.ToPoint()). ToArray(); // Use the location of neurons in this single layer for all layers. By making sure that each neuron represents the same point in each // layer (and the index of that neuron is the same in each layer), position logic in each tick can be optimized return(Enumerable.Range(0, dna.Filters.Length). Select(o => new NeuronLayer() { FilterType = dna.Filters[o], Z = neuronZs.z[o], Neurons = singlePlate. Select(p => new Neuron_SensorPosition(new Point3D(p.X, p.Y, neuronZs.z[o]), true, true)). ToArray(), }). ToArray()); }
private static Neuron_SensorPosition[] CreateNeurons(ShipPartDNA dna, ItemOptions itemOptions, double neuronDensity, bool ignoreSetValue) { #region calculate counts // Figure out how many to make //NOTE: This radius isn't taking SCALE into account. The other neural parts do this as well, so the neural density properties can be more consistent double radius = Math1D.Avg(dna.Scale.X, dna.Scale.Y, dna.Scale.Z) / 2d; // dividing by 2, because radius is wanted, not diameter double area = Math.Pow(radius, itemOptions.Sensor_NeuronGrowthExponent); int neuronCount = (neuronDensity * area).ToInt_Ceiling(); neuronCount = Math.Max(neuronCount, 30); #endregion // Place them evenly on the surface of a sphere Vector3D[] positions = NeuralUtility.GetNeuronPositions_Circular_Even(dna.Neurons, neuronCount, radius); return(positions. Select(o => new Neuron_SensorPosition(o.ToPoint(), true, ignoreSetValue)). ToArray()); }