Exemple #1
0
        public CurveEffect CreateDefaultCurveEffect(
            string name,
            bool isEnabled,
            IColorProvider colorProvider,
            int areaStartPosition,
            int areaLength,
            int effectLength,
            float speed,
            float intensity = 1)
        {
            Curve curve = new Curve();

            curve.AddPoint(0, 0, 0);
            curve.AddPoint(0.2, 1, 0);
            curve.AddPoint(1, 0, 0);
            var interpolator = CubicSpline.InterpolateHermite(curve.X.ToArray(), curve.Y.ToArray(), curve.W.ToArray());

            return(new CurveEffect(neoPixelSetup, colorProvider, interpolator)
            {
                Name = name,
                IsEnabled = isEnabled,
                AreaStartPosition = areaStartPosition,
                AreaLength = areaLength,
                EffectLength = effectLength,
                Speed = speed,
                Intensity = intensity
            });
        }
Exemple #2
0
    public Curve CreateChaikinCurve(Curve initial_curve, float u, float v, int nb_iteration)
    {
        Vector3 p1, p2, u_director, new_p1, new_p2;
        Curve   tmp_polygon_line = initial_curve;
        Curve   curve            = new Curve();

        curve.AddPoint(tmp_polygon_line.points[0].position, point);
        for (int i = 0; i < tmp_polygon_line.points.Count - 1; i++)
        {
            p1         = tmp_polygon_line.points[i].position;
            p2         = tmp_polygon_line.points[i + 1].position;
            u_director = p2 - p1;
            //Debug.Log("u_director : " + u_director);
            new_p1 = new Vector3(p1.x + u_director.x * u, p1.y + u_director.y * u, p1.z + u_director.z * u);
            //Debug.Log("new_p1 = " + new_p1);
            //AddPointOnChaikinCurve(], new_p1, "P");
            AddPointOnChaikinCurve(curve, new_p1, "P");
            new_p2 = new Vector3(p1.x + u_director.x * (1 - v), p1.y + u_director.y * (1 - v), p1.z + u_director.z * (1 - v));
            //Debug.Log("new_p2 = " + new_p2);
            //AddPointOnChaikinCurve(tmp_chaikin_curve, new_p2, "P");
            AddPointOnChaikinCurve(curve, new_p2, "P");
        }
        curve.AddPoint(tmp_polygon_line.points[tmp_polygon_line.points.Count - 1].position, point);
        nb_iteration--;
        if (nb_iteration != 0)
        {
            curve = CreateChaikinCurve(curve, u, v, nb_iteration);
        }
        return(curve);
        //tmp_polygon_line = curve;
    }
Exemple #3
0
 public override void InitModule()
 {
     if (curve == null)
     {
         curve = new Curve();
         curve.AddPoint(Vector2.Zero, 0, 0, Curve.TangentMode.Linear, Curve.TangentMode.Linear);
         curve.AddPoint(Vector2.One, 0, 0, Curve.TangentMode.Linear, Curve.TangentMode.Linear);
     }
 }
 public override void _EnterTree()
 {
     if (curve == null)
     {
         curve = new Curve();
         curve.AddPoint(Vector2.Zero, 0, 0, Curve.TangentMode.Linear, Curve.TangentMode.Linear);
         curve.AddPoint(Vector2.One, 0, 0, Curve.TangentMode.Linear, Curve.TangentMode.Linear);
         EmitSignal("CurveChanged", curve);
     }
     curve.Connect("changed", this, "OnCurveChanged");
     defaultFont = new Control().GetFont("font");
 }
Exemple #5
0
    protected BWProcessor()
    {
        red = 0.4f;
        green = 0.3f;
        blue = 0.3f;

        contrastCurve = new Curve (0.0f, 1.0f);
        contrastCurve.AddPoint (0.0f, 0.0f);
        contrastCurve.AddPoint (1.0f, 1.0f);

        tintHue = 23.0f;
        tintAmount = 0.1f;
    }
Exemple #6
0
    public override void _Ready()
    {
        _world = (World)GetNode("/root/World");
        _light = (Light2D)GetNode("Light2D");

        var mat = (ParticlesMaterial)ProcessMaterial;

        _sound = (AudioStreamPlayer)FindNode("ExtinguishSound");

        var gradient = new Gradient();

        gradient.AddPoint(2048 * 0.0f, new Color(255, 0, 0));
        gradient.AddPoint(2048 * 0.2f, new Color(255, 90, 0));
        gradient.AddPoint(2048 * 0.4f, new Color(255, 109, 0));
        gradient.AddPoint(2048 * 0.6f, new Color(255, 154, 0));
        gradient.AddPoint(2048 * 0.8f, new Color(255, 206, 0));
        gradient.AddPoint(2048 * 1.0f, new Color(255, 226, 6));

        var gradientTex = new GradientTexture();

        gradientTex.SetGradient(gradient);
        gradientTex.SetWidth(2048);

        var scale = new Curve();

        scale.AddPoint(new Vector2(0.0f, 1.0f));
        scale.AddPoint(new Vector2(1.0f, 0.5f));

        var scaleTex = new CurveTexture();

        scaleTex.SetCurve(scale);

        var matCopy = new ParticlesMaterial()
        {
            EmissionShape        = ParticlesMaterial.EMISSION_SHAPE_SPHERE,
            EmissionSphereRadius = 10,
            FlagDisableZ         = true,
            Spread                = 180,
            Gravity               = new Vector3(0, -98, 0),
            InitialVelocity       = 2,
            InitialVelocityRandom = 1,
            AngularVelocity       = 10,
            RadialAccel           = -15,
            Scale      = 3,
            ColorRamp  = gradientTex,
            ScaleCurve = scaleTex
        };

        this.ProcessMaterial = matCopy;
    }
Exemple #7
0
    public void AddPointOnChaikinCurve(Curve curve, Vector3 position, string name)
    {
        GameObject new_point = Instantiate(point, position, Quaternion.identity);

        new_point.transform.position = position;
        curve.AddPoint(new_point.transform.position, point);
    }
    // Declare member variables here. Examples:
    // private int a = 2;
    // private string b = "text";

    // Called when the node enters the scene tree for the first time.
    public override void _Ready()
    {
        Curve.AddPoint(new Vector2(0, 0));
        Curve.AddPoint(new Vector2(480, 0));
        Curve.AddPoint(new Vector2(480, 720));
        Curve.AddPoint(new Vector2(0, 720));
    }
