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); }
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); }
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(); }
/// <summary> /// Перестройка BSpline,CSpline. /// </summary> /// <returns></returns> public bool ReBuild() { try { BSpline(); CSplinePoints = CubicSpline.FitParametric(Points); } catch { return(false); } return(true); }
/// <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); }
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); }
// 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); }
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; }
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 }
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; } } }