Пример #1
0
    Vector2[] GenerateSpline(Vector2[] keyPoints)
    {
        //Get key points into float arrays
        float[] x = new float[keyPoints.Length];
        float[] y = new float[keyPoints.Length];
        for (int i = 0; i < keyPoints.Length; ++i)
        {
            x[i] = keyPoints[i].x;
            y[i] = keyPoints[i].y;
        }

        //Get buffer to generate the spline trajectory
        float[] xs = new float[keyPoints.Length * Precision];
        float[] ys = new float[keyPoints.Length * Precision];

        //Generate the spline
        CubicSpline.FitParametric(x, y, (int)(keyPoints.Length * Precision), out xs, out ys);

        //Get all the points in vec2 form
        Vector2[] points = new Vector2[this.KeyPointCount * 2 * Precision];
        for (int i = this.KeyPointCount * Precision; i < keyPoints.Length * Precision; ++i)
        {
            points[i - this.KeyPointCount * Precision] = getPositionInScreen(new Vector2(xs[i], ys[i]));
        }

        return(points);
    }
Пример #2
0
        private void drawSplineToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (_points.Count == 0)
            {
                return;
            }

            float[] ex;
            float[] ey;


            CubicSpline.FitParametric(_points.Select(x => x.X).ToArray(), _points.Select(x => x.Y).ToArray(), _points.Count * 100, out ex, out ey);
            using (Graphics g = Graphics.FromImage(MainImage.Image))
            {
                for (int i = 1; i < _points.Count; i++)
                {
                    g.DrawLine(new Pen(Color.Green, 1), _points[i - 1], _points[i]);
                }

                for (int i = 1; i < ex.Length; i++)
                {
                    g.DrawLine(new Pen(Color.Red, 2), ex[i - 1], ey[i - 1], ex[i], ey[i]);
                }

                g.DrawCurve(new Pen(Color.Blue), _points.ToArray());
            }
            MainImage.Invalidate();
            MessageBox.Show("RED: Spline interpolation\r\nBLUE: C# Curve line\r\nGREEN: Line by points", "INFO",
                            MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
        }
Пример #3
0
        internal void ConstructPolygon()
        {
            List <CCPoint> newPoints            = new List <CCPoint>();
            List <float>   splineControlPointsX = new List <float>();
            List <float>   splineControlPointsY = new List <float>();

            // go through all control points
            // generate and collect the new points of the polygon
            for (int i = 0; i < ControlPoints.Length; i++)
            {
                // search for the start of a spline
                if (SplineControl[i] == SplineYes)
                {
                    // add this point to the list of what will belong to this spline
                    splineControlPointsX.Add(ControlPoints[i].X);
                    splineControlPointsY.Add(ControlPoints[i].Y);
                    continue;
                }
                // search for the end of a spline
                else if (SplineControl[i] > 0 || SplineControl[i] < -1)
                {
                    // end the spline
                    // first also add the point as end point of the spline
                    splineControlPointsX.Add(ControlPoints[i].X);
                    splineControlPointsY.Add(ControlPoints[i].Y);
                    // get how many segments are intended between two control points
                    int segments = Math.Abs(SplineControl[i]);
                    // then calc the spline
                    CubicSpline.FitParametric(splineControlPointsX.ToArray(), splineControlPointsY.ToArray(), segments,
                                              out float[] splineX, out float[] splineY);
                    // now add all these points to the list of new points
                    for (int j = 0; j < splineX.Length - 1; j++)
                    {
                        newPoints.Add(new CCPoint(splineX[j], splineY[j]));
                    }
                    // check if the last point should really be added (usual case)
                    // or not (in case another spline is starting there (because it will be added then)
                    if (SplineControl[i] > 0)
                    {
                        newPoints.Add(new CCPoint(splineX[splineX.Length - 1], splineY[splineY.Length - 1]));
                    }
                    // finally clear the list of collected control points
                    splineControlPointsX.Clear();
                    splineControlPointsY.Clear();
                    continue;
                }
                // else you are really not inside a spline and can just add the control point to the Points as usual
                else
                {
                    newPoints.Add(ControlPoints[i]);
                    continue;
                }
            }
            // finally give the polygon its new form
            Points = newPoints.ToArray();
        }
Пример #4
0
 /// <summary>
 /// Перестройка BSpline,CSpline.
 /// </summary>
 /// <returns></returns>
 public bool ReBuild()
 {
     try
     {
         BSpline();
         CSplinePoints = CubicSpline.FitParametric(Points);
     }
     catch { return(false); }
     return(true);
 }
Пример #5
0
 /// <summary>
 /// Перестройка BSpline,CSpline.
 /// </summary>
 /// <returns> Выполнил или нет. </returns>
 public bool ReBuild()
 {
     try
     {
         BSpline();
         Points.Add(Points[0]);
         CSplinePoints = CubicSpline.FitParametric(Points);
         Points.RemoveAt(Points.Count - 1);
     }
     catch { return(false); }
     return(true);
 }