Exemple #9
0
            public SomeCurveData(MyCurveData referenceCurve, string name, Vector3 position, BGCurveBaseMath.Config config)
                : base(new GameObject(name), referenceCurve.LineRendererMaterial, Color.magenta)
            {
                this.referenceCurve = referenceCurve;

                //game object
                GameObject.transform.parent     = referenceCurve.GameObject.transform.parent;
                GameObject.transform.localScale = localScale;
                GameObject.transform.position   = position;
                origin = position;

                //curve
                Curve        = GameObject.AddComponent <BGCurve>();
                Curve.Closed = referenceCurve.Curve.Closed;

                //add points
                for (var i = 0; i < referenceCurve.Curve.PointsCount; i++)
                {
                    Curve.AddPoint(referenceCurve.Curve[i].CloneTo(Curve));
                }

                //init math after points are added
                Math = new BGCurveBaseMath(Curve, config);

                AddObjects(ObjectsCount, referenceCurve.ObjectToMove, referenceCurve.Curve.transform.parent);
            }
Exemple #10
0
        void mGraphingTimer_Tick(object sender, EventArgs e)
        {
            if (mTimerTotalTicks < mNumTicksPerSec * mTimeTrackTotal)
            {
                float ticks = mTimerTotalTicks * (1 / mNumTicksPerSec);
                Point tempPoint;
                if (mCurrentModeState == ModeState.MatchingMode)
                {
                    tempPoint = CalculateDistance();
                    mDistanceCurve.AddPoint(tempPoint, mGraphPlot);
                    mTimerTotalTicks++;
                }
                else
                {
                    tempPoint = CalculateDistance();
                    mDistanceCurve.AddPoint(tempPoint, mGraphPlot);
                    mCurrentSelectedCurve = mDistanceCurve;
                    mWindow.TableListBox.Items.Add(Truncate(tempPoint.X) + "\t" + Truncate(tempPoint.Y));
                    double curDist = tempPoint.Y;

                    tempPoint = CalculateVelocity(curDist);
                    mVelocityCurve.AddPoint(tempPoint, mGraphPlot);
                    double curVel = tempPoint.Y;

                    tempPoint = CalculateAcceleration(curVel);
                    mAccelerationCurve.AddPoint(tempPoint, mGraphPlot);



                    mTimerTotalTicks++;
                    mPreviousVel  = curVel;
                    mPreviousDist = mCurrentJoint.Position.Z;
                }
            }
            else
            {
                if (mGraphingTimer != null)
                {
                    mGraphingTimer.Stop();
                    mGraphingTimer.IsEnabled = false;
                }
                mTimerTotalTicks = 0;
            }

            mWindow.theGraphPlot.Refresh(true);
        }
        /// <summary>
        /// 最低工作压力试验
        /// </summary>
        private void MinworkingPreTest()
        {
            while (this.当前流量绝对值 > 2f)
            {
                Pause(1000);
            }
            if (System.Windows.Forms.MessageBox.Show("是否已调整减压阀的设定压力值为最小", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
            {
                CurvePanel panel = new CurvePanel();
                panel.Title  = TestType.最低工作压力试验.ToString() + "曲线";
                panel.XLabel = "流量(L/min)";
                panel.YLabel = "压力(MPa)";

                this.SetCircuitState(CircuitState.PBOut); //设置球阀状态,出口流量检测
                this.SetThrottleValve(100f);              //设置比例方向阀13/14.1/14.2的位置(右位开口最大)
                this.SetSourcePre(this.额定压力);
                this.SetSourceFlow(this.额定流量 + 10f);
                Pause(15000);
                const int div_cnt     = 20;
                const int measure_cnt = 10;
                float     delta_q     = (float)(this.额定流量 / div_cnt);
                float     flow        = 0;
                float     pressure_B  = 0;
                int       repeat_cnt  = 0;

                Curve curve = new Curve();
                panel.AddCurve(curve);
                curve.Name = repeat_cnt++.ToString();
                for (int i = 0; i <= div_cnt; i++)
                {
                    this.SetSourceFlow(i * delta_q);

                    //读取压力流量数据
                    flow       = 0;
                    pressure_B = 0;
                    for (int j = 0; j < measure_cnt; j++)
                    {
                        Pause(500);
                        flow       += Math.Abs(this.当前流量绝对值 / measure_cnt);
                        pressure_B += this.当前B口压力 / measure_cnt;
                    }
                    //将数据添加到曲线
                    curve.AddPoint(flow, pressure_B);
                }
                this.SetSourcePre(0);
                this.SetSourceFlow(0);
                this.SetThrottleValve(50f);
                this.dictCurvePanel.Remove(panel.Title);
                this.dictCurvePanel.Add(panel.Title, panel);
            }
            else
            {
                this.log.Debug("未将工作压力值置最小,试验结束");
            }
        }
 public void InsertAt(int index, double retentionTime, double intensity)
 {
     Curve.AddPoint(0, 0);
     for (int j = Curve.NPts - 1; j > index; j--)
     {
         Curve.Points[j].X = Curve.Points[j - 1].X;
         Curve.Points[j].Y = Curve.Points[j - 1].Y;
     }
     Curve.Points[index].X = retentionTime;
     Curve.Points[index].Y = intensity;
 }
        /// <summary>
        /// 等待油口B的压力上升到设定压力的50%
        /// </summary>
        /// <param name="pressure"></param>
        //public void WaitPressureBUntil(float pressure)
        //{
        //    while (Group["B口压力"] <= 0.5 * pressure)
        //    {
        //        System.Threading.Thread.Sleep(1000);
        //    }
        //    System.Threading.Thread.Sleep(2000);
        //}
        ///// <summary>
        ///// 等待油口A的压力上升到设定压力的50%
        ///// </summary>
        ///// <param name="pressure"></param>
        //public void WaitPressureSUntil(float pressure)
        //{
        //    while (Group["A口压力"] <= 0.5 * pressure)
        //    {
        //        System.Threading.Thread.Sleep(1000);
        //    }
        //    System.Threading.Thread.Sleep(2000);
        //}

        /// <summary>
        /// 稳态压差实验-单一状态
        /// </summary>
        /// <param name="dictCurve">由曲线名字和曲线构成的字典</param>
        /// <param name="state">球阀状态,也即液控单向阀液流方向</param>
        /// <param name="pa_pressure">控制油压力</param>
        private void SteadystatePreeesureSingleSide(Dictionary <string, Curve> dictCurve, CircuitState state, float pa_pressure)
        {
            if (state != CircuitState.ABOut && state != CircuitState.BAOut)
            {
                return;
            }
            string key   = state.ToString() + "-控制油" + pa_pressure.ToString() + "MPa";
            Curve  curve = new Curve();

            curve.Name = key;
            dictCurve.Add(key, curve);

            this.SetCircuitState(state);
            this.SetThrottleValve(100f);
            this.SetTestValveState(TestValveState.右位);
            this.SetValve4(10f);
            this.SetPaPressure(pa_pressure);//设置先导油的压力
            this.SetSourcePre(this.额定压力);
            float max_flow = (float)(this.额定流量);

            this.SetSourceFlow(0);
            Pause(3000);
            const int div_cnt     = 20;
            const int measure_cnt = 10;
            float     pressure_A  = 0;
            float     pressure_B  = 0;
            float     delta_q     = (float)(max_flow / div_cnt);
            float     flow        = 0;

            for (int i = 0; i <= div_cnt; i++)
            {
                this.SetSourceFlow(i * delta_q);

                //读取压力流量数据
                flow       = 0;
                pressure_A = 0;
                pressure_B = 0;
                for (int j = 0; j < measure_cnt; j++)
                {
                    Pause(1000);
                    flow       += this.当前流量绝对值 / measure_cnt;
                    pressure_A += this.当前A口压力 / measure_cnt;
                    pressure_B += this.当前B口压力 / measure_cnt;
                }
                //将数据添加到曲线
                curve.AddPoint(flow, Math.Abs(pressure_A - pressure_B));
            }

            this.SetSourcePre(0);
            this.SetSourceFlow(0);
            this.SetThrottleValve(50f);
        }
Exemple #14
0
        public override void UnSerializeModule(Godot.Collections.Dictionary data)
        {
            Curve newCurve = (Curve)data["curve"];

            curve = new Curve();
            for (int i = 0; i < newCurve.GetPointCount(); i++)
            {
                curve.AddPoint(
                    newCurve.GetPointPosition(i), newCurve.GetPointLeftTangent(i),
                    newCurve.GetPointRightTangent(i), newCurve.GetPointLeftMode(i), newCurve.GetPointRightMode(i)
                    );
            }
            sizeMultiplier = (float)data["sizeMultiplier"];
        }
            public CurveData(TestCurves testCurves, string name, string description, Vector3 position, BGCurveBaseMath.Config config, MathTypeEnum mathType)
                : base(new GameObject(name), testCurves.LineRendererMaterial, Color.magenta)
            {
                this.testCurves  = testCurves;
                this.description = description;

                //game object
                GameObject.transform.position = position;
                origin = position;

                //curve
                Curve        = GameObject.AddComponent <BGCurve>();
                Curve.Closed = testCurves.Curve.Closed;

                //add points
                for (var i = 0; i < testCurves.Curve.PointsCount; i++)
                {
                    var point      = testCurves.Curve[i];
                    var clonePoint = new BGCurvePoint(Curve, point.PositionLocal, point.ControlType, point.ControlFirstLocal, point.ControlSecondLocal);
                    Curve.AddPoint(clonePoint);
                }

                //init math after points are added
                switch (mathType)
                {
                case MathTypeEnum.Base:
                    Math = new BGCurveBaseMath(Curve, config);
                    break;

                case MathTypeEnum.Formula:
#pragma warning disable 0618
                    Math = new BGCurveFormulaMath(Curve, config);
#pragma warning restore 0618

                    break;

                case MathTypeEnum.Adaptive:
                    Math = new BGCurveAdaptiveMath(Curve, (BGCurveAdaptiveMath.ConfigAdaptive)config);
                    break;

                default:
                    throw new ArgumentOutOfRangeException("mathType", mathType, null);
                }

                AddObjects(ObjectsCount, testCurves.ObjectToMove, GameObject.transform);

                //scale down
                GameObject.transform.localScale = originalScale;
            }
        public void CreateCurves()
        {
            /* not used
             * if (StartTime == 35915)
             * {
             *  int u = 0;
             * }*/

            this.Curves = new List <Curve>();
            int n = this.Points.Count;

            if (n == 0)
            {
                return;
            }
            Point2 lastPoint    = this.Points[0];
            Curve  currentCurve = null;

            for (int i = 0; i < n; i++)
            {
                // if there are two points in a row that are the same control point then it is a red control point
                // and a new curve exists
                if (lastPoint.Equals(this.Points[i]))
                {
                    currentCurve = this.CreateCurve();
                    this.Curves.Add(currentCurve);
                }
                currentCurve.AddPoint(this.Points[i].ToVector2());
                lastPoint = this.Points[i];
            }
            this._TotalLength = 0;
            int lastIndex = this.Curves.Count - 1;

            for (int i = 0; i < lastIndex; i++)
            {
                this.Curves[i].Init();
                this._TotalLength += this.Curves[i].Length;
            }
            if (lastIndex >= 0)
            {
                // the last curve will be affected by the 'pixel length' property of sliders which
                // limit how long it is (so that way it ends in time with the beat, not geometrically)
                Curve lastCurve = this.Curves[lastIndex];
                lastCurve.PixelLength = this.PixelLength - this._TotalLength;
                lastCurve.Init();
                this._TotalLength += lastCurve.Length;
            }
        }
        /*        Curve curve = new Curve();
         *      curve .Name ="液控单向阀最小控制压力曲线";
         *      panel.AddCurve(curve);
         *      this.SetCircuitState(CircuitState.ATIn);
         * //     this.SetCircuitState(CircuitState.BAOut);
         *      this.SetThrottleValve(100f);//设置比例方向阀13/14.1/14.2的位置(右位开口最大)
         *      this.SetValve4(0f); ;//设置比例减压阀4的压力值为0
         *      this.SetPaPressure((float)(5*this.开启压力));//设置先导控制油压力,暂定16
         *      //2改为5倍开启压力
         *      //在操作面板上显示配置界面用户配置最大设定压力和被试流量
         *      //FormMinControlPress frm_minconpress = new FormMinControlPress("请输入实验压力",(float)this.额定压力);
         *      FormMinControlPress frm_minconpress = new FormMinControlPress("请输入试验压力", (float)this.额定压力);
         *      frm_minconpress.ShowDialog();
         *      this.SetSourcePre(frm_minconpress.ret);
         *      if(frm_minconpress.DialogResult == DialogResult.OK)
         *      {
         *          LOG.Debug("压力填写完毕");
         *          bool need_test = true;
         *          while(need_test)
         *          {
         *              FormMinControlPress frm_setflow = new FormMinControlPress("请输入试验流量",(float)this.额定流量);
         *              need_test = frm_setflow.ShowDialog()==DialogResult.OK;
         *              if(!need_test)
         *                  return;
         *              LOG.Debug("流量填写完毕");
         *              this.SetSourceFlow(frm_setflow.ret);
         *              this.WaitPressureUntil(frm_minconpress.ret);
         *              const int div_cnt = 20;
         *              for (int i = 0; i < div_cnt; i++)
         *              {
         *                  this.SetValve4(i *(float) (this.开启压力 / div_cnt));
         *                  System.Threading.Thread.Sleep(3000);
         *                  if (Math.Abs(Math.Abs(Group[selectedFlowmeter]) - frm_setflow.ret) <= 0.5)
         *                  {
         *                      curve.AddPoint(frm_setflow.ret, this.Pa口传感器压力);
         *                      break;
         *                  }
         *
         *              }
         *          }
         *
         *      }
         *      else
         *      {
         *
         *          MessageBox.Show("退出实验");
         *      }
         *      this.SetSourcePre(0);
         *      this.SetSourceFlow(0);
         *      this.dictCurvePanel.Remove(panel.Title);
         *      this.dictCurvePanel.Add(panel.Title, panel);
         *      this.LOG.Debug("液控单向阀最小控制压力实验完成");
         *
         *
         *  }
         */
        private void HyConLeakageTest()//液控单向阀泄漏量试验
        {
            CurvePanel panel = new CurvePanel();

            panel.Title  = TestType.液控单向阀泄漏量试验.ToString() + "曲线";
            panel.XLabel = "压力(MPa)";
            panel.YLabel = "泄漏量(Ml/Min)";
            Curve curve_leak = new Curve();

            panel.AddCurve(curve_leak);
            curve_leak.Name = "泄漏量";

            float retnum;
            float testret      = 0;
            int   time         = 0;
            float max_pressure = (float)this.额定压力;
            bool  needtest     = true;

            //this.SetCircuitState(CircuitState.BTIn);
            this.SetCircuitState(CircuitState.A);
            this.SetValve4(0);
            while (needtest)
            {
                FormLeakHydcheck leakHydcheck_config = new FormLeakHydcheck(max_pressure);
                needtest = leakHydcheck_config.ShowDialog() == DialogResult.OK;
                if (!needtest)
                {
                    break;
                }
                this.SetThrottleValve(100f);//使阀13,14_1,14_2工作于右位,且开口最大
                this.SetSourcePre(leakHydcheck_config.实验压力);
                this.SetSourceFlow(20);
                this.WaitPressureAUntil(leakHydcheck_config.实验压力);
                LOG.Debug("系统达到试验压力");
                FormLeakageReturn frm_return = new FormLeakageReturn(leakHydcheck_config.testtimecount, this);
                frm_return.ShowDialog();
                LOG.Debug("倒计时窗口显示");
                time    = leakHydcheck_config.testtimecount;
                testret = frm_return.retvol;
                retnum  = (frm_return.retvol / leakHydcheck_config.testtimecount) * 60f;
                curve_leak.AddPoint(leakHydcheck_config.实验压力, retnum);
            }
            this.SetSourcePre(0);
            this.SetSourceFlow(0);
            this.dictCurvePanel.Remove(panel.Title);
            this.dictCurvePanel.Add(panel.Title, panel);
            this.LOG.Debug("泄漏实验已完成");
        }
Exemple #18
0
        public void CreateRandomLine()
        {
            RemoveRandomLine();
            float rand;

            mRandomCurve = new Curve("Random Curve", OxyColor.FromArgb(0xFF, 0, 150, 0), mGraphPlot);
            for (int i = 0; i <= mNumRandomPoints; i++)
            {
                rand = GetRandom(100, 400);
                rand = rand / 100;
                System.Windows.Point tempPoint = new System.Windows.Point(((double)mTimeTrackTotal / (double)mNumRandomPoints) * (double)i, rand);
                mRandomCurve.AddPoint(tempPoint, mGraphPlot);
            }
            if (SmoothCurve)
            {
                mRandomCurve.Smooth = true;
            }
        }
        /// <summary>
        /// 稳态流量压力特性试验-指定阀口开度
        /// </summary>
        /// <param name="dictCurve"></param>
        /// <param name="state"></param>
        /// <param name="n">第N次试验</param>
        private void StaticFlowPressSingleState(CurvePanel panel, CircuitState state, int n)
        {
            string key   = state.ToString() + "曲线" + n.ToString();
            Curve  curve = new Curve();

            curve.Name = key;
            panel.AddCurve(curve);

            this.SetCircuitState(state);  //设置球阀状态
            this.SetThrottleValve(100f);
            this.SetSourcePre(this.额定压力);
            float max_flow = (float)(this.额定流量);

            this.SetSourceFlow(0);
            //Pause(3000);

            const int div_cnt     = 20;
            const int measure_cnt = 5;
            float     pressure_A  = 0;
            float     pressure_T  = 0;
            float     delta_q     = (float)(max_flow / div_cnt);
            float     flow        = 0;

            for (int i = 0; i <= div_cnt; i++)
            {
                this.SetSourceFlow(i * delta_q);
                //读取压力流量数据
                flow       = 0;
                pressure_A = 0;
                pressure_T = 0;
                for (int j = 0; j < measure_cnt; j++)
                {
                    Pause(1000);
                    flow       += this.当前流量绝对值 / measure_cnt;
                    pressure_A += this.当前A口压力 / measure_cnt;
                    pressure_T += this.当前T口压力 / measure_cnt;
                }
                //将数据添加到曲线
                curve.AddPoint(flow, pressure_A - pressure_T);
            }
            this.SetSourcePre(0);
            this.SetSourceFlow(0);
            this.SetThrottleValve(50f);
        }
        /// <summary>
        /// 稳态压差流量特性试验
        /// </summary>
        private void SteadyPreDifFlowTest()
        {
            CurvePanel panel = new CurvePanel();

            panel.Title  = TestType.稳态压差流量特性试验.ToString() + "曲线";
            panel.XLabel = "流量(L/Min)";
            panel.YLabel = "压差(MPa)";

            //Curve curveAB = new Curve();
            //curveAB.Name = "BA口";
            //panel.AddCurve(curveAB);
            Curve curvePABT = new Curve();

            curvePABT.Name = "BA口";
            panel.AddCurve(curvePABT);



            //this.SetCircuitState(CircuitState.ABOut);//设置球阀状态
            this.SetCircuitState(CircuitState.PABTOut);//设置球阀状态
            //因为上面叠加了一个液动方向阀,外控外排,需要先导油
            this.SetPaPressure(8);
            this.SetTestValveStatePilot(TestValveState.右位);
            this.SetValve4(5);

            this.SetThrottleValve(100f);  //设置比例方向阀13/14.1/14.2的位置(右位开口最大)
            this.SetSourcePre(this.额定压力); //设置最大试验压力
            float max_flow = (float)(this.额定流量);

            this.SetSourceFlow(0);
            const int div_cnt     = 20;
            const int measure_cnt = 10;

            float pressure_A = 0;
            float pressure_B = 0;
            float delta_q    = (float)(max_flow / div_cnt);
            float flow       = 0;

            for (int i = 0; i <= div_cnt; i++)
            {
                this.SetSourceFlow(i * delta_q);
                Pause(3000);
                //读取压力流量数据
                flow       = 0;
                pressure_A = 0;
                pressure_B = 0;
                for (int j = 0; j < measure_cnt; j++)
                {
                    Pause(1000);
                    flow       += this.当前流量绝对值 / measure_cnt;
                    pressure_A += this.当前A口压力 / measure_cnt;

                    //pressure_B += this.当前B口压力 / measure_cnt;
                    pressure_B += this.当前T口压力 / measure_cnt;
                }
                //将数据添加到曲线
                curvePABT.AddPoint(flow, pressure_A - pressure_B);
            }
            this.SetSourcePre(0);
            this.SetSourceFlow(0);
            this.SetThrottleValve(50f);
            this.dictCurvePanel.Remove(panel.Title);
            this.dictCurvePanel.Add(panel.Title, panel);
        }
Exemple #21
0
    private async void GeneratePoints()
    {
        Terrain terrain = Terrain.instance;

        for (int i = 0; i < numPoints; i++)
        {
            float t = (float)i / (numPoints);
            float a = t * Mathf.Pi * 2f;

            Vector2 p      = Vector2.Right.Rotated(a) * initialRadius;
            Vector3 p3D    = new Vector3(p.x, 0f, p.y);
            Vector3 normal = terrain.GetNormal(p3D);
            p3D.y = terrain.GetHeight(p3D);
            Curve.AddPoint(p3D);
            SpatialDebugger.instance.AddLine(p3D, p3D + normal * 16f, Colors.Blue);
            //viewPoints[i] = AddPoint(p3D);
        }

        for (int j = 0; j < iterations; j++)
        {
            bool moved = false;
            for (int i = 0; i < numPoints; i++)
            {
                float t = (float)i / (numPoints - 1);

                Vector3 p             = Curve.GetPointPosition(i);
                Vector3 normal        = terrain.GetNormal(p);
                Vector3 terrainNormal = normal;
                normal.y = 0f;
                normal   = normal.Normalized();

                float desiredHeight = SampleNoise1D(
                    elevationNoise, t * elevationFrequency, elevationFrequency
                    ) * .5f + .5f;
                desiredHeight = Mathf.Lerp(elevationRange.x, elevationRange.y, desiredHeight);

                float diff = desiredHeight - p.y;

                float diffT = 1f - (j % 100) / 100f;
                diffT = Mathf.Pow(diffT, .25f);
                diff *= diffT;

                if (diff <= elevationDiffThreshold)
                {
                    continue;
                }

                p.x -= normal.x * diff * elevationCorrection;
                p.z -= normal.z * diff * elevationCorrection;

                if ((j + 1) % 100 == 0)
                {
                    float   angle = (float)rng.NextDouble() * Mathf.Pi * 4f;
                    Vector2 dir   = Vector2.Right.Rotated(angle);
                    p.x += dir.x * 256f;
                    p.z += dir.y * 256f;
                }

                p.y = terrain.GetHeight(p);
                Curve.SetPointPosition(i, p);

                SpatialDebugger.instance.UpdateLine(
                    i, p, p + terrainNormal * 16f, Colors.Blue
                    );

                /*Transform tr = viewPoints[i].GlobalTransform;
                 * tr.origin = p;
                 * tr.basis = LookAtBasis(terrainNormal);
                 * viewPoints[i].GlobalTransform = tr;*/

                moved = true;

                if (j % 50 == 0)
                {
                    await ToSignal(GetTree(), "idle_frame");
                }
            }

            if (!moved)
            {
                continue;
            }
            else
            {
                System.Console.WriteLine("Next iteration");
            }
        }

        System.Console.WriteLine("Ended basic");

        walker        = new RoadWalker();
        walker.origin = Curve.GetPointPosition(0);
        Vector3 targetPoint = Curve.GetPointPosition(1);

        walker.direction = new Vector2(
            targetPoint.x - walker.origin.x,
            targetPoint.z - walker.origin.z
            ).Angle();

        for (int i = 0; i < numPoints; i++)
        {
            int nxt = (i + 1) % numPoints;
            await PathFind(Curve.GetPointPosition(nxt));
        }
    }
        private void MinControlPreTest()//液控单向阀最小控制压力
        {
            CurvePanel panel = new CurvePanel();

            panel.Title  = TestType.液控单向阀最小控制压力.ToString() + "实验曲线";
            panel.XLabel = "体积流量(L/Min)";
            panel.YLabel = "控制压力(MPa)";

            Curve curvePBmax   = new Curve();
            Curve curve75PBmax = new Curve();
            Curve curve50PBmax = new Curve();
            Curve curve25PBmax = new Curve();
            Curve curvePBmin   = new Curve();

            //添加曲线
            panel.AddCurve(curvePBmax);
            panel.AddCurve(curve75PBmax);
            panel.AddCurve(curve50PBmax);
            panel.AddCurve(curve25PBmax);
            panel.AddCurve(curvePBmin);
            //添加曲线名称
            curvePBmax.Name   = "100%PBmax";
            curve75PBmax.Name = "75%PBmax";
            curve50PBmax.Name = "50%PBmax";
            curve25PBmax.Name = "25%PBmax";
            curvePBmin.Name   = "PBmin";

            this.SetTestValveState(TestValveState.右位);
            this.SetCircuitState(CircuitState.ATIn);
            this.SetThrottleValve(100f); //设置比例方向阀13/14.1/14.2的位置(右位开口最大)

            this.SetValve4(0f);;         //设置比例减压阀4的压力值为0
            //   this.SetPaPressure((float)(5 * this.开启压力));//设置先导控制油压力,暂定16
            this.SetPaPressure(10f);     //设置先导控制油压力,暂定16
            //2改为5倍开启压力
            //在操作面板上显示配置界面用户配置最大设定压力和被试流量
            //FormMinControlPress frm_minconpress = new FormMinControlPress("请输入实验压力",(float)this.额定压力);
            this.SetSourceFlow(this.额定流量);
            for (int i = 1; i < 5; i++)
            {
                //每一个压力点寻找最小开启压力
                double OilPressure = this.额定压力 * i * 0.25;
                this.SetSourcePre(OilPressure);
                this.WaitPressureAUntil(OilPressure * 0.8);
                const int div_cnt      = 100;
                double[]  OpenPressure = new double[6];
                double[]  DesiredFlow  = new double[6];
                for (int j = 0; j < 6; j++)
                {
                    //每个设定压力下,寻找6个开启压力及对应的流量
                    int FlagFind = 1;
                    int m        = 0;//减压阀加载用
                    while (FlagFind == 1)
                    {
                        //寻找最低开启压力,一个点
                        m = m + 1;
                        this.SetValve4(m * (float)(this.额定压力 / div_cnt));
                        Pause(1000);
                        //if (Math.Abs(Math.Abs(Group[selectedFlowmeter]) / this.额定流量) >= 0.5)
                        {
                            OpenPressure[j] = this.Pa口传感器压力;
                            DesiredFlow[j]  = this.当前流量;
                            LOG.Debug("第" + j + "组数据");
                            FlagFind = 0;
                        }
                    }
                }
                for (int n = 0; n < 6; n++)          //n个数要进行n-1趟比较,按照流量从小到大排列
                {
                    for (int P = 0; P < 5; P++)
                    {
                        if (DesiredFlow[P] > DesiredFlow[P + 1])
                        {
                            //依次比较两个相邻的数,将小数放在前面,大数放在后面
                            double temp = DesiredFlow[P];
                            DesiredFlow[P]     = DesiredFlow[P + 1];
                            DesiredFlow[P + 1] = temp;

                            temp                = OpenPressure[P];
                            OpenPressure[P]     = OpenPressure[P + 1];
                            OpenPressure[P + 1] = temp;
                        }
                    }
                }

                switch (i)
                {
                case 1:
                {
                    for (int j = 0; j < 6; j++)
                    {
                        curve25PBmax.AddPoint(DesiredFlow[j], OpenPressure[j]);
                    }
                    break;
                }

                case 2:
                {
                    for (int j = 0; j < 6; j++)
                    {
                        curve50PBmax.AddPoint(DesiredFlow[j], OpenPressure[j]);
                    }
                    break;
                }

                case 3:
                {
                    for (int j = 0; j < 6; j++)
                    {
                        curve75PBmax.AddPoint(DesiredFlow[j], OpenPressure[j]);
                    }
                    break;
                }

                case 4:
                {
                    for (int j = 0; j < 6; j++)
                    {
                        curvePBmax.AddPoint(DesiredFlow[j], OpenPressure[j]);
                    }
                    break;
                }
                }
            }
            this.SetSourcePre(0);
            this.SetSourceFlow(0);
            this.dictCurvePanel.Remove(panel.Title);
            this.dictCurvePanel.Add(panel.Title, panel);
            this.LOG.Debug("液控单向阀最小控制压力实验完成");
        }
        // ================================================================================ Inspector
        public override void OnInspectorGui()
        {
            var settings = Settings;

            editorSelection.Reset();

            // ======================================== Top section
            InspectorTopSection();

            // ======================================== Points
            GUILayout.Space(5);

            if (Curve.PointsCount > 0)
            {
                var temp = BGCurveSettingsForEditor.DisableInspectorPointMenu;
                BGCurveSettingsForEditor.DisableInspectorPointMenu = BGEditorUtility.ButtonOnOff(ref temp, "Points menu [" + Curve.PointsCount + "]", "Show points in Editor inspector",
                                                                                                 HiddenPointMenuColor,
                                                                                                 new GUIContent("Show", "Click to show points menu"),
                                                                                                 new GUIContent("Hide", "Click to hide points menu"), () =>
                {
                    const string title = "Reverse points";
                    if (GUILayout.Button(new GUIContent(title, "Reverse all points, but keep curve intact")))
                    {
                        if (Curve.PointsCount < 2)
                        {
                            BGEditorUtility.Inform(title, "There should be at least 2 points. Curve has " + Curve.PointsCount);
                            return;
                        }
                        if (!BGEditorUtility.Confirm(title, "Are you sure you want to reverse the order of " + Curve.PointsCount + " points? Curve will remain intact.", "Reverse"))
                        {
                            return;
                        }

                        Curve.Reverse();
                        EditorUtility.SetDirty(Curve);
                    }
                });

                if (!BGCurveSettingsForEditor.DisableInspectorPointMenu)
                {
                    BGEditorUtility.VerticalBox(() => Curve.ForEach((point, index, count) => editorPoint.OnInspectorGUI(point, index, settings)));
                }

                // ======================================== Selections operations
                editorSelection.InspectorSelectionOperations();

                //warning
                BGEditorUtility.HelpBox("Selection mode is on", MessageType.Warning, !editorSelection.Changed && editorSelection.HasSelected());
            }
            else
            {
                BGEditorUtility.HorizontalBox(() =>
                {
                    EditorGUILayout.LabelField("No points!");
                    if (BGEditorUtility.ButtonWithIcon(addPointIcon, "Add new point at (0,0,0) local coordinates"))
                    {
                        Curve.AddPoint(new BGCurvePoint(Curve, Vector3.zero, settings.ControlType, Vector3.right, Vector3.left));
                    }
                });
            }

            if (editorSelection.Changed)
            {
                EditorUtility.SetDirty(Curve);
            }
        }
Exemple #24
0
        /// <summary>
        /// 稳态压力流量特性试验
        /// 设置不同的出口压力值,针对不同的出口压力设定值(必须包含最高和最低):
        /// 流量从零加到最大,再从最大减到0,测试被试阀的进口压力
        /// </summary>
        private void StaticPressureFlowTest()
        {
            CurvePanel panel = new CurvePanel();

            panel.Title  = TestType.稳态压力流量特性试验.ToString() + "曲线";
            panel.XLabel = "流量(L/min)";
            panel.YLabel = "压力(MPa)";
            this.SetOfSelectFlowMeter((float)this.额定流量);
            this.SetCircuitState(CircuitState.PTOut); //设置球阀状态,出口流量检测
            this.SetThrottleValve(100f);              //设置比例方向阀13/14.1/14.2的位置(右位开口最大)
            this.SetSourcePre(this.额定压力);

            const int div_cnt     = 20;
            const int measure_cnt = 10;
            float     delta_q     = (float)(this.额定流量 / div_cnt);
            float     flow        = 0;
            float     pressure_P  = 0;
            int       repeat_cnt  = 0;

            while (System.Windows.Forms.MessageBox.Show("调整溢流阀的设定压力值,是否继续", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
            {
                Curve curve = new Curve();
                panel.AddCurve(curve);
                curve.Name = repeat_cnt++.ToString();
                this.SetSourcePre(this.额定压力);
                for (int i = 0; i <= div_cnt; i++)
                {
                    this.SetSourceFlow(i * delta_q);

                    //读取压力流量数据
                    flow       = 0;
                    pressure_P = 0;
                    for (int j = 0; j < measure_cnt; j++)
                    {
                        Pause(500);
                        flow       += Math.Abs(this.当前流量绝对值 / measure_cnt);
                        pressure_P += this.当前P口压力 / measure_cnt;
                    }
                    //将数据添加到曲线
                    curve.AddPoint(flow, pressure_P);
                }

                for (int i = div_cnt - 1; i >= 0; i--)
                {
                    this.SetSourceFlow(i * delta_q);

                    //读取压力流量数据
                    flow       = 0;
                    pressure_P = 0;
                    for (int j = 0; j < measure_cnt; j++)
                    {
                        Pause(500);
                        flow       += Math.Abs(this.当前流量绝对值 / measure_cnt);
                        pressure_P += this.当前P口压力 / measure_cnt;
                    }
                    //将数据添加到曲线
                    curve.AddPoint(flow, pressure_P);
                }
                this.SetSourcePre(0);
                this.SetSourceFlow(0);
            }
            //this.SetSourcePre(0);
            //this.SetThrottleValve(50f);//设置比例方向阀13/14.1/14.2的位置(右位开口最大)
            this.dictCurvePanel.Remove(panel.Title);
            this.dictCurvePanel.Add(panel.Title, panel);
        }
Exemple #25
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="state"></param>
        private void SteadystatePreeesureSingleSide(TestValveState state)
        {
            if (state == TestValveState.中位)
            {
                return;
            }

            CurvePanel panel = new CurvePanel();

            panel.Title  = TestType.稳态压差流量特性试验.ToString() + "(" + state.ToString() + ")";
            panel.XLabel = "流量(L/Min)";
            panel.YLabel = "压差(MPa)";
            Curve curvePT = new Curve();
            Curve curvePA = new Curve();
            Curve curvePB = new Curve();
            Curve curveAT = new Curve();
            Curve curveBT = new Curve();

            //添加曲线
            panel.AddCurve(curvePT);
            panel.AddCurve(curvePA);
            panel.AddCurve(curvePB);
            panel.AddCurve(curveAT);
            panel.AddCurve(curveBT);
            //添加曲线名称
            curvePT.Name = "PT口";
            curvePA.Name = "PA口";
            curvePB.Name = "PB口";
            curveAT.Name = "AT口";
            curveBT.Name = "BT口";


            this.SetCircuitState(CircuitState.PABTOut);
            this.SetThrottleValve(100f);
            this.SetTestValveState(state);
            this.SetSourcePre(this.额定压力);
            float 最大流量 = (float)(this.额定流量);

            this.SetSourceFlow(0);
            Pause(3000);

            const int div_cnt     = 10;
            const int measure_cnt = 10;

            float pressure_A = 0;
            float pressure_B = 0;
            float pressure_P = 0;
            float pressure_T = 0;
            float delta_q    = (float)(最大流量 / div_cnt);

            float flow = 0;

            for (int i = 0; i <= div_cnt; i++)
            {
                this.SetSourceFlow(i * delta_q);

                //读取压力流量数据
                flow       = 0;
                pressure_A = 0;
                pressure_B = 0;
                pressure_P = 0;
                pressure_T = 0;
                for (int j = 0; j < measure_cnt; j++)
                {
                    Pause(500);
                    flow       += this.当前流量绝对值 / measure_cnt;
                    pressure_A += this.当前A口压力 / measure_cnt;
                    pressure_B += this.当前B口压力 / measure_cnt;
                    pressure_P += this.当前P口压力 / measure_cnt;
                    pressure_T += this.当前T口压力 / measure_cnt;
                }
                //将数据添加到曲线
                curvePT.AddPoint(flow, pressure_P - pressure_T);
                curvePA.AddPoint(flow, pressure_P - pressure_A);
                curvePB.AddPoint(flow, pressure_P - pressure_B);
                curveAT.AddPoint(flow, pressure_A - pressure_T);
                curveBT.AddPoint(flow, pressure_B - pressure_T);
            }
            this.SetSourcePre(0);
            this.SetSourceFlow(0);
            SetTestValveState(TestValveState.中位);
            this.SetThrottleValve(50f);

            this.dictCurvePanel.Remove(panel.Title);
            this.dictCurvePanel.Add(panel.Title, panel);
        }
        public override void _GuiInput(InputEvent ev)
        {
            if (!(ev is InputEventMouse))
            {
                return;
            }

            InputEventMouse evM = (InputEventMouse)ev;

            Vector2 mousePos    = evM.Position;
            Vector2 relCurvePos = mousePos;

            relCurvePos.x = Mathf.InverseLerp(MARGIN, RectSize.x - MARGIN, relCurvePos.x);
            relCurvePos.y = Mathf.InverseLerp(RectSize.y - MARGIN, MARGIN, relCurvePos.y);

            relCurvePos.x = Mathf.Clamp(relCurvePos.x, 0, 1);
            relCurvePos.y = Mathf.Clamp(relCurvePos.y, 0, 1);

            int handleIdx        = -1;
            int handleTangentIdx = 0;

            int pointCount = curve.GetPointCount();

            for (int i = 0; i < pointCount; i++)
            {
                Vector2 handlePos = GetHandlePos(i);
                Rect2   r         = new Rect2();

                r.Position = handlePos - Vector2.One * (HANDLE_SIZE / 2f);
                r.Size     = Vector2.One * HANDLE_SIZE;

                if (r.HasPoint(mousePos))
                {
                    handleIdx = i;
                }

                if (i > 0)
                {
                    Vector2 tangentPos = GetHandleLeftTangent(i);
                    r.Position = tangentPos - Vector2.One * (TANGENT_HANDLE_SIZE / 2f);
                    r.Size     = Vector2.One * TANGENT_HANDLE_SIZE;

                    if (r.HasPoint(mousePos))
                    {
                        handleTangentIdx = -1;
                    }
                }
                if (i < pointCount - 1)
                {
                    Vector2 tangentPos = GetHandleRightTangent(i);
                    r.Position = tangentPos - Vector2.One * (TANGENT_HANDLE_SIZE / 2f);
                    r.Size     = Vector2.One * TANGENT_HANDLE_SIZE;

                    if (r.HasPoint(mousePos))
                    {
                        handleTangentIdx = 1;
                    }
                }
            }

            if (ev is InputEventMouseButton)
            {
                InputEventMouseButton evMB = ev as InputEventMouseButton;

                if (evMB.ButtonIndex == (int)ButtonList.Left)
                {
                    if (evMB.Pressed)
                    {
                        if (handleTangentIdx != 0)
                        {
                            dragTangentIdx = handleTangentIdx;
                        }
                        else
                        {
                            if (handleIdx == -1)
                            {
                                handleIdx   = curve.AddPoint(relCurvePos);
                                selectedIdx = handleIdx;
                                dragIdx     = handleIdx;
                            }
                            else
                            {
                                selectedIdx = handleIdx;
                                dragIdx     = handleIdx;
                            }
                        }
                    }
                    else
                    {
                        dragTangentIdx = 0;
                        dragIdx        = -1;
                    }
                }
                if (evMB.ButtonIndex == (int)ButtonList.Right)
                {
                    if (evMB.Pressed)
                    {
                        if (handleIdx != -1)
                        {
                            curve.RemovePoint(handleIdx);
                            if (selectedIdx == handleIdx)
                            {
                                selectedIdx = -1;
                            }
                            handleIdx = -1;
                        }
                    }
                }
            }
            if (ev is InputEventMouseMotion)
            {
                if (dragIdx != -1)
                {
                    curve.SetPointOffset(dragIdx, relCurvePos.x);
                    curve.SetPointValue(dragIdx, relCurvePos.y);
                }
                if (dragTangentIdx != 0)
                {
                    Vector2 handlePos = GetHandlePos(selectedIdx);
                    Vector2 dir       = (mousePos - handlePos).Normalized();

                    float tangent;
                    if (!Mathf.IsZeroApprox(dir.x))
                    {
                        tangent = dir.y / dir.x;
                    }
                    else
                    {
                        tangent = 9999f * (dir.y >= 0 ? 1 : -1);
                    }

                    bool link = !Input.IsKeyPressed((int)KeyList.Shift);

                    if (dragTangentIdx == 1)
                    {
                        curve.SetPointRightTangent(selectedIdx, -tangent);
                        link &= selectedIdx > 0 && curve.GetPointLeftMode(selectedIdx) != Curve.TangentMode.Linear;
                        if (link)
                        {
                            curve.SetPointLeftTangent(selectedIdx, -tangent);
                        }
                    }
                    else
                    {
                        curve.SetPointLeftTangent(selectedIdx, -tangent);
                        link &= selectedIdx < pointCount - 1 && curve.GetPointRightMode(selectedIdx) != Curve.TangentMode.Linear;
                        if (link)
                        {
                            curve.SetPointRightTangent(selectedIdx, -tangent);
                        }
                    }
                }
            }

            if (dragIdx != -1)
            {
                hoverIdx = dragIdx;
            }

            hoverIdx        = handleIdx;
            hoverTangentIdx = handleTangentIdx;
            Update();
        }
Exemple #27
0
        public static void Init()
        {
            #region effects

            var rocketEngineCurve = new Curve();
            rocketEngineCurve.AddPoint(new Vector2(1, 0.5f));
            rocketEngineCurve.AddPoint(new Vector2(0.5f, 0.75f));
            rocketEngineCurve.AddPoint(new Vector2(0, 0.1f));

            var wheelSkidCurve = new Curve();
            var rng            = new RandomNumberGenerator();
            for (var i = 0; i < 100; i++)
            {
                wheelSkidCurve.AddPoint(new Vector2(i / 100f, rng.RandiRange(900, 1100) / 1000f));
            }

            var explorerSkid = new Skid
            {
                Length  = 300,
                Width   = 4,
                Opacity = 10,
                Curve   = wheelSkidCurve,
                Color   = new Color(0, 0, 0)
            };

            var crimsonSkid = new Skid
            {
                Length  = 15,
                Width   = 5,
                Color   = new Color(255 / 255f, 254 / 255f, 152 / 255f),
                Opacity = 75,
                Curve   = rocketEngineCurve
            };

            #endregion

            explorer = new UnitType("explorer.png")
            {
                Name                = "Explorer",
                Description         = "Starting bot.",
                MaxSpeed            = 60f,
                Acceleration        = 400f,
                Deceleration        = 200f,
                AngularDeceleration = 0.075f,
                Mass                = 250f,
                Inertia             = 500f,
                RotationSpeed       = 6f,
                Health              = 100f,
                CollisionShape      = new []
                {
                    new Vector2(26, 22),
                    new Vector2(26, -25),
                    new Vector2(-26, -25),
                    new Vector2(-26, -21)
                },
                ShadowBlur   = 4,
                ShadowOffset = new Vector2(0, 0.2f),
                Body         = "Body",

                SkidMarks = new System.Collections.Generic.Dictionary <Vector2, Skid>
                {
                    { new Vector2(-4, 4), explorerSkid },
                    { new Vector2(4, 4), explorerSkid }
                }
            };

            crimson = new UnitType("crimson.png")
            {
                Name                = "Crimson",
                Description         = "A big cruiser drone. Flies at high altitudes.",
                MaxSpeed            = 90f,
                Acceleration        = 170f,
                RotationSpeed       = 5f,
                Mass                = 1000f,
                Inertia             = 5000f,
                Deceleration        = 50f,
                AngularDeceleration = 0.1f,
                Health              = 500f,
                CollisionShape      = new []
                {
                    new Vector2(16, 17),
                    new Vector2(8, -7),
                    new Vector2(0, -15),
                    new Vector2(-8, -7),
                    new Vector2(-16, 17),
                    new Vector2(0, 12)
                },
                ShadowOffset = new Vector2(-12, 18),
                Body         = "Air",

                SkidMarks = new System.Collections.Generic.Dictionary <Vector2, Skid>
                {
                    { new Vector2(4.5f, 4.5f), crimsonSkid },
                    { new Vector2(-4.5f, 4.5f), crimsonSkid }
                }
            };

            ghost = new UnitType("ghost.png")
            {
                Name           = "Ghost",
                Description    = "A special unit used for editing & spectating.",
                MaxSpeed       = 200f,
                Acceleration   = 1000f,
                Rotates        = false,
                Mass           = 1f,
                Inertia        = 0f,
                Deceleration   = 1000f,
                Health         = float.MaxValue - float.MaxValue / 2,
                CollisionShape = new []
                {
                    new Vector2(0, 0),
                    new Vector2(0, 0),
                },
                ShadowBlur = -1,
                Body       = "Air"
            };
        }