コード例 #1
0
ファイル: Program.cs プロジェクト: daefimov-1/CSharp2019-2020
        static void Main()
        {
            MassPoint[] elements;
            int         N; // количество точек на плоскости
            Random      gen = new Random(0);

            do
            {
                Console.Write("Введите количество точек на плоскости: ");
            }while (!int.TryParse(Console.ReadLine(), out N) || N < 1);
            elements = new MassPoint[N];
            for (int i = 0; i < elements.Length; i++)
            {
                PointS ps = new PointS(gen.Next(-10, 11), gen.Next(-10, 11));
                elements[i] = new MassPoint(ps, gen.Next(1, 6));
                Console.WriteLine(elements[i].ToString());
            }
            SetOfMassPoint real;

            do
            {
                double R = 0;
                do
                {
                    Console.Write("Введите радиус множества: ");
                }while (!double.TryParse(Console.ReadLine(), out R) || R <= 1);
                real = new SetOfMassPoint(elements, new PointS(0, 0), R);
                Console.WriteLine(real.ToString());
                Console.WriteLine(real.MassCenter.ToString());
                Console.WriteLine("Для завершения работы нажмите Escape ");
            } while (Console.ReadKey(true).Key != ConsoleKey.Escape);
        }
コード例 #2
0
ファイル: Integrator.cs プロジェクト: bp-tags/GamePhysics
 public static void EulerIntegrateMassPoint(MassPoint point, Vector3 force, float deltaTime)
 {
     if (!point.IsFixed)
     {
         point.Derivative = PerformEulerIntegrationStep(ref point.State, point.Derivative, force, deltaTime);
     }
 }
コード例 #3
0
        void UpdateForceSpread(MassPoint massPoint, float force, int deep)
        {
            if (deep > 1)
            {
                return;
            }

            if (massPoint.LeftMassPoint != null)
            {
                massPoint.LeftMassPoint.Velocity += force * vertexSpreadAtte_Second;
                UpdateForceSpread(massPoint.LeftMassPoint, massPoint.LeftMassPoint.Velocity, ++deep);
            }
            else
            {
                UpdateForceSpread(massPoint.RightMassPoint, force * vertexSpreadAtte_ContactToWall, deep);
            }

            if (massPoint.RightMassPoint != null)
            {
                massPoint.RightMassPoint.Velocity += force * vertexSpreadAtte_Second;
                UpdateForceSpread(massPoint.RightMassPoint, massPoint.RightMassPoint.Velocity, ++deep);
            }
            else
            {
                UpdateForceSpread(massPoint.LeftMassPoint, force * vertexSpreadAtte_ContactToWall, deep);
            }
        }
コード例 #4
0
    private void Update()
    {
        Rigidbody t_rigidbody  = GetComponent <Rigidbody>();
        var       t_massPoints = MassPointManager.Instance.massPointHandler.massPoints;

        massPoint           = null;
        _gravitationalForce = 0;
        _gravitationalField = 0;

        for (int i = 0; i < t_massPoints.Count; i++)
        {
            if (Vector3.Distance(transform.position, t_massPoints[i].massPoint.transform.position) <= t_massPoints[i].massPoint.transform.localScale.y * 20 + t_massPoints[i].gravitationalField)
            {
                massPoint           = t_massPoints[i].massPoint;
                _gravitationalForce = t_massPoints[i].gravitationalForce;
                _gravitationalField = t_massPoints[i].gravitationalField;
            }
        }

        if (massPoint != null)
        {
            transform.parent = massPoint.transform;
            massPoint.Attract(transform, _gravitationalForce, _gravitationalField);
        }
        else
        {
            t_rigidbody.velocity = Vector3.zero;
        }
    }
