Ejemplo n.º 1
0
        private static Neuron_SensorPosition[] GetNeuronSet(Point3D centerPoint, double size)
        {
            double half = size / 2;

            Vector3D posDir     = new Vector3D(half, half, half);
            Vector3D halfPosDir = posDir / 2;       // posDir's length is half of the cube's diagonal, so halfPosDir length is a quarter of the diagonal

            Vector3D orth = Vector3D.CrossProduct(posDir, new Vector3D(-1, 1, -1));

            orth = Vector3D.CrossProduct(posDir, orth);
            orth = orth.ToUnit() * halfPosDir.Length;

            Point3D posMid = centerPoint + halfPosDir + orth;
            Point3D negMid = centerPoint - halfPosDir - (orth * .5);        // using a different distance so it's not symetric

            Neuron_SensorPosition[] retVal = new Neuron_SensorPosition[5];

            retVal[0] = new Neuron_SensorPosition(centerPoint - posDir, true);
            retVal[1] = new Neuron_SensorPosition(negMid, true);
            retVal[2] = new Neuron_SensorPosition(centerPoint, true);
            retVal[3] = new Neuron_SensorPosition(posMid, true);
            retVal[4] = new Neuron_SensorPosition(centerPoint + posDir, true);

            return(retVal);
        }
Ejemplo n.º 2
0
        public FuelTank(EditorOptions options, ItemOptions itemOptions, ShipPartDNA dna)
            : base(options, dna, itemOptions.FuelTank_Damage.HitpointMin, itemOptions.FuelTank_Damage.HitpointSlope, itemOptions.FuelTank_Damage.Damage)
        {
            _itemOptions = itemOptions;

            this.Design = new FuelTankDesign(options, true);
            this.Design.SetDNA(dna);

            double surfaceArea, radius;

            _container = GetContainer(out surfaceArea, out _scaleActual, out radius, itemOptions, dna);

            _dryMass    = surfaceArea * itemOptions.FuelTank_WallDensity;
            this.Radius = radius;

            _neuron = new Neuron_SensorPosition(new Point3D(0, 0, 0), false);

            this.Destroyed += FuelTank_Destroyed;
        }
Ejemplo n.º 3
0
        public PlasmaTank(EditorOptions options, ItemOptions itemOptions, ShipPartDNA dna)
            : base(options, dna, itemOptions.PlasmaTank_Damage.HitpointMin, itemOptions.PlasmaTank_Damage.HitpointSlope, itemOptions.PlasmaTank_Damage.Damage)
        {
            _itemOptions = itemOptions;

            this.Design = new PlasmaTankDesign(options, true);
            this.Design.SetDNA(dna);

            double surfaceArea, radius;

            _container = FuelTank.GetContainer(out surfaceArea, out _scaleActual, out radius, itemOptions, dna);

            _mass       = _container.QuantityMax * itemOptions.PlasmaTank_Density; // max quantity is the volume
            this.Radius = radius;

            _neuron = new Neuron_SensorPosition(new Point3D(0, 0, 0), false);

            this.Destroyed += PlasmaTank_Destroyed;
        }
Ejemplo n.º 4
0
        private static (Neuron_SensorPosition rot_dirspeed, Neuron_SensorPosition rot_radius, Neuron_SensorPosition[] linear) CreateNeurons(ShipPartDNA dna, ItemOptionsArco itemOptions)
        {
            #region ring - linear

            // 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 = (dna.Scale.X + dna.Scale.Y) / (2d * 2d);            // XY should always be the same anyway (not looking at Z for this.  Z is just to keep the sensors from getting too close to each other)
            double area   = Math.Pow(radius, itemOptions.MotionController2_NeuronGrowthExponent);

            int neuronCount = (area * itemOptions.MotionController2_NeuronDensity).ToInt_Ceiling();
            neuronCount += 2;       // manually add two for the rotation neruons

            if (neuronCount < 7)
            {
                neuronCount = 7;
            }

            var neuronPositions = SplitNeuronPositions(dna.Neurons);

            // Place them evenly around the perimiter of a circle.
            Vector3D[] linearPositions = NeuralUtility.GetNeuronPositions_CircularShell_Even(neuronPositions?.linear, neuronCount, radius);

            Neuron_SensorPosition[] linearNeurons = linearPositions.
                                                    Select(o => new Neuron_SensorPosition(o.ToPoint(), true, false)).
                                                    ToArray();

            #endregion

            #region interior - rotation

            Neuron_SensorPosition rotateDirSpeed = new Neuron_SensorPosition(new Point3D(-.25, 0, 0), false, false);
            Neuron_SensorPosition rotateRadius   = new Neuron_SensorPosition(new Point3D(.25, 0, 0), true, false);

            #endregion

            return
                (
                rotateDirSpeed,
                rotateRadius,
                linearNeurons
                );
        }
