Esempio n. 1
0
 /// <summary>
 /// Returns the average curvature of the substroke
 /// </summary>
 public double getAvgCurvature(Substroke sub)
 {
     this.arclength = new ArcLength(sub.Points);
     this.slope     = new Slope(sub.Points);
     this.curve     = new Curvature(sub.Points, arclength.Profile, slope.TanProfile);
     return(curve.AverageCurvature);
 }
Esempio n. 2
0
    void Update()
    {
        CheckInput();
        UpdateAnim();
        distance += velocity * Time.deltaTime;

        var pos = transform.position;

        float curveOffset = Curvature.Get() * Time.deltaTime * velocity * adhesion;

        pos.x -= curveOffset;

        if (left)
        {
            pos.x = pos.x - (cornerSpeed * Time.deltaTime + Mathf.Abs(curveOffset * 0.4f));
        }

        if (right)
        {
            pos.x = pos.x + (cornerSpeed * Time.deltaTime + Mathf.Abs(curveOffset * 0.4f));
        }

        pos.x = Mathf.Max(pos.x, -max);
        pos.x = Mathf.Min(pos.x, max);

        transform.position = pos;

        Distance.Set(distance);
        Velocity.Set(velocity);
    }
Esempio n. 3
0
 public Vector3[] Step(int count, Vector3[] p)
 {
     if (count <= 0)
     {
         return(p);
     }
     else
     {
         return(Step(count - 1, Curvature.Smoother(p)));
     }
 }
Esempio n. 4
0
    public void Update()
    {
        float current = multiplayer;

        for (int i = 0; i < backgrounds.Length; ++i)
        {
            var pos = positions[i];
            pos.x = pos.x + Curvature.Get() * current;
            backgrounds[i].transform.position = pos;
            current *= current;
        }
    }
Esempio n. 5
0
 public void Update()
 {
     if (!IsOnScreen())
     {
         Destroy(gameObject);
     }
     else
     {
         offset         += CalculateOffset();
         currentPosition = new Vector2(startPosition.x, startPosition.y + offset);
         perspective     = RoadCommon.PERSPECTIVE(currentPosition.y, RoadSize.Get().y);
         float distanceFromCenter = 0.5f - startPosition.x;
         currentPosition.x += RoadCommon.CURVE(Curvature.Get(), perspective) + distanceFromCenter * perspective;
         ApplyPosition(currentPosition);
     }
 }
Esempio n. 6
0
    void Update()
    {
        float distance = Distance.Get();

        material.SetFloat(CurvatureId, Curvature.Get());
        material.SetFloat(DistanceId, distance);

        var newSection = track.FindSection(distance);

        if (newSection != section)
        {
            section = newSection;
            Curvature.Next(section.curvature);
        }

        Curvature.Update(Distance.Delta());
    }
Esempio n. 7
0
    public WorldChunk(Vector2 coord, HeightMapSettings heightMapSettings, MeshSettings meshSettings, LODInfo[] detailLevels, int colliderLODIndex, Transform parent, Transform viewer, Material material, WorldSettings worldSettings)
    {
        this.viewer            = viewer;
        this.heightMapSettings = heightMapSettings;
        this.meshSettings      = meshSettings;
        this.coord             = coord;
        this.colliderLODIndex  = colliderLODIndex;
        this.detailLevels      = detailLevels;

        sampleCenter = coord * meshSettings.MeshWorldSize / meshSettings.meshScale;
        var position = coord * meshSettings.MeshWorldSize;

        bounds = new Bounds(sampleCenter, Vector2.one * meshSettings.MeshWorldSize);

        meshObject = new GameObject("World Chunk");
        //meshObject.isStatic = true;
        meshRenderer = meshObject.AddComponent <MeshRenderer>();
        meshFilter   = meshObject.AddComponent <MeshFilter>();
        meshCollider = meshObject.AddComponent <MeshCollider>();

        meshObject.transform.localScale = Vector3.one * meshSettings.meshScale;

        meshRenderer.material = material;

        meshObject.transform.position = new Vector3(position.x, 0, position.y);
        meshObject.transform.parent   = parent;
        SetVisible(false);

        lodMeshes = new LODMesh[detailLevels.Length];
        for (var i = 0; i < detailLevels.Length; i++)
        {
            lodMeshes[i] = new LODMesh(detailLevels[i].lod);
            lodMeshes[i].updateCallback += UpdateWorldChunk;
            if (i == colliderLODIndex)
            {
                lodMeshes[i].updateCallback += UpdateCollisionMesh;
            }
        }

        maxViewDst = detailLevels[detailLevels.Length - 1].visibleDistanceThreshold;

        curvature = HeightMapGenerator.GenerateWorldCurvatureMap(meshSettings.numberOfVerticesPerLine, worldSettings);
    }
Esempio n. 8
0
 private void SetTarget(Vector2 startPos, Vector2 finishPos, TimeSpan now, float durationSeconds, Curvature type)
 {
     StartPos = startPos;
     EndPos = finishPos;
     _time1 = now;
     _durationSeconds = durationSeconds;
     switch (type)
     {
         case Curvature.SlowFastSlow: _curve = SLOW_FAST_SLOW_CURVE; break;
         case Curvature.SlowFast: _curve = SLOW_FAST_CURVE; break;
         case Curvature.FastSlow: _curve = FAST_SLOW_CURVE; break;
         case Curvature.Linear: _curve = LINEAR_CURVE; break;
         case Curvature.AlmostLinear: _curve = ALMOST_LINEAR_CURVE; break;
         default: throw new ApplicationException("Unexpected curvature " + type);
     }
 }