コード例 #5
0
ファイル: RopeAllignment.cs プロジェクト: asmboom/VACC
    // Use this for initialization
    void Start()
    {
        pointList = new List <MassPoint>();
        MassPoint mp;

        for (int i = 0; i < 30; i++)
        {
            if (i == 0)
            {
                mp = new MassPoint(new Vector3(-10 + (i * 0.5f), 0, 0), 0.05f, true);
                pointList.Add(mp);
            }
            else
            {
                if (i == 20)
                {
                    mp = new MassPoint(new Vector3(-10 + (i * 0.5f), 0, 0), 0.05f, true);
                }
                else
                {
                    mp = new MassPoint(new Vector3(-10 + (i * 0.5f), 0, 0), 0.05f, false);
                }
                mp.ConnectTo(pointList[pointList.Count - 1]);
                pointList.Add(mp);
            }
        }

        isInitialized = true;
    }
コード例 #6
0
        /// <summary>
        /// Get mass point.
        /// </summary>
        /// <param name="line"> Line </param>
        /// <returns> Mass point </returns>
        private static MassPoint GetMassPoint(string line)
        {
            var x         = double.Parse(line.Substring(0, 3));
            var y         = double.Parse(line.Substring(5, 5));
            var mass      = double.Parse(line.Substring(10, 6));
            var massPoint = new MassPoint(new PointS(x, y), mass);

            return(massPoint);
        }
コード例 #7
0
        public List <ModResModel> getPmFromDB(double ipaco)
        {
            StringBuilder sb = new StringBuilder();

            sb.Append("SELECT max(z) MAXZ,Parent_ions.* FROM Parent_ions group by seq,mod_res");
            //sb.Append(" WHERE ABS(MZ - " + pmFromFile.ToString() + ") < " + deviation + "order by FORUMLA");

            DataSet ds = sqlHelper.Query(sb.ToString());

            int count = ds.Tables[0].Rows.Count;

            List <ModResModel> lst = new List <ModResModel>();

            ModResModel model = new ModResModel();

            for (int i = 0; i < count; i++)
            {
                //if (model.Forumla == ds.Tables[0].Rows[i]["FORUMLA"].ToString())
                //{
                //continue;
                //}
                model          = new ModResModel();
                model.ID       = ds.Tables[0].Rows[i]["ID"].ToString();
                model.Mod_Res  = ds.Tables[0].Rows[i]["MOD_RES"].ToString();
                model.Z        = int.Parse(ds.Tables[0].Rows[i]["MAXZ"].ToString());
                model.Sequence = ds.Tables[0].Rows[i]["SEQ"].ToString();
                model.M_Z      = double.Parse(ds.Tables[0].Rows[i]["MZ"].ToString());
                model.Forumla  = ds.Tables[0].Rows[i]["FORUMLA"].ToString();
                model.M_Z_ALL  = ds.Tables[0].Rows[i]["MZ_ALL"].ToString().Split(',').Select(ms => double.Parse(ms)).ToList();
                model.M_ALL    = ds.Tables[0].Rows[i]["Relative_Abundance_ALL"].ToString().Split(',').Select(ms => double.Parse(ms)).ToList();
                List <MassPoint> lstMassPoint = new List <MassPoint>();

                for (int j = 0; j < model.M_Z_ALL.Count; j++)
                {
                    MassPoint mp = new MassPoint();

                    mp.Mass      = Convert.ToDouble(model.M_Z_ALL[j]);
                    mp.Intensity = Convert.ToDouble(model.M_ALL[j]);

                    if (Convert.ToDouble(model.M_ALL[j]) * 100 > ipaco)
                    {
                        if (Convert.ToDouble(model.M_ALL[j]) == 1.000)
                        {
                            model.M = lstMassPoint.Count;
                        }
                        lstMassPoint.Add(mp);
                    }
                }

                model.Mass_Point = lstMassPoint;
                lst.Add(model);
            }

            return(lst);
        }