Ejemplo n.º 5
0
        public MotionController2(EditorOptions options, ItemOptionsArco itemOptions, ShipPartDNA dna, AIMousePlate mousePlate)
            : base(options, dna, itemOptions.MotionController_Damage.HitpointMin, itemOptions.MotionController_Damage.HitpointSlope, itemOptions.MotionController_Damage.Damage)
        {
            _itemOptions = itemOptions;
            _mousePlate  = mousePlate;

            this.Design = new MotionController2Design(options, true);
            this.Design.SetDNA(dna);

            GetMass(out _mass, out double volume, out double radius, out _scaleActual, dna, itemOptions);

            this.Radius = radius;

            var neurons = CreateNeurons(dna, itemOptions);

            _neuron_rotate_direction_speed = neurons.rot_dirspeed;
            _neuron_rotate_radius          = neurons.rot_radius;
            _neurons_linear = neurons.linear;
            _neurons_all    = UtilityCore.Iterate <Neuron_SensorPosition>(_neuron_rotate_direction_speed, _neuron_rotate_radius, _neurons_linear).ToArray();
        }
Ejemplo n.º 6
0
        public EnergyTank(EditorOptions options, ItemOptions itemOptions, ShipPartDNA dna)
            : base(options, dna, itemOptions.EnergyTank_Damage.HitpointMin, itemOptions.EnergyTank_Damage.HitpointSlope, itemOptions.EnergyTank_Damage.Damage)
        {
            _itemOptions = itemOptions;

            this.Design = new EnergyTankDesign(options, true);
            this.Design.SetDNA(dna);

            double radius;

            _container = GetContainer(out _scaleActual, out radius, itemOptions, dna);

            this.Radius = radius;

            _mass = _container.QuantityMax * itemOptions.EnergyTank_Density;

            _neuron = new Neuron_SensorPosition(new Point3D(0, 0, 0), false);

            this.Destroyed += EnergyTank_Destroyed;
        }
Ejemplo n.º 7
0
        private static Neuron_SensorPosition[] GetNeuronSet_STRAIGHTLINE(Point3D centerPoint, double size)
        {
            //TODO: If the count gets much over 4, put them in a more compact pattern, some kind of spiral, or the verticies of a polyhedron
            //Math3D.GetRandomVectors_SphericalShell_EvenDist

            Neuron_SensorPosition[] retVal = new Neuron_SensorPosition[5];

            double stepSize = size / retVal.Length;
            double half     = size / 2;

            for (int cntr = 0; cntr < retVal.Length; cntr++)
            {
                double  offset   = -half + (cntr * stepSize);
                Point3D position = new Point3D(centerPoint.X + offset, centerPoint.Y + offset, centerPoint.Z + offset);     // doing the offset on each axis so the total length is sqrt(2) instead of 1

                retVal[cntr] = new Neuron_SensorPosition(position, true);
            }

            return(retVal);
        }
Ejemplo n.º 8
0
        public CargoBay(EditorOptions options, ItemOptions itemOptions, ShipPartDNA dna)
            : base(options, dna, itemOptions.CargoBay_Damage.HitpointMin, itemOptions.CargoBay_Damage.HitpointSlope, itemOptions.CargoBay_Damage.Damage)
        {
            _itemOptions = itemOptions;

            this.Design = new CargoBayDesign(options, true);
            this.Design.SetDNA(dna);

            double volume, radius;

            GetMass(out _dryMass, out volume, out radius, _itemOptions, dna);

            _scaleActual = new Vector3D(dna.Scale.X, dna.Scale.Y, dna.Scale.Z);

            this.MaxVolume = volume;
            this.Radius    = radius;

            _neuron = new Neuron_SensorPosition(new Point3D(0, 0, 0), false);

            this.Destroyed += CargoBay_Destroyed;
        }
Ejemplo n.º 9
0
        public EnergyTank(EditorOptions options, ItemOptions itemOptions, ShipPartDNA dna)
            : base(options, dna, itemOptions.EnergyTank_Damage.HitpointMin, itemOptions.EnergyTank_Damage.HitpointSlope, itemOptions.EnergyTank_Damage.Damage)
        {
            _itemOptions = itemOptions;

            this.Design = new EnergyTankDesign(options, true);
            this.Design.SetDNA(dna);

            double radius;
            _container = GetContainer(out _scaleActual, out radius, itemOptions, dna);

            this.Radius = radius;

            _mass = _container.QuantityMax * itemOptions.EnergyTank_Density;

            _neuron = new Neuron_SensorPosition(new Point3D(0, 0, 0), false);

            this.Destroyed += EnergyTank_Destroyed;
        }
