Beispiel #1
0
        private void FormMain_Paint(object sender, PaintEventArgs e)
        {
            if (brain == null)
            {
                return;
            }

            Graphics g = e.Graphics;
            Size     s = this.DisplayRectangle.Size;
            float    w = s.Width / 2;
            float    h = s.Height / 2;

            g.Clear(Color.White);
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

            // Move the top/left coordinates to the center of the screen
            g.ScaleTransform(1, -1);
            g.TranslateTransform(w, -h);

            // Draw X/Y axis
            g.DrawLine(Pens.Gray, 0, h, 0, -h);
            g.DrawLine(Pens.Gray, -w, 0, w, 0);

            // Draw current function
            g.DrawLine(Pens.Blue, -w, (float)DataPoint.F(-w), w, (float)DataPoint.F(w));

            // Draw user line
            if (isAdjustingParams)
            {
                using (Pen p = new Pen(Color.Green, 3)) {
                    p.DashPattern = new float[] { 4, 2 };
                    g.DrawLine(p, -w, (float)(tmpM * -w + tmpB), w, (float)(tmpM * w + tmpB));
                }
            }

            // Draw predicted function
            double x1 = -w;
            double y1 = (-brain.Weigths[2] - brain.Weigths[0] * x1) / brain.Weigths[1];
            double x2 = w;
            double y2 = (-brain.Weigths[2] - brain.Weigths[0] * x2) / brain.Weigths[1];

            g.DrawLine(Pens.Red, (float)x1, (float)y1, (float)x2, (float)y2);

            // Draw data points
            foreach (DataPoint dp in points)
            {
                dp.Render(g);

                RectangleF r = new RectangleF(dp.Point.X - dp.Size.Width / 2, dp.Point.Y - dp.Size.Height / 2, dp.Size.Width, dp.Size.Height);
                r.Inflate(-dp.Size.Width / 5, -dp.Size.Height / 5);
                using (SolidBrush sb = new SolidBrush((brain.Guess(dp.Inputs) == dp.Answer ? Color.Green : Color.Red))) {
                    g.FillEllipse(sb, r);
                }
            }

            // Legend background
            g.ResetTransform();
            using (SolidBrush sb = new SolidBrush(Color.FromArgb(230, Color.White))) {
                g.FillRectangle(sb, 0, 0, 200, (brain.Weigths.Length + 13) * 10);
            }
            using (SolidBrush sb = new SolidBrush(Color.FromArgb(32, Color.Black))) {
                g.FillRectangle(sb, 0, 0, 200, (brain.Weigths.Length + 13) * 10);
            }

            // Legend - Weights
            string rm = isDone && (DateTime.Now.Millisecond < 750) ? " √" : "";
            int    y  = 10;

            for (int i = 0; i < brain.Weigths.Length; i++)
            {
                g.DrawString($"w{i + 1} = " + $"{brain.Weigths[i]:F4}".PadLeft(9) + rm, mono, Brushes.Black, 10, y);
                y += 10;
            }

            // Legend - Equations
            y += 10;
            g.DrawString($"{DataPoint.m:F2}".PadLeft(7) + "x + " + $"{DataPoint.b:F2}".PadLeft(7), mono, Brushes.Blue, 10, y);
            y += 10;
            double m = (y2 - y1) / (x2 - x1);
            double b = y1 - m * x1;

            g.DrawString($"{m:F2}".PadLeft(7) + "x + " + $"{b:F2}".PadLeft(7), mono, Brushes.Red, 10, y);

            // Legend - Misc
            y += 10 * 2;
            g.DrawString("FPS: " + $"{++fCounter * 1000.0 / sw.ElapsedMilliseconds:F2}".PadLeft(11), mono, Brushes.Black, 10, y);
            y += 10;
            g.DrawString("Itr: " + $"{iCounter:N0}".PadLeft(8), mono, Brushes.Black, 10, y);
            y += 10;
            if (!isDone)
            {
                runTime = DateTime.Now - startTime;
            }
            g.DrawString("RnT: " + $"{runTime.Hours:00}:{runTime.Minutes:00}:{runTime.Seconds:00}.{runTime.Milliseconds:000}", mono, Brushes.Black, 10, y);

            // Legend - Help
            y += 10 * 2;
            g.DrawString("Press", mono, Brushes.Gray, 10, y);
            g.DrawString("      [ENTER]", mono, Brushes.Purple, 10, y);
            y += 10;
            g.DrawString($"To change parameters", mono, Brushes.Gray, 10, y);
        }