コード例 #8
0
        public List <ModResModel> getPmFromDB(double pmFromFile, double deviation, double ipaco)
        {
            StringBuilder sb = new StringBuilder();

            //sb.AppendFormat("SELECT * FROM {0}", sTableName);
            //sb.AppendFormat(" WHERE ABS(MZ - {0}) < {1}", pmFromFile, deviation);
            //sb.Append(" ORDER BY FORUMLA");

            sb.AppendFormat("SELECT * FROM {0}", sTableName);
            sb.AppendFormat(" WHERE MZ < {0} + {1} AND MZ > {2}", pmFromFile, deviation, pmFromFile);
            sb.AppendFormat("    OR MZ < {0} AND MZ > {1} - {2}", pmFromFile, pmFromFile, deviation);
            sb.Append(" ORDER BY FORUMLA");
            DataSet ds = sqlHelper.Query(sb.ToString());

            List <ModResModel> lst = new List <ModResModel>();

            ModResModel model;

            for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
            {
                model          = new ModResModel();
                model.ID       = ds.Tables[0].Rows[i]["ID"].ToString();
                model.Mod_Res  = ds.Tables[0].Rows[i]["MOD_RES"].ToString();
                model.Z        = int.Parse(ds.Tables[0].Rows[i]["Z"].ToString());
                model.Sequence = ds.Tables[0].Rows[i]["SEQ"].ToString();
                model.M_Z      = double.Parse(ds.Tables[0].Rows[i]["MZ"].ToString());
                model.Forumla  = ds.Tables[0].Rows[i]["FORUMLA"].ToString();
                model.M_Z_ALL  = ds.Tables[0].Rows[i]["MZ_ALL"].ToString().Split(',').Select(ms => double.Parse(ms)).ToList();
                model.M_ALL    = ds.Tables[0].Rows[i]["Relative_Abundance_ALL"].ToString().Split(',').Select(ms => double.Parse(ms)).ToList();

                List <MassPoint> lstMassPoint = new List <MassPoint>();
                for (int j = 0; j < model.M_Z_ALL.Count; j++)
                {
                    MassPoint mp = new MassPoint();

                    mp.Mass      = Convert.ToDouble(model.M_Z_ALL[j]);
                    mp.Intensity = Convert.ToDouble(model.M_ALL[j]);

                    if (Convert.ToDouble(model.M_ALL[j]) * 100 > ipaco)
                    {
                        if (Convert.ToDouble(model.M_ALL[j]) == 1.000)
                        {
                            model.M = lstMassPoint.Count;
                        }
                        lstMassPoint.Add(mp);
                    }
                }

                model.Mass_Point = lstMassPoint;
                lst.Add(model);
            }

            return(lst);
        }
コード例 #9
0
    public Spring(MassPoint massPoint1, MassPoint massPoint2, float springConstant)
    {
        this.massPoint1     = massPoint1;
        this.massPoint2     = massPoint2;
        this.springConstant = springConstant;


        restingLength        = Vector3.Magnitude(massPoint1.Position - massPoint2.Position);
        tearTolerance        = restingLength * 2.59f;
        squaredRestingLength = Vector3.SqrMagnitude(massPoint2.Position - massPoint1.Position);
        direction            = new Vector3();
    }
コード例 #10
0
        private static void Main()
        {
            var sep  = Path.DirectorySeparatorChar;
            var path = $@"..{sep}..{sep}..{sep}MassPoints.bin";

            var elements = new List <MassPoint>();
            var radius   = GetNumber <double>("Enter radius of set: ",
                                              el => el > 1);

            try
            {
                // Read info from file.
                using (var sr = new StreamReader(new FileStream(path, FileMode.Open)))
                {
                    string line;

                    while ((line = sr.ReadLine()) != null)
                    {
                        MassPoint massPoint = GetMassPoint(line);

                        elements.Add(massPoint);
                    }
                }

                var real = new SetOfMassPoint(elements, new PointS(0, 0), radius);

                PrintMessage("\nSuitable points:\n\n", ConsoleColor.Green);
                PrintMessage(real.ToString(), ConsoleColor.Yellow);
            }
            catch (IOException)
            {
                PrintMessage("Problem with file!\n", ConsoleColor.Red);
            }
            catch (Exception)
            {
                PrintMessage("Unexpected error!\n", ConsoleColor.Red);
            }

            PrintMessage("\nPress ESC to exit...", ConsoleColor.Green);
            while (Console.ReadKey().Key != ConsoleKey.Escape)
            {
                ;
            }
        }
