Exemple #1
0
        internal static void CreateNeurons(out Neuron_SensorPosition[] neuronsR, out Neuron_SensorPosition[] neuronsG, out Neuron_SensorPosition[] neuronsB, out OverlayResult[][] overlayR, out OverlayResult[][] overlayG, out OverlayResult[][] overlayB, out int pixelWidthHeight, ShipPartDNA dna, ItemOptions itemOptions, double neuronDensity)
        {
            const int MINPIXELWIDTH = 16;

            #region Calculate counts

            // Figure out how many neurons 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 = (dna.Scale.X + dna.Scale.Y + dna.Scale.Z) / (3d * 2d);              // xyz should all be the same anyway
            double area   = Math.Pow(radius, itemOptions.Sensor_NeuronGrowthExponent);

            int neuronCount = Convert.ToInt32(Math.Ceiling(neuronDensity * area));
            if (neuronCount == 0)
            {
                neuronCount = 1;
            }

            // Figure out how many pixels to make
            pixelWidthHeight = neuronCount / 9;     // dividing by 3 to get the number of neurons in a single plate.  divide that by 3, because that's a good ratio of neuron cells to pixels
            if (pixelWidthHeight < MINPIXELWIDTH)
            {
                pixelWidthHeight = MINPIXELWIDTH;
            }

            #endregion

            #region Neurons

            // Place them evenly in a sphere
            //NOTE: An interesting side effect of calling this for each generation is that the parent may not have been perfectly evenly spaced, but calling this
            //again will slightly refine the positions
            Vector3D[][] positions = GetNeuronPositions(dna.Neurons, neuronCount, 3, radius);

            // Create neurons
            neuronsR = positions[0].Select(o => new Neuron_SensorPosition(o.ToPoint(), true)).ToArray();
            neuronsG = positions[1].Select(o => new Neuron_SensorPosition(o.ToPoint(), true)).ToArray();
            neuronsB = positions[2].Select(o => new Neuron_SensorPosition(o.ToPoint(), true)).ToArray();

            #endregion

            #region Polygons around neurons

            // Figure out which pixels each neuron intersects with
            VoronoiResult2D[] voronoi = new VoronoiResult2D[3];
            voronoi[0] = Math2D.CapVoronoiCircle(Math2D.GetVoronoi(positions[0].Select(o => new Point(o.X, o.Y)).ToArray(), true));
            voronoi[1] = Math2D.CapVoronoiCircle(Math2D.GetVoronoi(positions[1].Select(o => new Point(o.X, o.Y)).ToArray(), true));
            voronoi[2] = Math2D.CapVoronoiCircle(Math2D.GetVoronoi(positions[2].Select(o => new Point(o.X, o.Y)).ToArray(), true));

            #region Figure out the extremes

            Point[] allEdgePoints = voronoi.SelectMany(o => o.EdgePoints).ToArray();

            Point min = new Point(allEdgePoints.Min(o => o.X), allEdgePoints.Min(o => o.Y));
            Point max = new Point(allEdgePoints.Max(o => o.X), allEdgePoints.Max(o => o.Y));

            double width  = max.X - min.X;
            double height = max.Y - min.Y;

            // Enlarge a bit
            min.X -= width * .05d;
            min.Y -= height * .05d;
            max.X += width * .05d;
            max.Y += height * .05d;

            width  = max.X - min.X;
            height = max.Y - min.Y;

            Vector offset = new Vector(-min.X, -min.Y);

            #endregion

            //  Figure out which pixels each polygon overlaps
            overlayR = GetIntersections(new Size(width, height), pixelWidthHeight, pixelWidthHeight, GetPolygons(voronoi[0], offset));
            overlayG = GetIntersections(new Size(width, height), pixelWidthHeight, pixelWidthHeight, GetPolygons(voronoi[1], offset));
            overlayB = GetIntersections(new Size(width, height), pixelWidthHeight, pixelWidthHeight, GetPolygons(voronoi[2], offset));

            #endregion
        }
        internal static void CreateNeurons(out Neuron_SensorPosition[] neuronsR, out Neuron_SensorPosition[] neuronsG, out Neuron_SensorPosition[] neuronsB, out OverlayResult[][] overlayR, out OverlayResult[][] overlayG, out OverlayResult[][] overlayB, out int pixelWidthHeight, ShipPartDNA dna, ItemOptions itemOptions, double neuronDensity)
        {
            const int MINPIXELWIDTH = 16;

            #region Calculate counts

            // Figure out how many neurons 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 = (dna.Scale.X + dna.Scale.Y + dna.Scale.Z) / (3d * 2d);		// xyz should all be the same anyway
            double area = Math.Pow(radius, itemOptions.Sensor_NeuronGrowthExponent);

            int neuronCount = Convert.ToInt32(Math.Ceiling(neuronDensity * area));
            if (neuronCount == 0)
            {
                neuronCount = 1;
            }

            // Figure out how many pixels to make
            pixelWidthHeight = neuronCount / 9;     // dividing by 3 to get the number of neurons in a single plate.  divide that by 3, because that's a good ratio of neuron cells to pixels
            if (pixelWidthHeight < MINPIXELWIDTH)
            {
                pixelWidthHeight = MINPIXELWIDTH;
            }

            #endregion

            #region Neurons

            // Place them evenly in a sphere
            //NOTE: An interesting side effect of calling this for each generation is that the parent may not have been perfectly evenly spaced, but calling this
            //again will slightly refine the positions
            Vector3D[][] positions = GetNeuronPositions(dna.Neurons, neuronCount, 3, radius);

            // Create neurons
            neuronsR = positions[0].Select(o => new Neuron_SensorPosition(o.ToPoint(), true)).ToArray();
            neuronsG = positions[1].Select(o => new Neuron_SensorPosition(o.ToPoint(), true)).ToArray();
            neuronsB = positions[2].Select(o => new Neuron_SensorPosition(o.ToPoint(), true)).ToArray();

            #endregion

            #region Polygons around neurons

            // Figure out which pixels each neuron intersects with
            VoronoiResult2D[] voronoi = new VoronoiResult2D[3];
            voronoi[0] = Math2D.CapVoronoiCircle(Math2D.GetVoronoi(positions[0].Select(o => new Point(o.X, o.Y)).ToArray(), true));
            voronoi[1] = Math2D.CapVoronoiCircle(Math2D.GetVoronoi(positions[1].Select(o => new Point(o.X, o.Y)).ToArray(), true));
            voronoi[2] = Math2D.CapVoronoiCircle(Math2D.GetVoronoi(positions[2].Select(o => new Point(o.X, o.Y)).ToArray(), true));

            #region Figure out the extremes

            Point[] allEdgePoints = voronoi.SelectMany(o => o.EdgePoints).ToArray();

            Point min = new Point(allEdgePoints.Min(o => o.X), allEdgePoints.Min(o => o.Y));
            Point max = new Point(allEdgePoints.Max(o => o.X), allEdgePoints.Max(o => o.Y));

            double width = max.X - min.X;
            double height = max.Y - min.Y;

            // Enlarge a bit
            min.X -= width * .05d;
            min.Y -= height * .05d;
            max.X += width * .05d;
            max.Y += height * .05d;

            width = max.X - min.X;
            height = max.Y - min.Y;

            Vector offset = new Vector(-min.X, -min.Y);

            #endregion

            //  Figure out which pixels each polygon overlaps
            overlayR = GetIntersections(new Size(width, height), pixelWidthHeight, pixelWidthHeight, GetPolygons(voronoi[0], offset));
            overlayG = GetIntersections(new Size(width, height), pixelWidthHeight, pixelWidthHeight, GetPolygons(voronoi[1], offset));
            overlayB = GetIntersections(new Size(width, height), pixelWidthHeight, pixelWidthHeight, GetPolygons(voronoi[2], offset));

            #endregion
        }