protected void applyHookesLaw(bool twoD = false)
        {
            foreach (var e in Graph.Edges)
            {
                SpringFD spring       = GetSpring(e);
                Vector3  d            = spring.point2.Position - spring.point1.Position;
                float    displacement = spring.Length - d.magnitude;
                Vector3  direction    = d.normalized;
                if (twoD)
                {
                    direction.z = 0;
                }

                if (spring.point1.Pinned && spring.point2.Pinned)
                {
                    spring.point1.ApplyForce(direction * 0.0f);
                    spring.point2.ApplyForce(direction * 0.0f);
                }
                else if (spring.point1.Pinned)
                {
                    spring.point1.ApplyForce(direction * 0.0f);
                    spring.point2.ApplyForce(direction * (spring.K * displacement));
                }
                else if (spring.point2.Pinned)
                {
                    spring.point1.ApplyForce(direction * (spring.K * displacement * -1.0f));
                    spring.point2.ApplyForce(direction * 0.0f);
                }
                else
                {
                    spring.point1.ApplyForce(direction * (spring.K * displacement * -0.5f));
                    spring.point2.ApplyForce(direction * (spring.K * displacement * 0.5f));
                }
            }
        }
        //get spring associated to edge
        public SpringFD GetSpring(IEdge <INode> edge)
        {
            //if (!(m_edgeSprings.ContainsKey(edge.Uid)))
            //{
            //    float length = GetEdgeLength(edge);
            //    SpringFD existingSpring = null;

            //    List<IEdge<INode>> fromEdges = (SimpleGraph)Graph.GetEdges(edge.Source, edge.Target);
            //    if (fromEdges != null)
            //    {
            //        foreach (Edge e in fromEdges)
            //        {
            //            if (existingSpring == null && m_edgeSprings.ContainsKey(e.ID))
            //            {
            //                existingSpring = m_edgeSprings[e.ID];
            //                break;
            //            }
            //        }

            //    }
            //    if (existingSpring != null)
            //    {
            //        return new SpringFD(existingSpring.point1, existingSpring.point2, 0.0f, 0.0f);
            //    }

            //    List<Edge> toEdges = Graph.GetEdges(edge.Target, edge.Source);
            //    if (toEdges != null)
            //    {
            //        foreach (Edge e in toEdges)
            //        {
            //            if (existingSpring == null && m_edgeSprings.ContainsKey(e.ID))
            //            {
            //                existingSpring = m_edgeSprings[e.ID];
            //                break;
            //            }
            //        }
            //    }

            //    if (existingSpring != null)
            //    {
            //        return new SpringFD(existingSpring.point2, existingSpring.point1, 0.0f, 0.0f);
            //    }
            //    m_edgeSprings[edge.ID] = new SpringFD(GetPoint(edge.Source), GetPoint(edge.Target), length, Stiffness);

            //}
            //return m_edgeSprings[edge.Uid];
            SpringFD spring;

            if (!m_edgeSprings.TryGetValue(edge.Uid, out spring))
            {
                spring = new SpringFD(GetPoint(edge.Source), GetPoint(edge.Target), GetEdgeLength(edge), Stiffness);
                m_edgeSprings.Add(edge.Uid, spring);
            }
            return(m_edgeSprings[edge.Uid]);
        }