コード例 #11
0
        private void AddPointsAndSprings(List <TriangleVertexIndices> indices, List <JVector> vertices)
        {
            for (int i = 0; i < vertices.Count; i++)
            {
                MassPoint point = new MassPoint(sphere, this, material);
                point.Position = vertices[i];

                point.Mass = 0.1f;

                points.Add(point);
            }

            for (int i = 0; i < indices.Count; i++)
            {
                TriangleVertexIndices index = indices[i];

                Triangle t = new Triangle(this);

                t.indices = index;
                triangles.Add(t);

                t.boundingBox = JBBox.SmallBox;
                t.boundingBox.AddPoint(points[t.indices.I0].position);
                t.boundingBox.AddPoint(points[t.indices.I1].position);
                t.boundingBox.AddPoint(points[t.indices.I2].position);

                t.dynamicTreeID = dynamicTree.AddProxy(ref t.boundingBox, t);
            }

            HashSet <Edge> edges = GetEdges(indices);

            int count = 0;

            foreach (Edge edge in edges)
            {
                Spring spring = new Spring(points[edge.Index1], points[edge.Index2]);
                spring.Softness   = 0.01f; spring.BiasFactor = 0.1f;
                spring.SpringType = SpringType.EdgeSpring;

                springs.Add(spring);
                count++;
            }
        }
コード例 #12
0
    public void RemoveMassSpring(int vid1, int vid2)
    {
        //UnityEngine.Debug.LogFormat ("RemoveMassSpring {0} {1}", vid1, vid2);

        MassPoint m1 = dicVertex2Mass [vid1];
        MassPoint m2 = dicVertex2Mass [vid2];

        if (MassSprings [m1.id].ContainsKey(m2.id))
        {
            MassSprings [m1.id].Remove(m2.id);
        }

        if (MassSprings [m2.id].ContainsKey(m1.id))
        {
            MassSprings [m2.id].Remove(m1.id);
        }

        Vector3 v1 = originalVertices [vid1];
        Vector3 v2 = originalVertices [vid2];

        float value = 0.05f;

        if (!dic_Force.ContainsKey(m1.id))
        {
            dic_Force.Add(m1.id, (v1 - v2) * value);
        }
        else
        {
            dic_Force [m1.id] += (v1 - v2) * value;
        }

        if (!dic_Force.ContainsKey(m2.id))
        {
            dic_Force.Add(m2.id, (v2 - v1) * value);
        }
        else
        {
            dic_Force [m2.id] += (v2 - v1) * value;
        }
    }
コード例 #13
0
    // Use this for initialization
    void Start()
    {
        pointList = new List <MassPoint>();
        MassPoint mp;

        for (int i = 0; i < 2; i++)
        {
            for (int j = 0; j < 15; j++)
            {
                if (j == 0)
                {
                    mp = new MassPoint(new Vector3(-10 + (j * 0.5f), 0.5f * i, 0), 20.0f, true);
                }
                else
                {
                    mp = new MassPoint(new Vector3(-10 + (j * 0.5f), 0.5f * i, 0), 20.0f, false);
                    mp.ConnectTo(pointList[pointList.Count - 1]);
                }
                pointList.Add(mp);
            }
        }
        for (int i = 0; i < 15; i++)
        {
            {
                pointList[i].ConnectTo(pointList[i + 15]);
            }
            if (i != 0)
            {
                pointList[i].ConnectTo(pointList[i + 14]);
            }
            if (i != 14)
            {
                pointList[i].ConnectTo(pointList[i + 16]);
            }
        }

        isInitialized = true;
    }
