Beispiel #1
0
    public void CalculateBends()
    {
        if (!IsCircular)
        {
            return;
        }
        Bends = new CircleList <Bend>();
        Bend           _bend      = new Bend();
        int            BendId     = 0;
        MovingAvgFloat AngleQueue = new MovingAvgFloat(5);

        _bez = BezierLine.Instance;
        int      XSecCount = XSecs.Count();
        Vector3  PrevMid;
        Vector3  ThisMid;
        Vector3  NextMid;
        BendType _bt            = BendType.Unknown;
        BendType _prevbt        = BendType.Unknown;
        int      Incr           = 1;
        float    AngleThreshold = 1.34f;

        foreach (XSec X in XSecs)
        {
            PrevMid = XSecs.Prev(X).MidPt;
            ThisMid = X.MidPt;
            NextMid = XSecs.Next(X).MidPt;
            float Angle    = VectGeom.SignedAngle(ThisMid + ThisMid - PrevMid, ThisMid, NextMid, Vector3.up);
            float _segDist = Vector3.Distance(ThisMid, NextMid);
            AngleQueue.Push(Angle);
            if (Mathf.Abs(AngleQueue.Avg) < AngleThreshold)
            {
                _bt = BendType.Straight;
            }
            else
            {
                _bt = AngleQueue.Avg > 0 ? BendType.Right : BendType.Left;
            }

            if (_prevbt == _bt)
            {
                _bend.Angle += Angle;
            }
            else
            {
                if (_prevbt == BendType.Left || _prevbt == BendType.Right)
                {  //Finish off the previous bend
                    if (Mathf.Abs(_bend.Angle) < 15)
                    {
                        //ignore small bends
                        Bends.Remove(_bend);
                        BendId--;
                    }
                    else
                    {
                        //take 2 off cos of moving avg
                        _bend.EndXSec    = XSecs[X.Idx - 2];
                        _bend.EndSegIdx  = _bend.EndXSec.Idx;
                        _bend.ApexXSec   = XSecs[_bend.StartSegIdx + Mathf.RoundToInt(XSecs.Diff(_bend.StartXSec, _bend.EndXSec) / 2)];
                        _bend.ApexSegIdx = _bend.ApexXSec.Idx;
                        if (_bend.Type == BendType.Right)
                        {
                            _bend.ApexPos = _bend.ApexXSec.KerbR + (_bend.ApexXSec.KerbL - _bend.ApexXSec.KerbR).normalized; _bend.MinTurninPos = _bend.StartXSec.KerbR + (_bend.StartXSec.KerbL - _bend.StartXSec.KerbR).normalized * (_bend.Concatenated ? 4 : 2);
                        }
                        if (_bend.Type == BendType.Left)
                        {
                            _bend.ApexPos = _bend.ApexXSec.KerbL + (_bend.ApexXSec.KerbR - _bend.ApexXSec.KerbL).normalized; _bend.MinTurninPos = _bend.StartXSec.KerbL + (_bend.StartXSec.KerbR - _bend.StartXSec.KerbL).normalized * (_bend.Concatenated ? 4 : 2);
                        }
                        //Fmax = mv^2/r
                        float c = (_bend.EndSegIdx - _bend.StartSegIdx) * 360 / _bend.Angle;
                        float r = Mathf.Abs(c) / Mathf.PI / 2f;
                        //Debug.Log("Bend" + _bend.BendId + " radius = " + r);
                        _bend.SqrtRad = Mathf.Sqrt(r);
                    }
                }
                else
                {   //We might be starting a new bend or carrying n the previous one
                    if (_bt == BendType.Left || _bt == BendType.Right)
                    {
                        bool StartNewBend = true;

                        if (BendId > 0 && X.Idx - Bends[BendId - 1].EndSegIdx < 15 && Bends[BendId - 1].Type == _bt) ///bugbugbug circle bug
                        {                                                                                            //if the bend we've just finished is close to and the same sign as one before
                          //We just carry on with this bend and dont create a new one
                            StartNewBend       = false;
                            _bend.Concatenated = true;
                            GameObject.Destroy(GameObject.Find("Turnin" + _bend.BendId));
                            GameObject.Destroy(GameObject.Find("Apex" + _bend.BendId));
                            GameObject.Destroy(GameObject.Find("BendStart" + _bend.BendId));
                        }

                        if (StartNewBend)
                        {
                            //Create a new Bend
                            _bend             = new Bend();
                            _bend.Type        = _bt;
                            _bend.Sign        = _bt == BendType.Right ? (Int16)1 : (Int16)(-1);
                            _bend.StartXSec   = XSecs[X.Idx - 2];//-2 cos of moving avg
                            _bend.StartSegIdx = _bend.StartXSec.Idx;
                            _bend.Angle       = Angle;
                            _bend.BendId      = BendId;
                            Bends.Add(_bend);
                            BendId++;
                        }
                    }
                }
                //******************************************************************************************
            }
            _prevbt = _bt;
        }
        //This is the last bend. NOt a brilliant bit but it doesn't crash
        if (_bt == BendType.Straight)
        {
            goto Finalise;
        }
        _bend.EndSegIdx = XSecs.Count - 1;
        _bend.EndXSec   = XSecs[_bend.EndSegIdx];
        if (_bend.EndSegIdx <= _bend.StartSegIdx && Bends.Count() > 0)
        {
            Bends.Remove(_bend); Bends.Last().EndSegIdx = XSecs.Count;
        }
        else
        {
            _bend.ApexSegIdx = Mathf.RoundToInt((_bend.EndSegIdx + _bend.StartSegIdx) / 2);
            _bend.ApexXSec   = XSecs[_bend.ApexSegIdx];
            if (_bend.Type == BendType.Right)
            {
                _bend.ApexPos = _bend.ApexXSec.KerbR + (_bend.ApexXSec.KerbL - _bend.ApexXSec.KerbR).normalized;
            }
            if (_bend.Type == BendType.Left)
            {
                _bend.ApexPos = _bend.ApexXSec.KerbL + (_bend.ApexXSec.KerbR - _bend.ApexXSec.KerbL).normalized;
            }
        }
Finalise:
        CalculateTurninAndExitPoints();
        PopulateXSecCurrBends();
    }