Beispiel #1
0
        private static Tuple <SamplePoint[], Neuron_SensorPosition[][]> CreateNeurons(ShipPartDNA dna, ItemOptions itemOptions)
        {
            #region count

            // Figure out how many sample points to create
            //NOTE: radius assumes a sphere, but this camera is a cone.  Not perfect, but good enough
            double radius = (dna.Scale.X + dna.Scale.Y + dna.Scale.Z) / (3d * 2d);              // xyz should all be the same anyway
            double volume = Math.Pow(radius, itemOptions.Sensor_NeuronGrowthExponent);

            int numSamples = Convert.ToInt32(Math.Ceiling(itemOptions.CameraHardCoded_NeuronDensity * volume));
            if (numSamples == 0)
            {
                numSamples = 1;
            }

            #endregion

            //TODO: Calculate this based on the densitiy of sets inside the cone portion of the unit sphere
            double setSize = .1;

            #region positions

            // Get points in a cone
            //NOTE: Going with a narrower angle, because the neurons will go to the edges, but the neurons will be the center of a vision sphere -- so the actual vision will be larger than this cone
            Vector3D[] pointsModel = Math3D.GetRandomVectors_Cone_EvenDist(numSamples, CameraColorRGBDesign.CameraDirection, 60, .2, 1);

            // Turn into sensor neurons
            Neuron_SensorPosition[][] neurons = pointsModel.
                                                Select(o => GetNeuronSet(o.ToPoint(), setSize)).
                                                ToArray();

            double worldMax = itemOptions.CameraHardCoded_WorldMax;

            //NOTE: The term world is a bit misleading.  It's world distances, but still technically model coords.  It's just not neural's unit circle coords
            Point3D[] pointsWorld = pointsModel.
                                    Select(o =>
            {
                double distanceFromOrigin = o.Length;
                return(o.ToUnit() * (worldMax * Math.Pow(distanceFromOrigin, 3)));
            }).
                                    Select(o => o.ToPoint()).
                                    ToArray();

            #endregion

            #region vision radius

            // Delaunay
            //TODO: Throw out thin triangles
            Tetrahedron[] tetras = Math3D.GetDelaunay(pointsWorld, 10);

            double approximateRadius = worldMax * .667;

            double[] cellRadii = null;
            if (tetras == null)
            {
                cellRadii = Enumerable.Range(0, pointsWorld.Length).
                            Select(o => approximateRadius).
                            ToArray();
            }
            else
            {
                Tuple <int, int>[] uniqueLines = Tetrahedron.GetUniqueLines(tetras);

                cellRadii = Enumerable.Range(0, pointsWorld.Length).
                            Select(o => GetCellRadius(o, pointsWorld, uniqueLines, approximateRadius)).
                            ToArray();
            }

            #endregion

            // Turn into sample points
            SamplePoint[] samplePoints = Enumerable.Range(0, numSamples).
                                         Select(o => new SamplePoint(pointsModel[o].ToPoint(), pointsWorld[o].ToVector(), cellRadii[o], neurons[o])).
                                         ToArray();

            return(Tuple.Create(samplePoints, neurons));
        }