コード例 #14
0
        private void AddPointsAndSprings(List<TriangleVertexIndices> indices, List<JVector> vertices)
        {
            for (int i = 0; i < vertices.Count; i++)
            {
                MassPoint point = new MassPoint(sphere, this,material);
                point.Position = vertices[i];

                point.Mass = 0.1f;

                points.Add(point);
            }

            for (int i = 0; i < indices.Count; i++)
            {
                TriangleVertexIndices index = indices[i];
                
                Triangle t = new Triangle(this);

                t.indices = index;
                triangles.Add(t);

                t.boundingBox = JBBox.SmallBox;
                t.boundingBox.AddPoint(points[t.indices.I0].position);
                t.boundingBox.AddPoint(points[t.indices.I1].position);
                t.boundingBox.AddPoint(points[t.indices.I2].position);

                t.dynamicTreeID = dynamicTree.AddProxy(ref t.boundingBox, t);
            }

            HashSet<Edge> edges = GetEdges(indices);

            int count = 0;

            foreach (Edge edge in edges)
            {
                Spring spring = new Spring(points[edge.Index1], points[edge.Index2]);
                spring.Softness = 0.01f; spring.BiasFactor = 0.1f;
                spring.SpringType = SpringType.EdgeSpring;

                springs.Add(spring);
                count++;
            }

        }
コード例 #15
0
 public double Distance(MassPoint other)
 {
     return((Position - other.Position).Length);
 }
コード例 #16
0
    void AddMeshSprings(Dictionary <int, List <int> > dicSameVertex)
    {
        foreach (int id in dicSameVertex.Keys)
        {
            MassPoint mass;
            if (dicVertex2Mass.ContainsKey(id) == false)
            {
                mass          = new MassPoint();
                mass.id       = Masses.Count;
                mass.pos      = originalVertices [id];
                mass.vertices = new List <int> ();
                mass.vertices.Add(id);
                Masses.Add(mass);
                dicVertex2Mass [id] = mass;
            }
            else
            {
                mass = dicVertex2Mass [id];
            }

            List <int> refs = dicSameVertex [id];

            for (int j = 0; j < refs.Count; j++)
            {
                int vid = refs [j];
                dicVertex2Mass [vid] = mass;
                if (mass.vertices.Contains(vid) == false)
                {
                    mass.vertices.Add(vid);
                }
            }
        }

        // 质点弹簧初始化
        int[] triangles = _mesh.triangles;
        for (int i = 0; i < triangles.Length / 3; i++)
        {
            int     vidx1 = triangles [i * 3];
            int     vidx2 = triangles [i * 3 + 1];
            int     vidx3 = triangles [i * 3 + 2];
            Vector3 v1    = originalVertices [vidx1];
            Vector3 v2    = originalVertices [vidx2];
            Vector3 v3    = originalVertices [vidx3];
            float   dst12 = (v2 - v1).magnitude;
            float   dst13 = (v3 - v1).magnitude;
            float   dst23 = (v3 - v2).magnitude;

            MassPoint m1 = dicVertex2Mass [vidx1];
            MassPoint m2 = dicVertex2Mass [vidx2];
            MassPoint m3 = dicVertex2Mass [vidx3];

            if (!MassSprings.ContainsKey(m1.id))
            {
                MassSprings.Add(m1.id, new Dictionary <int, float> ());
            }
            if (!MassSprings.ContainsKey(m2.id))
            {
                MassSprings.Add(m2.id, new Dictionary <int, float> ());
            }
            if (!MassSprings.ContainsKey(m3.id))
            {
                MassSprings.Add(m3.id, new Dictionary <int, float> ());
            }
            if (!MassSprings[m1.id].ContainsKey(m2.id))
            {
                MassSprings[m1.id].Add(m2.id, dst12);
            }
            if (!MassSprings[m1.id].ContainsKey(m3.id))
            {
                MassSprings[m1.id].Add(m3.id, dst13);
            }
            if (!MassSprings[m2.id].ContainsKey(m1.id))
            {
                MassSprings[m2.id].Add(m1.id, dst12);
            }
            if (!MassSprings[m2.id].ContainsKey(m3.id))
            {
                MassSprings[m2.id].Add(m3.id, dst23);
            }
            if (!MassSprings[m3.id].ContainsKey(m1.id))
            {
                MassSprings[m3.id].Add(m1.id, dst13);
            }
            if (!MassSprings[m3.id].ContainsKey(m2.id))
            {
                MassSprings[m3.id].Add(m2.id, dst23);
            }
        }
    }