Beispiel #2
0
        public void UpdatePerceptron()
        {
            _guessedCorrectRight = 0;
            _guessedCorrectLeft  = 0;

            compassPos = new Vector2(compasspivot.transform.position.x, compasspivot.transform.position.y);

            if (swtchwaypointtype == 0)
            {
                /*var right = compasspivot.transform.right;
                 * right.y = 0;
                 * right *= Mathf.Sign(compasspivot.transform.up.y);
                 * var fwd = Vector3.Cross(right, Vector3.up).normalized;
                 * float pitch = Vector3.Angle(fwd, compasspivot.transform.forward) * Mathf.Sign(compasspivot.transform.forward.y);
                 */

                angle = sc_maths.ClampValue(compasspivot.transform.eulerAngles.z, 0, SC_anglesQuarterNumber);
            }
            else if (swtchwaypointtype == 1)
            {
                angle = sc_maths.ClampValue(compasspivot.transform.eulerAngles.y, 0, SC_anglesQuarterNumber);
            }
            else if (swtchwaypointtype == 2)
            {
                angle = sc_maths.ClampValue(compasspivot.transform.eulerAngles.x, 0, SC_anglesQuarterNumber);
            }



            angleRounded = Mathf.Round(angle);
            currentDiff  = (angle - angleRounded);
            currentQuarterRoundedAngle  = Mathf.Round(currentDiff * SC_Angle_Divider) / SC_Angle_Divider;
            currentQuarterRoundedAngle *= 100;
            currentQuarterRoundedAngle  = (angle * SC_Angle_Divider);
            currentQuarterRoundedAngle  = sc_maths.ClampValue(currentQuarterRoundedAngle, 0, SC_anglesQuarterNumber);

            weights = perc.GetWeights();

            if ((int)currentQuarterRoundedAngle < saveCurrentWeightForTheCurrentAngleInsideOfUnitsOf360.Length)
            {
                perc._SC_Perceptron_SetRotWeights(saveCurrentWeightForTheCurrentAngleInsideOfUnitsOf360[(int)currentQuarterRoundedAngle]);

                if (swtchwaypointtype == 0)
                {
                    Vector2 dirbulletprimerright = new Vector2(compasspivot.transform.right.x, compasspivot.transform.right.y);
                    dirbulletprimerright.Normalize();

                    Vector2 dirprimertonorthpoletransform = new Vector2(northpoletransform.position.x, northpoletransform.position.y) - new Vector2(compasspivot.position.x, compasspivot.position.y);
                    dirprimertonorthpoletransform.Normalize();

                    _dotGoal = sc_maths.Dot(dirbulletprimerright.x, dirbulletprimerright.y, dirprimertonorthpoletransform.x, dirprimertonorthpoletransform.y);

                    if (_dotGoal >= 0) // 0.001f
                    {
                        answer = 1;
                    }
                    else if (_dotGoal < 0) //-0.001f
                    {
                        answer = -1;
                    }
                }
                else if (swtchwaypointtype == 1)
                {
                    Vector2 dirbulletprimerright = new Vector2(-compasspivot.transform.right.z, compasspivot.transform.right.x);
                    dirbulletprimerright.Normalize();

                    Vector2 dirprimertonorthpoletransform = new Vector2(northpoletransform.position.x, northpoletransform.position.z) - new Vector2(compasspivot.position.x, compasspivot.position.z);
                    dirprimertonorthpoletransform.Normalize();

                    _dotGoal = sc_maths.Dot(dirbulletprimerright.x, dirbulletprimerright.y, dirprimertonorthpoletransform.x, dirprimertonorthpoletransform.y);

                    if (_dotGoal >= 0) // 0.001f
                    {
                        answer = 1;
                    }
                    else if (_dotGoal < 0)//-0.001f
                    {
                        answer = -1;
                    }
                }
                else if (swtchwaypointtype == 2)
                {
                    Vector2 dirbulletprimerright = new Vector2(compasspivot.transform.forward.z, compasspivot.transform.forward.y);
                    dirbulletprimerright.Normalize();

                    Vector2 dirprimertonorthpoletransform = new Vector2(compasspivot.position.z, compasspivot.position.y) - new Vector2(northpoletransform.position.z, northpoletransform.position.y);
                    dirprimertonorthpoletransform.Normalize();

                    _dotGoal = sc_maths.Dot(dirbulletprimerright.x, dirbulletprimerright.y, dirprimertonorthpoletransform.x, dirprimertonorthpoletransform.y);

                    if (_dotGoal >= 0) // 0.001f
                    {
                        answer = 1;
                    }
                    else if (_dotGoal < 0) //-0.001f
                    {
                        answer = -1;
                    }
                }



                if (swtchwaypointtype == 0)
                {
                    compassPos = new Vector2(compasspivot.transform.position.x, compasspivot.transform.position.y);

                    for (int i = 0; i < training.Length; i++)
                    {
                        double angleInRadians = random.Next(360) / (2 * Math.PI);

                        // randomly getting a point at the location of the compass
                        float x = (float)(0.001f * Math.Cos(angleInRadians) + compassPos.x);
                        float y = (float)(0.001f * Math.Sin(angleInRadians) + compassPos.y);

                        training[i] = new Trainer(weightsNumber, x, y, answer);
                        perc.Train(training[i].inputs, training[i].answer);
                    }
                }
                else if (swtchwaypointtype == 1)
                {
                    compassPos = new Vector2(-compasspivot.transform.position.z, compasspivot.transform.position.x);

                    for (int i = 0; i < training.Length; i++)
                    {
                        double angleInRadians = random.Next(360) / (2 * Math.PI);

                        // randomly getting a point at the location of the compass
                        float x = (float)(0.001f * Math.Cos(angleInRadians) + compassPos.x);
                        float y = (float)(0.001f * Math.Sin(angleInRadians) + compassPos.y);

                        training[i] = new Trainer(weightsNumber, x, y, answer);
                        perc.Train(training[i].inputs, training[i].answer);
                    }
                }
                else if (swtchwaypointtype == 2)
                {
                    compassPos = new Vector2(compasspivot.transform.position.z, compasspivot.transform.position.y);

                    for (int i = 0; i < training.Length; i++)
                    {
                        double angleInRadians = random.Next(360) / (2 * Math.PI);

                        // randomly getting a point at the location of the compass
                        float x = (float)(0.001f * Math.Cos(angleInRadians) + compassPos.x);
                        float y = (float)(0.001f * Math.Sin(angleInRadians) + compassPos.y);

                        training[i] = new Trainer(weightsNumber, x, y, answer);
                        perc.Train(training[i].inputs, training[i].answer);
                    }
                }



                guessedCorrect = 0;
                guessedWrong   = 0;

                turnRight = 0;
                turnLeft  = 0;

                for (int i = 0; i < training.Length; i++)
                {
                    int guess = perc.Guess(training[i].inputs);
                    //Vector2 neededPos = new Vector2(training[i].inputs[0], training[i].inputs[1]);

                    if (training[i].answer == 1)
                    {
                        turnRight++;
                    }
                    else if (training[i].answer == -1)
                    {
                        turnLeft++;
                    }

                    if (guess >= 0)
                    {
                        guessedCorrect++;
                    }
                    else
                    {
                        guessedWrong++;
                    }
                }

                if (guessedCorrect >= (training.Length * 0.5f) - errormargin || // if the guess is higher than half of training.length
                    guessedWrong >= (training.Length * 0.5f) - errormargin ||
                    guessedCorrect <= (training.Length * 0.5f) + errormargin ||
                    guessedWrong <= (training.Length * 0.5f) + errormargin)
                {
                    if (turnRight >= (training.Length * 0.5f) - errormargin ||
                        turnLeft >= (training.Length * 0.5f) - errormargin ||
                        turnRight <= (training.Length * 0.5f) + errormargin ||
                        turnLeft <= (training.Length * 0.5f) + errormargin)
                    {
                        if (turnRight > turnLeft)
                        {
                            _guessedCorrectRight++;
                        }
                        else if (turnRight < turnLeft)
                        {
                            _guessedCorrectLeft++;
                        }
                        else
                        {
                            randguess = (int)(Math.Floor(sc_maths.getSomeRandNumThousandDecimal(0, 2))); // random value between 0 and 1

                            if (randguess == 0)
                            {
                                _guessedCorrectRight++;
                            }
                            else
                            {
                                _guessedCorrectLeft++;
                            }
                            //Debug.Log("Data is too similar");
                        }
                    }
                    else
                    {
                        randguess = (int)(Math.Floor(sc_maths.getSomeRandNumThousandDecimal(0, 2))); // random value between 0 and 1

                        if (randguess == 0)
                        {
                            _guessedCorrectRight++;
                        }
                        else
                        {
                            _guessedCorrectLeft++;
                        }
                        //Debug.Log("Data is too similar");
                    }
                }
                else
                {
                    randguess = (int)(Math.Floor(sc_maths.getSomeRandNumThousandDecimal(0, 2))); // random value between 0 and 1

                    if (randguess == 0)
                    {
                        _guessedCorrectRight++;
                    }
                    else
                    {
                        _guessedCorrectLeft++;
                    }
                    //Debug.Log("Data is too similar 0");
                }
                saveCurrentWeightForTheCurrentAngleInsideOfUnitsOf360[(int)currentQuarterRoundedAngle] = perc.GetWeights();
            }
            else
            {
                Debug.Log("out of range: " + currentQuarterRoundedAngle);
            }
        }