Пример #6
0
    private static void CrearPista()
    {
        var r = new System.Random();
        int m = 500;



        Punto[] puntos = new Punto[m];
        for (int i = 0; i < m; i++)
        {
            //COORDENADAS POLARES
            puntos[i] = new Punto(Convert.ToSingle(r.NextDouble() * 125), Convert.ToSingle(r.NextDouble() * 2 * Math.PI), 1);
        }
        List <Punto> l = new List <Punto>();

        for (int i = 0; i < puntos.Length; i++)
        {
            l.Add(puntos[i]);
        }
        l.Add(puntos[0]);
        puntos = l.ToArray();
        ConvexHull   ch = new ConvexHull();
        List <float> ll = new List <float>();

        for (int i = 0; i < puntos.Length; i++)
        {
            ll.Add(puntos[i].x);
            ll.Add(puntos[i].y);
        }
        FloatArray fa = new FloatArray(ll.ToArray());

        FloatArray contorno = ch.computePolygon(fa, false);


        float[] xx;
        float[] yy;
        float[] xs, ys;
        int     n = 1000;

        desglosar(contorno, out xx, out yy);

        Punto[] convexo = Punto.CrearArregloDesdeArreglos(xx, yy);
        CubicSpline.FitParametric(xx, yy, n, out xs, out ys, 1, -1, 1, -1);


        ////////////////////////////////////// AGREGAR DIFICULTAD

        //agregarDificultad(ref convexo, 30);
        deformar(ref convexo);
        xx = Punto.getAbscisas(convexo);
        yy = Punto.getOrdenadas(convexo);
        CubicSpline.FitParametric(xx, yy, n, out xs, out ys);
    }
Пример #7
0
    // Use this for initialization
    void Start()
    {
        // Create the data to be fitted

        //initKeyballsRandom(3);
        //initKeyballsLinear(2);
        //initKeyballsDemo();
        initKeyballsSnake(5, 2);

        CubicSpline.FitParametric(keyballs, interpolationDensity, out interpolation, out dinterpolation, out ddinterpolation);

        visualizeKeypoints(keyballs);
        visualizeCenterLine();
        visualizeHull();
        //meshify();
        //testSphereCap();
    }
        public void FitParametric()
        {
            // Create the data to be fitted
            float[] x = { 0.5f, 2.0f, 3.0f, 4.5f, 3.0f, 2.0f };
            float[] y = { 4.0f, 2.0f, 6.0f, 4.0f, 3.0f, 5.0f };

            float[] xs, ys;

            CubicSpline.FitParametric(x, y, 100, out xs, out ys);

            // Specify start slope
            CubicSpline.FitParametric(x, y, 100, out xs, out ys, 1, 0);
            CubicSpline.FitParametric(x, y, 100, out xs, out ys, 0, 1);
            CubicSpline.FitParametric(x, y, 100, out xs, out ys, 1, -1);
            CubicSpline.FitParametric(x, y, 100, out xs, out ys, -1, -1);
            CubicSpline.FitParametric(x, y, 100, out xs, out ys, -1, 1);
            CubicSpline.FitParametric(x, y, 100, out xs, out ys, 1, -1, 1, 1);
            CubicSpline.FitParametric(x, y, 100, out xs, out ys, 1, -1, 1, -1);

            Assert.True(xs.Length == 100 && ys.Length == 100);
        }