Esempio n. 9
0
 /// <summary>
 /// Sets a new target for the movement.
 /// </summary>
 public void SetTarget(Vector2 finishPos, TimeSpan now, float durationSeconds, Curvature type)
 {
     SetTarget(Evaluate(now), finishPos, now, durationSeconds, type);
 }
Esempio n. 10
0
        /**
         * <summary>
         * <para>
         * Calculates knee points using the Kneedle algorithm. Returns the x value corresponding to the knee
         * point when successful, null otherwise.
         * </para>
         * <para>
         * Reference:
         *      Finding a ‘kneedle’in a haystack: Detecting knee points in system behavior.
         *      Satopaa, V and Albrecht, J and Irwin, D and Raghavan, B
         *      <see cref="https://raghavan.usc.edu/papers/kneedle-simplex11.pdf"/>
         * </para>
         *
         *  <list type="bullet">
         *  <param name="x">x: X axis values of the points. Points must be sorted in ascending order w.r.t. X axis.</param>
         *  <param name="y">y: Y axis values of the points.</param>
         *  <param name="direction">direction: If the curve is increasing or decreasing. Make sure to set this value according to the input curve.</param>
         *  <param name="concavity">concavity: Whether the curve has positive or negative curvature. In other words, concave or convex. Whether the tangent rotates clockwise or counterclockwise. Make sure to set this value according to the input curve.</param>
         *  <param name="sensitivity">sensitivity: Adjusts the knee detection threshold. Defaults to 1 as per the paper.</param>
         *  <param name="forceLinearInterpolation">forceLinearInterpolation: Interpolation is done using robust cubic splines. For some inputs, spline can overshoot. This param forces linear interpolation instead of cubic spline.</param>
         *  </list>
         *
         * Can return null when the algorithm fails to identify a knee/elbow for various reasons:
         *      - the number of data points is too small
         *      - there are no local maxima on the diffs, which means either the curve is a line, or the
         *        parameters provided are incompatible with the curve
         *
         *  <list type="bullet">
         *  2019-01-08: rename curvature enum to be easy to interpret and remember (Prashant Borole)
         *  2019-01-07: initial version (Prashant Borole)
         *  </list>
         *  </summary>
         */
        public static double?CalculateKneePoints(double[] x, double[] y, CurveDirection direction, Curvature concavity, double sensitivity = 1, bool forceLinearInterpolation = true)
        {
            if (x == null || y == null || x.Length != y.Length || x.Length < 2)
            {
                return(null);
            }

            var numPoints = x.Length;

            MathNet.Numerics.Interpolation.IInterpolation interpolator = null;
            if (numPoints > 5 && !forceLinearInterpolation)
            {
                interpolator = Interpolate.CubicSplineRobust(x, y);
            }
            else
            {
                interpolator = Interpolate.Linear(x, y);
            }
            var x_spaced = Generate.LinearSpaced(numPoints, x.Min(), x.Max());
            var y_spaced = Generate.Map(x_spaced, interpolator.Interpolate);

            var x_norm = MinMaxNormalize(x_spaced);
            var y_norm = MinMaxNormalize(y_spaced);

            var x_diff = x_norm;
            var y_diff = new double[numPoints];

            if (direction == CurveDirection.Decreasing)
            {
                for (int i = 0; i < numPoints; i++)
                {
                    y_diff[i] = x_norm[i] + y_norm[i];
                }
                if (concavity == Curvature.Counterclockwise)
                {
                    for (int i = 0; i < numPoints; i++)
                    {
                        y_diff[i] = 1 - y_diff[i];
                    }
                }
            }
            else
            {
                // increasing
                for (int i = 0; i < numPoints; i++)
                {
                    y_diff[i] = y_norm[i] - x_norm[i];
                }
                if (concavity == Curvature.Counterclockwise)
                {
                    for (int i = 0; i < numPoints; i++)
                    {
                        y_diff[i] = Math.Abs(y_diff[i]);
                    }
                }
            }


            // find local maxima
            var xmx_idxs = FindLocalExtrema(y_diff, true);

            if (xmx_idxs.Count == 0)
            {
                return(null);
            }
            var xmx = xmx_idxs.Select(idx => x_diff[idx]).ToArray();
            var ymx = xmx_idxs.Select(idx => y_diff[idx]).ToArray();

            // minima
            var xmn_idxs = FindLocalExtrema(y_diff, false);
            var xmn      = xmn_idxs.Select(idx => x_diff[idx]).ToArray();
            var ymn      = xmn_idxs.Select(idx => y_diff[idx]).ToArray();

            var tmx = Threshold(ymx, x_norm, sensitivity);

            // now find the knee point between each of the local maxima
            var    curMaximaIdx = 0;
            var    xmn_idxs_set = new HashSet <int>(xmn_idxs);
            double?knee         = null;

            for (int x_i = xmx_idxs[0] + 1; x_i < x.Length; x_i++)
            {
                if (curMaximaIdx < xmx_idxs.Count - 1 && x_i == xmx_idxs[curMaximaIdx + 1])
                {
                    curMaximaIdx++;
                    x_i++;
                    continue;
                }

                if (xmn_idxs_set.Contains(x_i))
                {
                    if (x_i < x.Length - 1 && y_diff[x_i + 1] > y_diff[x_i])
                    {
                        tmx[curMaximaIdx] = 0;
                    }
                }

                if (y_diff[x_i] < tmx[curMaximaIdx] || tmx[curMaximaIdx] < 0)
                {
                    knee = x[xmx_idxs[curMaximaIdx]];
                }
            }

            return(knee);
        }