Ejemplo n.º 10
0
        public CargoBay(EditorOptions options, ItemOptions itemOptions, ShipPartDNA dna)
            : base(options, dna, itemOptions.CargoBay_Damage.HitpointMin, itemOptions.CargoBay_Damage.HitpointSlope, itemOptions.CargoBay_Damage.Damage)
        {
            _itemOptions = itemOptions;

            this.Design = new CargoBayDesign(options, true);
            this.Design.SetDNA(dna);

            double volume, radius;
            GetMass(out _dryMass, out volume, out radius, _itemOptions, dna);

            _scaleActual = new Vector3D(dna.Scale.X, dna.Scale.Y, dna.Scale.Z);

            this.MaxVolume = volume;
            this.Radius = radius;

            _neuron = new Neuron_SensorPosition(new Point3D(0, 0, 0), false);

            this.Destroyed += CargoBay_Destroyed;
        }
Ejemplo n.º 11
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
        }
Ejemplo n.º 12
0
        public FuelTank(EditorOptions options, ItemOptions itemOptions, ShipPartDNA dna)
            : base(options, dna, itemOptions.FuelTank_Damage.HitpointMin, itemOptions.FuelTank_Damage.HitpointSlope, itemOptions.FuelTank_Damage.Damage)
        {
            _itemOptions = itemOptions;

            this.Design = new FuelTankDesign(options, true);
            this.Design.SetDNA(dna);

            double surfaceArea, radius;
            _container = GetContainer(out surfaceArea, out _scaleActual, out radius, itemOptions, dna);

            _dryMass = surfaceArea * itemOptions.FuelTank_WallDensity;
            this.Radius = radius;

            _neuron = new Neuron_SensorPosition(new Point3D(0, 0, 0), false);

            this.Destroyed += FuelTank_Destroyed;
        }
Ejemplo n.º 13
0
        public PlasmaTank(EditorOptions options, ItemOptions itemOptions, ShipPartDNA dna)
            : base(options, dna, itemOptions.PlasmaTank_Damage.HitpointMin, itemOptions.PlasmaTank_Damage.HitpointSlope, itemOptions.PlasmaTank_Damage.Damage)
        {
            _itemOptions = itemOptions;

            this.Design = new PlasmaTankDesign(options, true);
            this.Design.SetDNA(dna);

            double surfaceArea, radius;
            _container = FuelTank.GetContainer(out surfaceArea, out _scaleActual, out radius, itemOptions, dna);

            _mass = _container.QuantityMax * itemOptions.PlasmaTank_Density;     // max quantity is the volume
            this.Radius = radius;

            _neuron = new Neuron_SensorPosition(new Point3D(0, 0, 0), false);

            this.Destroyed += PlasmaTank_Destroyed;
        }
Ejemplo n.º 14
0
        /// <summary>
        /// This sets all the neurons from 0 to magnitude.  Magnitude needs to be from 0 to 1, and is based on the currently felt gravity compared
        /// to what the sensor has seen as the max felt
        /// </summary>
        internal static void UpdateNeurons(Neuron_SensorPosition[] neurons, double neuronMaxRadius, Vector3D vector, double magnitude)
        {
            const double MINDOT = 1.25d;

            if (Math3D.IsNearZero(vector))
            {
                // There is no gravity to report
                for (int cntr = 0; cntr < neurons.Length; cntr++)
                {
                    neurons[cntr].Value = 0d;
                }
                return;
            }

            Vector3D gravityUnit = vector.ToUnit();

            for (int cntr = 0; cntr < neurons.Length; cntr++)
            {
                if (neurons[cntr].PositionUnit == null)
                {
                    // This neuron is sitting at 0,0,0
                    neurons[cntr].Value = magnitude;
                }
                else
                {
                    // Figure out how aligned this neuron is with the gravity vector
                    double dot = Vector3D.DotProduct(gravityUnit, neurons[cntr].PositionUnit.Value);
                    dot += 1d;		// get this to scale from 0 to 2 instead of -1 to 1

                    // Scale minDot
                    double radiusPercent = neurons[cntr].PositionLength / neuronMaxRadius;
                    double revisedMinDot = UtilityCore.GetScaledValue_Capped(0d, MINDOT, 0d, 1d, radiusPercent);

                    // Rig it so that the lower radius neurons will fire stronger
                    double minReturn = 1d - radiusPercent;
                    if (minReturn < 0d)
                    {
                        minReturn = 0d;
                    }

                    // Figure out what percentage of magnitude to use
                    double percent;
                    if (dot < revisedMinDot)
                    {
                        percent = UtilityCore.GetScaledValue_Capped(0d, minReturn, 0d, revisedMinDot, dot);
                    }
                    else
                    {
                        percent = UtilityCore.GetScaledValue_Capped(minReturn, 1d, revisedMinDot, 2d, dot);
                    }

                    // Set the neuron
                    neurons[cntr].Value = percent * magnitude;
                }
            }
        }