Пример #9
0
    public void CrearPista(Vector3 a)
    {
        var r = new System.Random();
        int m = 500;

        Punto[] puntos = new Punto[m];
        Punto   Centro = new Punto(a.x, a.z);


        for (int i = 0; i < m; i++)
        {
            //COORDENADAS POLARES argumentos en radianes
            puntos[i]    = new Punto(125 * UnityEngine.Random.value, UnityEngine.Random.value * 2 * Mathf.PI, 1);
            puntos[i].x += Centro.x;
            puntos[i].y += Centro.y;
        }
        List <Punto> l = new List <Punto>();

        for (int i = 0; i < puntos.Length; i++)
        {
            l.Add(puntos[i]);
        }
        l.Add(puntos[0]);
        puntos = l.ToArray();
        ConvexHull   ch = new ConvexHull();
        List <float> ll = new List <float>();

        for (int i = 0; i < puntos.Length; i++)
        {
            ll.Add(puntos[i].x);
            ll.Add(puntos[i].y);
        }
        FloatArray fa       = new FloatArray(ll.ToArray());
        FloatArray contorno = ch.computePolygon(fa, false);


        float[] xx;
        float[] yy;
        float[] xs, ys;

        desglosarFloatArrayEnVectoresNormales(contorno, out xx, out yy);
        Punto[] convexo = Punto.CrearArregloDesdeArreglos(xx, yy);



        ////////////////////////////////////// AGREGAR DIFICULTAD
        float ancho = UnityEngine.Random.Range(5f, 9f);

        ancho = (isSeguidorDeLinea) ? ancho / 3 : ancho;
        Punto[] convexo2 = new Punto[convexo.Length * 2];
        if (isDeforme)
        {
            deformar(ref convexo);
        }

        separarPuntos(ref convexo);

        xx = Punto.getAbscisas(convexo);

        yy = Punto.getOrdenadas(convexo);

        CubicSpline.FitParametric(xx, yy, n, out xs, out ys, 1, -1, 1, -1);

        /////////////////////////////////////////////////////////////////////////

        /*
         * en xs y en ys estan las posiciones x,y de cada punto de la pista
         */



        LS.Add(Instantiate(this.suelo, new Vector3(0, -1, 0), Quaternion.Euler(Vector3.zero), this.transform));
        float[] angulosEnGrados = new float[n];

        for (int i = 0; i < xs.Length - 1; i++)
        {
            angulosEnGrados[i] = 180 * Mathf.Atan2(ys[i + 1] - ys[i], -xs[i + 1] + xs[i]) / Mathf.PI;
        }

        IList <Punto> listaRoja  = new List <Punto>();
        IList <Punto> listaBuena = new List <Punto>();

        Punto[] puntosInteriores;
        Punto[] puntosLinea;

        int        offset = r.Next();
        Vector3    pos, pos2 = new Vector3();
        Quaternion rot;
        float      offsetPos;
        float      offsetBuenas;// = UnityEngine.Random.Range(0.5f, ancho - 0.5f);

        for (int i = 0; i < xs.Length - 1; i++)
        {
            pos = new Vector3(xs[i], 0, ys[i]);
            rot = Quaternion.Euler(0, angulosEnGrados[i], 0);
            pared.transform.position = pos;
            pared.transform.rotation = rot;
            LPA.Add(Instantiate(pared, pos, rot, this.transform));
            if (isSeguidorDeLinea)
            {
                offsetBuenas = ancho / 4 * Mathf.Sin(i / n) - ancho / 4;
                pared.transform.Translate((ancho / 2 - offsetBuenas) * -Vector3.back, Space.Self);
                listaBuena.Add(new Punto(pared.transform.position));
                pared.transform.Translate((ancho - offsetBuenas) * -Vector3.back, Space.Self);
            }
            if (i % 10 == 0)
            {
                offsetPos = UnityEngine.Random.Range(0, ancho / 2);
                pared.transform.Translate(offsetPos * -Vector3.back, Space.Self);
                pos2 = pared.transform.position;
                pared.transform.Translate((ancho - offsetPos) * -Vector3.back, Space.Self);
                listaRoja.Add(new Punto(pared.transform.position));
            }
            else
            {
                pared.transform.Translate((ancho) * -Vector3.back, Space.Self);
                listaRoja.Add(new Punto(pared.transform.position));
            }

            if (i % 5 == 0)
            {
                pared.transform.Translate(ancho / 2 * Vector3.back, Space.Self);
                checkpoint.transform.rotation   = Quaternion.Euler(0, angulosEnGrados[i], 0);
                checkpoint.transform.position   = pared.transform.position;
                checkpoint.transform.localScale = new Vector3(0.1f, checkpoint.transform.localScale.y, ancho);
                LCH.Add(Instantiate(checkpoint, pared.transform.position, Quaternion.Euler(0, angulosEnGrados[i], 0), this.transform));
            }
            if ((UnityEngine.Random.value > 0.65f) && !isSeguidorDeLinea)
            {
                powerUp.transform.position = pos;
                powerUp.transform.rotation = rot;
                powerUp.transform.Translate(UnityEngine.Random.Range(1, ancho - 1) * Vector3.forward, Space.Self);
                LPU.Add(Instantiate(powerUp, this.transform));
            }
            if (isObstaculos)
            {
                if (UnityEngine.Random.value > 0.988f)
                {
                    obstaculo.transform.position = pos;
                    obstaculo.transform.rotation = rot;
                    obstaculo.transform.Translate(UnityEngine.Random.Range(1, ancho - 1) * Vector3.forward, Space.Self);
                    LO.Add(Instantiate(obstaculo, this.transform));
                }
            }
            posIni[i / (EvolutionManager.CarCount / 10)] = pos2;
            EvolutionManager.ini = posIni[i / (EvolutionManager.CarCount / 10)];
        }


        puntosLinea = listaBuena.ToArray();

        if (listaBuena.Count > 0)
        {
            puntosLinea[puntosLinea.Length - 1] = puntosLinea[0];
            arreglarAngulos(ref puntosLinea);
        }
        puntosInteriores = listaRoja.ToArray();
        puntosInteriores[puntosInteriores.Length - 1] = puntosInteriores[0];
        arreglarAngulos(ref puntosInteriores);

        float[] xx2, xx3;
        float[] yy2, yy3;
        float[] xs2, ys2, xs3, ys3;
        float[] angulosEnGrados2 = new float[n2];
        float[] angulosEnGrados3 = new float[n2];
        xx2 = Punto.getAbscisas(puntosInteriores);
        yy2 = Punto.getOrdenadas(puntosInteriores);


        if (isSeguidorDeLinea)
        {
            xx3 = Punto.getAbscisas(puntosLinea);
            yy3 = Punto.getOrdenadas(puntosLinea);
            CubicSpline.FitParametric(xx3, yy3, n2, out xs3, out ys3, 1, -1, 1, -1);
            for (int i = 0; i < xx3.Length; i++)
            {
                angulosEnGrados3[i] = 180 * Mathf.Atan2(ys3[i + 1] - ys3[i], -xs3[i + 1] + xs3[i]) / Mathf.PI;

                Linea.transform.rotation = Quaternion.Euler(0, angulosEnGrados3[i], 0);
                Linea.transform.position = new Vector3(xs3[i], 0, ys3[i]);
                LB.Add(Instantiate(Linea, new Vector3(xs3[i], 0, ys3[i]), Quaternion.Euler(0, angulosEnGrados3[i], 0), this.transform));
            }
        }

        CubicSpline.FitParametric(xx2, yy2, n2, out xs2, out ys2, 1, -1, 1, -1);


        for (int i = 0; i < xs2.Length - 1; i++)
        {
            angulosEnGrados2[i] = 180 * Mathf.Atan2(ys2[i + 1] - ys2[i], -xs2[i + 1] + xs2[i]) / Mathf.PI;
        }

        for (int i = 0; i < xs2.Length - 1; i++)
        {
            paredRoja.transform.rotation = Quaternion.Euler(0, angulosEnGrados2[i], 0);
            paredRoja.transform.position = new Vector3(xs2[i], 0, ys2[i]);
            LPR.Add(Instantiate(paredRoja, new Vector3(xs2[i], 0, ys2[i]), Quaternion.Euler(0, angulosEnGrados2[i], 0), this.transform));
        }
    }
        internal void CalculatePath(CCPoint startPosition, float startSlopeDx, float startSlopeDy, CCPoint endPosition, float endSlopeDx = float.NaN, float endSlopeDy = float.NaN)
        {
            //List<CCPoint> pathPoints = new List<CCPoint>();
            // fixes for numerical problems
            if (startSlopeDx < 0.0001 && 0 < startSlopeDx)
            {
                startSlopeDx = 0.001f;
            }
            if (startSlopeDx > -0.0001 && 0 > startSlopeDx)
            {
                startSlopeDx = -0.001f;
            }
            if (startSlopeDy < 0.0001 && 0 < startSlopeDy)
            {
                startSlopeDy = 0.001f;
            }
            if (startSlopeDy > -0.0001 && 0 > startSlopeDy)
            {
                startSlopeDy = -0.001f;
            }
            if (startSlopeDx == 0)
            {
                startSlopeDx = 0.001f;
            }
            if (startSlopeDy == 0)
            {
                startSlopeDy = 0.001f;
            }

            /*
             * // ALTERNATIVE METHOD:
             * // create a path that is a circular arc
             * // for this 1. find the rotational center
             * // 2. rotate the start point towards the end point around the rotational center, step by step, and add these points to the path
             *
             * // SPECIAL CASE: the path is a straight line
             * CCPoint normalizedVectorStartEnd = CCPoint.Normalize(endPosition - startPosition);
             * const float DELTA = 0.01f;
             * if (CCPoint.Distance(normalizedVectorStartEnd, new CCPoint(startSlopeDx, startSlopeDy)) < DELTA)
             * {
             *  pathPoints.Add(startPosition);
             *  pathPoints.Add(endPosition);
             * }
             *  // 1.1 solve yStart = -1/(dy/dx) * xStart + n  for n (line through start perpendicular to the start direction)
             *  // 1.2 get the midpoint between start and end
             *  // 1.3 solve yMid = -1/((endY-startY)/(endX-startX)) * xMid + n2  for n2 (line through midpoint perpendicular to the line from start to end)
             *  // 1.4 solve -1/(dy/dx) * x + n = -1/((endY-startY)/(endX-startX)) * x + n2  for x (intersection of the previous two lines, aka "the rotational center")
             *
             *  // 1.1
             *  // yStart = - dx/dy * xStart + n
             *  // yStart + dx/dy * xStart = n
             *  float n = startPosition.Y + (startSlopeDx / startSlopeDy) * startPosition.X;
             *  // 1.2
             *  CCPoint midPoint = (endPosition + startPosition) / 2;
             *  // 1.3
             *  // yMid + ((endX-startX)/(endY-startY)) * xMid = n2
             *  float n2 = midPoint.Y + ((endPosition.X - startPosition.X) / (endPosition.Y - startPosition.Y)) * midPoint.X;
             *  // 1.4
             *  // - dx/dy * x + n = - ((endX-startX)/(endY-startY)) * x + n2
             *  // - dx/dy * x + ((endX-startX)/(endY-startY)) * x = n2 - n
             *  // x = (n2 - n) / ((dx/dy) - ((endX-startX)/(endY-startY)))
             *  float xRotCenter = (n2 - n) / (((endPosition.X - startPosition.X) / (endPosition.Y - startPosition.Y)) - (startSlopeDx / startSlopeDy));
             *  float yRotCenter = -(startSlopeDx / startSlopeDy) * xRotCenter + n;
             *  CCPoint rotationPoint = new CCPoint(xRotCenter, yRotCenter);
             *
             *  // 2.1 find out whether to rotate left or right
             *  // for that rotate the start-direction-vector by 90° and by -90° and check which rotated vector is closer to the rotation point
             *  CCPoint rotatedLeft = CCPoint.RotateByAngle(new CCPoint(startSlopeDx, startSlopeDy), CCPoint.Zero, (float)Math.PI / 2) + startPosition;
             *  CCPoint rotatedRight = CCPoint.RotateByAngle(new CCPoint(startSlopeDx, startSlopeDy), CCPoint.Zero, -(float)Math.PI / 2) + startPosition;
             *  float angleSign;
             *  if (CCPoint.Distance(rotatedLeft, rotationPoint) < CCPoint.Distance(rotatedRight, rotationPoint))
             *  {
             *      // the rotation point is on your left, so rotate to the left
             *      angleSign = 1;
             *  }
             *  else
             *  {
             *      // the rotation point is on your right, so rotate to the right
             *      angleSign = -1;
             *  }
             *
             *  // ALTERNATE PATH COMPUTATION:
             *  // compute the angle between the vectors starting at the rotational center and ending in a) the startpoint b) the endpoint.
             *  // The path points are then generated by rotating the startpoint (using that point for each rotation) and increasing the angle
             *  // of rotation until it reaches the computed angle between the vectors.
             *  // The number of steps is dependent on the length of the line, calculated from the radius * the angle.
             *  float radius = CCPoint.Distance(rotationPoint, startPosition);
             *  CCPoint normalizedVectorRotStart = CCPoint.Normalize(startPosition - rotationPoint);
             *  CCPoint normalizedVectorRotEnd   = CCPoint.Normalize(endPosition - rotationPoint);
             *  float angleStart = Constants.DxDyToRadians(normalizedVectorRotStart.X, normalizedVectorRotStart.Y);
             *  float angleEnd   = Constants.DxDyToRadians(normalizedVectorRotEnd.X, normalizedVectorRotEnd.Y);
             *  // make sure angles are positive
             *  if (angleStart < 0) angleStart = (float)(2.0 * Math.PI) + angleStart;
             *  if (angleEnd < 0) angleEnd = (float)(2.0 * Math.PI) + angleEnd;
             *  // normalize the angles
             *  float angleShift = (float)(2.0 * Math.PI) - angleStart;
             *  angleEnd = (angleEnd + angleShift) % (float)(2.0 * Math.PI);
             *  float angleDestination = angleSign == 1 ? angleEnd : (float)(2.0*Math.PI) - angleEnd;
             *  //int steps = (int)(radius * angleDestination);
             *  //if (steps < 200) steps = 200;
             *  int steps = 250;
             *  for (int i=0; i < steps; i++)
             *  {
             *      CCPoint pathPoint = CCPoint.RotateByAngle(startPosition, rotationPoint, angleSign * angleDestination * ((float)i / (float)steps));
             *      pathPoints.Add(pathPoint);
             *  }
             *  pathPoints.Add(endPosition);
             * }
             */
            // SPECIAL CASE: the path is a straight line
            CCPoint     normalizedVectorStartEnd = CCPoint.Normalize(endPosition - startPosition);
            const float DELTA = 0.01f;

            if (CCPoint.Distance(normalizedVectorStartEnd, new CCPoint(startSlopeDx, startSlopeDy)) < DELTA)
            {
                Path = new CCPoint[] { startPosition, endPosition };
            }
            else
            {
                // calculate a spline
                // as the first point of the input-path add a new point
                // this point realises the start slope
                float firstX = startPosition.X - startSlopeDx;
                float firstY = startPosition.Y - startSlopeDy;
                // also create another point as the third point
                // it makes sure that the plane HAS TO MOVE a little bit in a somewhat straight way first
                float secondX = startPosition.X + 1 * startSlopeDx;
                float secondY = startPosition.Y + 1 * startSlopeDy;
                float thirdX  = startPosition.X + 10 * startSlopeDx;
                float thirdY  = startPosition.Y + 10 * startSlopeDy;

                // now calculate a special midpoint; it strongly defines the curvature of the path
                // start with the midpoint between start and end
                CCPoint midpoint = new CCPoint((endPosition.X + startPosition.X) / 2, (endPosition.Y + startPosition.Y) / 2);
                // now we need the perpendicular line going through that point (midpoint.Y = (-1/m)*midpoint.X + np) (mp = -1/m)
                float m  = (endPosition.Y - startPosition.Y) / (endPosition.X - startPosition.X);
                float mp = -1 / m;
                float np = midpoint.Y - midpoint.X * mp;
                // now get the line extending from the starting point with the startSlope (startPosition.Y = startSlope*startPosition.X + ns)
                float ns = startPosition.Y - (startSlopeDy / startSlopeDx) * startPosition.X;
                // next find the intersection point that these lines form (startSlope*x + ns = mp*x + np)
                // x*(startSlope - mp) = np - ns;
                float x = (np - ns) / ((startSlopeDy / startSlopeDx) - mp);
                float y = mp * x + np;
                // finally, as the special curvature point calculate the midpoint between the start-end-midpoint and intersection point
                float curvaturePointX = midpoint.X + ((x - midpoint.X) / 3f);
                float curvaturePointY = midpoint.Y + ((y - midpoint.Y) / 3f);
                // ADDITIONAL PROCESS FOR REFINING THIS FURTHER:
                // first get the curvature point as a vector relative to the midpoint
                CCPoint curveVector = new CCPoint(curvaturePointX - midpoint.X, curvaturePointY - midpoint.Y);
                // if it's not (0,0) (i.e. if there is any curvature at all)
                float curveFactor         = 0;
                float halfDistance        = CCPoint.Distance(startPosition, midpoint);
                float magicDistanceFactor = halfDistance / 900f < 1 ? halfDistance / 900f : 1;
                if (!curveVector.Equals(CCPoint.Zero))
                {
                    // normalize it
                    curveVector = CCPoint.Normalize(curveVector);
                    // now we need to calculate the factor by which it is to be scaled
                    // for that we calculate the scalar product of the normalized direction vector of the starting slope and the normalized direction vector from start to end point
                    float scalarProduct = CCPoint.Dot(new CCPoint(startSlopeDx, startSlopeDy), CCPoint.Normalize(new CCPoint(endPosition.X - startPosition.X, endPosition.Y - startPosition.Y)));
                    // the larger this product, the less curvature
                    curveFactor = 1 - scalarProduct;
                    //Console.WriteLine("CurveVector: " + curveVector);
                    //Console.WriteLine("CurveFactor: " + curveFactor);
                    //Console.WriteLine("Distance: " + CCPoint.Distance(startPosition, midpoint));
                    // now calculate the curvature point
                    curvaturePointX = midpoint.X + curveVector.X * curveFactor * (1.3f - 0.8f * magicDistanceFactor) * halfDistance * (curveFactor > 1 ? -1 : 1);
                    curvaturePointY = midpoint.Y + curveVector.Y * curveFactor * (1.3f - 0.8f * magicDistanceFactor) * halfDistance * (curveFactor > 1 ? -1 : 1);
                    //Console.WriteLine("Midpoint: " + midpoint);
                    //Console.WriteLine("CurvaturePoint: " + curvaturePointX + "," + curvaturePointY);
                }
                float[] xValues, yValues;
                magicDistanceFactor = halfDistance / 900f;
                if (curveFactor / magicDistanceFactor > 0.55f)
                {
                    xValues = new float[] { startPosition.X, secondX, thirdX, curvaturePointX, endPosition.X };
                    yValues = new float[] { startPosition.Y, secondY, thirdY, curvaturePointY, endPosition.Y };
                }
                else
                {
                    xValues = new float[] { startPosition.X, secondX, thirdX, endPosition.X };
                    yValues = new float[] { startPosition.Y, secondY, thirdY, endPosition.Y };
                }
                //var xValues = new float[] { startPosition.X, curvaturePointX, endPosition.X };
                //var yValues = new float[] { startPosition.Y, curvaturePointY, endPosition.Y };
                CubicSpline.FitParametric(xValues, yValues, POINTS_PER_PATH / 4, out float[] pathX1, out float[] pathY1); // startSlopeDx, startSlopeDy, endSlopeDx, endSlopeDy);
                                                                                                                          // get the point before the endpoint to adjust the curvature
                float xBeforeEnd = pathX1[pathX1.Length - 2];
                float yBeforeEnd = pathY1[pathY1.Length - 2];
                if (curveFactor / magicDistanceFactor > 0.55f)
                {
                    xValues = new float[] { startPosition.X, secondX, thirdX, curvaturePointX, xBeforeEnd, endPosition.X };
                    yValues = new float[] { startPosition.Y, secondY, thirdY, curvaturePointY, yBeforeEnd, endPosition.Y };
                }
                else
                {
                    xValues = new float[] { startPosition.X, secondX, thirdX, xBeforeEnd, endPosition.X };
                    yValues = new float[] { startPosition.Y, secondY, thirdY, yBeforeEnd, endPosition.Y };
                }
                CubicSpline.FitParametric(xValues, yValues, POINTS_PER_PATH, out float[] pathX, out float[] pathY);
                var newPath = new CCPoint[pathX.Length];

                // for the output skip the first point (start slope point)
                // and replace it with the start point
                newPath[0] = startPosition;
                for (int i = 1; i < pathX.Length; i++)
                {
                    newPath[i] = new CCPoint(pathX[i], pathY[i]);
                }
                Path = newPath;
            }

            // calculate and update the PathLength
            var pathLength = 0f;

            for (int i = 0; i < Path.Length - 1; i++)
            {
                pathLength += Constants.DistanceBetween(Path[i], Path[i + 1]);
            }
            PathLength = pathLength;
            // reset the advancement to 0
            AdvancementAsQuasiIndex = 0f;
        }