コード例 #17
0
ファイル: Connector.cs プロジェクト: slwatmough/CyberElegans
 public Connector(MassPoint p1, MassPoint p2)
 {
     status  = 1;
     this.P1 = p1;
     this.P2 = p2;
 }
コード例 #18
0
    void UpdateVertices()
    {
        UnityEngine.Debug.Log("Update Vertices");

        Stopwatch sw = new Stopwatch();

        sw.Start();

        if (dic_VertexForce.Count == 0)
        {
            _mesh.vertices = originalVertices;
            _mesh.RecalculateNormals();
            NormalSolver.RecalculateNormals(_mesh, 30);
            return;
        }

        Vector3[,] offsets = new Vector3[Masses.Count, dic_VertexForce.Count];

        Dictionary <int, Vector3> .Enumerator it = dic_VertexForce.GetEnumerator();
        int forceIdx = 0;

        while (it.MoveNext())
        {
            int     vertexIdx = it.Current.Key;
            Vector3 force     = it.Current.Value;

            offsets[vertexIdx, forceIdx++] = force;
        }


        // 多组质点弹簧遍历
        it = dic_VertexForce.GetEnumerator();
        Queue <int>   masses = new Queue <int> ();
        HashSet <int> mark   = new HashSet <int> ();

        forceIdx = 0;
        while (it.MoveNext())
        {
            int     vidx_force = it.Current.Key;
            Vector3 force      = it.Current.Value;

            offsets[vidx_force, forceIdx] = force;

            masses.Clear();
            mark.Clear();
            masses.Enqueue(vidx_force);
            mark.Add(vidx_force);

            // 一组质点弹簧遍历
            while (masses.Count > 0)
            {
                int     vidx  = masses.Dequeue();
                Vector3 delta = offsets[vidx, forceIdx];

                // 遍历此节点所有链接点
                Dictionary <int, float>             edge = MassSprings [vidx];
                Dictionary <int, float> .Enumerator iter = edge.GetEnumerator();
                while (iter.MoveNext())
                {
                    int   idx   = iter.Current.Key;
                    float value = iter.Current.Value;

                    int key = vidx > idx ? vidx | (idx << 16) : (vidx << 16) | idx;
                    if (mark.Contains(key))
                    {
                        continue;
                    }

                    Vector3 v = delta / (1 + value / kViscosity);

                    if (v.magnitude <= kThresholdZero)
                    {
                        continue;
                    }

                    if (!dic_VertexForce.ContainsKey(idx) && offsets[idx, forceIdx].sqrMagnitude < v.sqrMagnitude)
                    {
                        offsets[idx, forceIdx] = v;

                        masses.Enqueue(idx);
                    }
                }

                iter = edge.GetEnumerator();
                while (iter.MoveNext())
                {
                    int idx = iter.Current.Key;
                    int key = vidx > idx ? vidx | (idx << 16) : (vidx << 16) | idx;
                    mark.Add(key);
                }
            }

            forceIdx++;
        }


        sw.Stop();
        //UnityEngine.Debug.LogFormat ("using {0}", sw.ElapsedMilliseconds);


        // 计算各顶点偏移量
        for (int i = 0; i < offsets.GetLength(0); i++)
        {
            Vector3 result = Vector3.zero;

            // 计算改顶点最终形变量(x,y,z)
            for (int j = 0; j < 3; j++)
            {
                float positive = 0f;
                float negative = 0f;

                for (int k = 0; k < dic_VertexForce.Count; k++)
                {
                    Vector3 offset = offsets [i, k];
                    float   v      = offset [j];
                    if (v > 0 && v > positive)
                    {
                        positive = v;
                    }
                    else if (v < 0 && v < negative)
                    {
                        negative = v;
                    }
                }

                result [j] = positive + negative;
            }

            // 最终结果保存在第一个位置
            offsets [i, 0] = result;
        }

        // 计算出最新的顶点位置
        for (int i = 0; i < Masses.Count; i++)
        {
            MassPoint mass = Masses [i];

            for (int j = 0; j < mass.vertices.Count; j++)
            {
                int vid = mass.vertices [j];
                displacedVertices [vid] = originalVertices [vid] + offsets [i, 0];
            }
        }

        _mesh.vertices = displacedVertices;
        _mesh.RecalculateNormals();
        NormalSolver.RecalculateNormals(_mesh, 30);
    }