Пример #11
0
    public void CrearPista(Vector3 a)
    {
        var r = new System.Random();
        int m = 500;

        Punto[] puntos = new Punto[m];
        Punto   Centro = new Punto(a.x, a.z);


        for (int i = 0; i < m; i++)
        {
            //COORDENADAS POLARES argumentos en radianes
            puntos[i]    = new Punto(125 * UnityEngine.Random.value, UnityEngine.Random.value * 2 * Mathf.PI, 1);
            puntos[i].x += Centro.x;
            puntos[i].y += Centro.y;
        }
        List <Punto> l = new List <Punto>();

        for (int i = 0; i < puntos.Length; i++)
        {
            l.Add(puntos[i]);
        }
        l.Add(puntos[0]);
        puntos = l.ToArray();
        ConvexHull   ch = new ConvexHull();
        List <float> ll = new List <float>();

        for (int i = 0; i < puntos.Length; i++)
        {
            ll.Add(puntos[i].x);
            ll.Add(puntos[i].y);
        }
        FloatArray fa       = new FloatArray(ll.ToArray());
        FloatArray contorno = ch.computePolygon(fa, false);


        float[] xx;
        float[] yy;
        float[] xs, ys;

        desglosarFloatArrayEnVectoresNormales(contorno, out xx, out yy);
        Punto[] convexo = Punto.CrearArregloDesdeArreglos(xx, yy);



        ////////////////////////////////////// AGREGAR DIFICULTAD
        float ancho = UnityEngine.Random.Range(5f, 9f);

        Punto[] convexo2 = new Punto[convexo.Length * 2];

        deformar(ref convexo);

        separarPuntos(ref convexo);

        xx = Punto.getAbscisas(convexo);

        yy = Punto.getOrdenadas(convexo);

        CubicSpline.FitParametric(xx, yy, n, out xs, out ys, 1, -1, 1, -1);

        /////////////////////////////////////////////////////////////////////////

        /*
         * en xs y en ys estan las posiciones x,y de cada punto de la pista
         */



        LS.Add(Instantiate(this.suelo, new Vector3(0, -1, 0), Quaternion.Euler(Vector3.zero), this.transform));
        float[] angulosEnGrados = new float[n];

        for (int i = 0; i < xs.Length - 1; i++)
        {
            angulosEnGrados[i] = 180 * Mathf.Atan2(ys[i + 1] - ys[i], -xs[i + 1] + xs[i]) / Mathf.PI;
        }

        IList <Punto> listaRoja       = new List <Punto>();
        IList <Punto> listaCheckpoint = new List <Punto>();

        Punto[]    puntosInteriores;
        int        offset = r.Next();
        Vector3    pos, pos2 = new Vector3();
        Quaternion rot;

        for (int i = 0; i < xs.Length - 1; i++)
        {
            pos = new Vector3(xs[i], 0, ys[i]);
            rot = Quaternion.Euler(0, angulosEnGrados[i], 0);
            pared.transform.position = pos;
            pared.transform.rotation = rot;

            LPA.Add(Instantiate(pared, pos, rot, this.transform));
            if (i % 10 == 0)
            {
                pared.transform.Translate(ancho / 2 * -Vector3.back, Space.Self);
                pos2 = pared.transform.position;
                pared.transform.Translate(ancho / 2 * -Vector3.back, Space.Self);
                listaRoja.Add(new Punto(pared.transform.position));
            }
            else
            {
                pared.transform.Translate((ancho + Mathf.Sin(i / 10)) * -Vector3.back, Space.Self);
                listaRoja.Add(new Punto(pared.transform.position));
            }

            if (i % 5 == 0)
            {
                pared.transform.Translate(ancho / 2 * Vector3.back, Space.Self);
                checkpoint.transform.rotation   = Quaternion.Euler(0, angulosEnGrados[i], 0);
                checkpoint.transform.position   = pared.transform.position;
                checkpoint.transform.localScale = new Vector3(0.1f, checkpoint.transform.localScale.y, ancho);
                LCH.Add(Instantiate(checkpoint, pared.transform.position, Quaternion.Euler(0, angulosEnGrados[i], 0), this.transform));
            }
            if (UnityEngine.Random.value > 0.97f)
            {
                obstaculo.transform.position = pos;
                obstaculo.transform.rotation = rot;
                obstaculo.transform.Translate(UnityEngine.Random.Range(1, ancho - 1) * Vector3.forward, Space.Self);
                LO.Add(Instantiate(obstaculo, this.transform));
            }
            posIni[i / 10]       = pos2;
            EvolutionManager.ini = posIni[i / 10];
        }


        puntosInteriores = listaRoja.ToArray();
        puntosInteriores[puntosInteriores.Length - 1] = puntosInteriores[0];
        arreglarAngulos(ref puntosInteriores);

        Punto[] PC = listaCheckpoint.ToArray();
        float[] xx2;
        float[] yy2;
        float[] xs2, ys2;
        float[] angulosEnGrados2 = new float[n2];
        float[] angulosEnGrados3 = new float[n / 10];
        xx2 = Punto.getAbscisas(puntosInteriores);
        yy2 = Punto.getOrdenadas(puntosInteriores);
        CubicSpline.FitParametric(xx2, yy2, n2, out xs2, out ys2, 1, -1, 1, -1);

        for (int i = 0; i < xs2.Length - 1; i++)
        {
            angulosEnGrados2[i] = 180 * Mathf.Atan2(ys2[i + 1] - ys2[i], -xs2[i + 1] + xs2[i]) / Mathf.PI;
        }

        for (int i = 0; i < xs2.Length - 1; i++)
        {
            paredRoja.transform.rotation = Quaternion.Euler(0, angulosEnGrados2[i], 0);
            paredRoja.transform.position = new Vector3(xs2[i], 0, ys2[i]);
            LPR.Add(Instantiate(paredRoja, new Vector3(xs2[i], 0, ys2[i]), Quaternion.Euler(0, angulosEnGrados2[i], 0), this.transform));
        }
        //Cuando lee esta variable, los autos van a estar creados para una pista vieja

        ////////////////////////////////////7
    }
Пример #12
0
        void CalculateAndDrawLines()
        {
            float[] xs = new float[_NotesXValues.Count];                       // list of x values
            Dictionary <float, String> ids = new Dictionary <float, String>(); // map x to id

            Vector2 vLastLeft  = new Vector2(-100, 0);
            Vector2 vLastRight = vLastLeft;

            _posYears.Clear();
            _years.Clear();

            _txlistNotes.Clear();
            _posListNotes.Clear();

            // build: xs to hold x values
            //        dIds to hold x->id
            int m = 0;

            foreach (var n in _NotesXValues)
            {
                float x = (float)Math.Round(n.Value, ROUND);

                xs[m++] = x; // note x values

                if (ids.ContainsKey(x) == false)
                {
                    ids.Add(x, n.Key); // note id foreach x value
                }
            }

            Array.Sort(xs);

            // now we've the x values and we know which x value is which note...

            for (int j = 0; j < xs.Length - 1; ++j) // draw from left to right - xs is sorted
            {
                float left, right;

                left  = xs[j];
                right = xs[j + 1];

                float width = right - left;
                float h     = posLnZero.Y - 25;

                if (width > 22)
                #region draw parametric line
                {
                    // draw parametric line

                    // Ranges for line
                    float   half = left + width / 2;
                    float[] ixs  = { left, half, right };
                    float[] iys  = { posLnZero.Y, h, posLnZero.Y };

                    float[] xout, yout;

                    int nOutputPoints = (int)Math.Max(10, Math.Round(width / 4, 0));

                    CubicSpline.FitParametric(ixs, iys, nOutputPoints, out xout, out yout);

                    for (int k = 0; k < xout.Length - 1; ++k)
                    {
                        Vector2 pt1 = new Vector2(xout[k], yout[k]);
                        Vector2 pt2 = new Vector2(xout[k + 1], yout[k + 1]);

                        DrawLine(pt1, pt2, _clrGlobal);
                    }

                    // draw years

                    Vector2 pt = new Vector2(left + width / 2, posLnZero.Y - 25 - 14); //todo magic

                    _posYears.Add(pt);

                    // The current left, right x-values

                    float a = left;
                    float b = right;

                    if (ids.ContainsKey(a) && ids.ContainsKey(b))
                    {
                        //String[] id = { ids[a], ids[b] }; // note ids

                        TimeSpan   ts;
                        DateTime[] dts = { _Notes[ids[a]].dtUnified, _Notes[ids[b]].dtUnified };

                        if (dts[0] > dts[1])
                        {
                            ts = dts[0] - dts[1];
                        }
                        else
                        {
                            ts = dts[1] - dts[0];
                        }

                        DateTime dt = DateTime.MinValue + ts;
                        _years.Add(Math.Max(1, dt.Year - 1));

                        DateTime dtLeft  = dts[0];
                        DateTime dtRight = dts[1];

                        if (dtLeft.Year != yearprev)
                        {
                            TexXyz texLeft = new TexXyz();
                            texLeft.LoadContent_CAS_SizeM_UnsignedX(_mgr.GraphicsDevice, _sb, _mgr.Content);
                            texLeft.Update(dtLeft.Year);

                            _txlistNotes.Add(texLeft);
                            _posListNotes.Add(new Vector2(left, posNotes.Y));
                        }

                        TexXyz texRight = new TexXyz();
                        texRight.LoadContent_CAS_SizeM_UnsignedX(_mgr.GraphicsDevice, _sb, _mgr.Content);
                        texRight.Update(dtRight.Year);

                        _txlistNotes.Add(texRight);
                        _posListNotes.Add(new Vector2(right, posNotes.Y));

                        yearprev = dtRight.Year;
                    }
#if DEBUG
                    else
                    {
                        Debug.WriteLine("Internal error CwaNoteStatsImage CalculateDrawLines missing key");
                    }
#endif
                } // if draw
                #endregion
                else
                {
                    // curve is too small, so just draw a small line
                    DrawLine(new Vector2(left, posLnZero.Y), new Vector2(right, posLnZero.Y), _clrGlobal);
                }
            }

            for (int i = 1; i < _posListNotes.Count; ++i)
            {
                float w = _posListNotes[i].X - _posListNotes[i - 1].X;

                if (w < 30)
                {
                    Vector2 left = _posListNotes[i];
                    left.X          += 7;
                    _posListNotes[i] = left;

                    Vector2 right = _posListNotes[i - 1];
                    right.X -= 7;
                    _posListNotes[i - 1] = right;
                }
            }

            // calculate the years difference textures

            _txYearsDif = new TexXyz[_years.Count];

            for (int w = 0; w < _years.Count; ++w)
            {
                if (_years[w] > 0)
                {
                    _txYearsDif[w] = new TexXyz();
                    _txYearsDif[w].LoadContent_CAS_SizeM_UnsignedX(_mgr.GraphicsDevice, _sb, _mgr.Content);
                    _txYearsDif[w].Update(_years[w]);
                    bool updated = _txYearsDif[w].UpdateConsume;
                }
            }
        }