コード例 #19
0
    void UpdateMassSpringsMesh()
    {
        Vector3[,] offsets = new Vector3[Masses.Count, dic_Force.Count];

        Dictionary <int, Vector3> .Enumerator it = dic_Force.GetEnumerator();
        int forceIdx = 0;

        while (it.MoveNext())
        {
            int     vertexIdx = it.Current.Key;
            Vector3 force     = it.Current.Value;

            offsets[vertexIdx, forceIdx++] = force;
        }


        // 多组质点弹簧遍历
        it = dic_Force.GetEnumerator();
        Queue <int>   masses = new Queue <int> ();
        HashSet <int> mark   = new HashSet <int> ();

        forceIdx = 0;
        while (it.MoveNext())
        {
            int     vidx_force = it.Current.Key;
            Vector3 force      = it.Current.Value;

            offsets[vidx_force, forceIdx] = force;

            masses.Clear();
            mark.Clear();
            masses.Enqueue(vidx_force);
            mark.Add(vidx_force);

            // 一组质点弹簧遍历
            while (masses.Count > 0)
            {
                int     vidx  = masses.Dequeue();
                Vector3 delta = offsets[vidx, forceIdx];

                // 遍历此节点所有链接点
                Dictionary <int, float>             edge = MassSprings [vidx];
                Dictionary <int, float> .Enumerator iter = edge.GetEnumerator();
                while (iter.MoveNext())
                {
                    int   idx   = iter.Current.Key;
                    float value = iter.Current.Value;

                    int key = vidx > idx ? vidx | (idx << 16) : (vidx << 16) | idx;
                    if (mark.Contains(key))
                    {
                        continue;
                    }

                    Vector3 v = delta / (1 + value / kViscosity);

                    if (v.magnitude <= kThresholdZero)
                    {
                        continue;
                    }

                    if (!dic_Force.ContainsKey(idx) && offsets[idx, forceIdx].sqrMagnitude < v.sqrMagnitude)
                    {
                        offsets[idx, forceIdx] = v;

                        masses.Enqueue(idx);
                    }
                }

                iter = edge.GetEnumerator();
                while (iter.MoveNext())
                {
                    int idx = iter.Current.Key;
                    int key = vidx > idx ? vidx | (idx << 16) : (vidx << 16) | idx;
                    mark.Add(key);
                }
            }

            forceIdx++;
        }

        // 计算各顶点偏移量
        for (int i = 0; i < offsets.GetLength(0); i++)
        {
            Vector3 result = Vector3.zero;

            // 计算改顶点最终形变量(x,y,z)
            for (int j = 0; j < 3; j++)
            {
                float positive = 0f;
                float negative = 0f;

                for (int k = 0; k < dic_Force.Count; k++)
                {
                    Vector3 offset = offsets [i, k];
                    float   v      = offset [j];
                    if (v > 0 && v > positive)
                    {
                        positive = v;
                    }
                    else if (v < 0 && v < negative)
                    {
                        negative = v;
                    }
                }

                result [j] = positive + negative;
            }

            // 最终结果保存在第一个位置
            offsets [i, 0] = result;
        }

        // 计算出最新的质点位置
        for (int i = 0; i < Masses.Count; i++)
        {
            MassPoint mass = Masses [i];
            mass.pos += offsets [i, 0];

            for (int j = 0; j < mass.vertices.Count; j++)
            {
                int vid = mass.vertices [j];
                originalVertices [vid] = originalVertices [vid] + offsets [i, 0];
            }
        }
    }
コード例 #20
0
 public void ConnectTo(MassPoint massPoint)
 {
     attachedSprings.Add(new Spring(this, massPoint, 0.7f));
 }