public static double CalculateAngle
   (MutableVector a, MutableVector b)
 {
   a.Normalize();  
   b.Normalize();
   var theta = Math.Acos(a.X * b.X + a.Y * b.Y + a.Z * b.Z);
   return theta * 180 / Math.PI;
 }
Esempio n. 2
0
    public static double CalculateAngle
        (MutableVector a, MutableVector b)
    {
        a.Normalize();
        b.Normalize();
        var theta = Math.Acos(a.X * b.X + a.Y * b.Y + a.Z * b.Z);

        return(theta * 180 / Math.PI);
    }
Esempio n. 3
0
    public static MutableVector <int> GetNeighbor(IList <int> coordinate, int side)
    {
        var neighbor = MutableVector <int> .CopyOf(coordinate);

        if (side < coordinate.Count)
        {
            --neighbor[side];
        }
        else
        {
            ++neighbor[side - coordinate.Count];
        }
        return(neighbor);
    }
        /// <summary>
        /// Performs one step in the layout process. Most uses will want to call this in a loop
        /// until there is little energy left in the system, or some amount of time has elapsed.
        /// </summary>
        /// <param name="handle_constraints">Whether to enforce constraints on this step of not.</param>
        /// <returns>An approximation of the total acceleration of the system...?</returns>
        public double Step()
        {
            // every thread must perform thread-safe operations only
            Parallel.For(0, nodes.Length, (i) =>
            {
                FDLNode node = nodes[i];
                MutableVector force = new MutableVector(Vector.ZERO_VECTOR);

                //sum forces
                for (int j = 0; j < nodes.Length; j++)
                {
                    if (j == i)
                        continue;

                    FDLNode other_node = nodes[j];
                    force.Add(NodeNodeForce(node, other_node));
                }

                //sum forces
                foreach (FDLEdge edge in node.InEdges)
                {
                    force.Add(EdgeForce(edge));
                    force.Add(EdgeTorque(edge));
                }

                //derive acceleration
                Vector acceleration = (Vector)force / node.Mass;
                accels[i] = acceleration.Magnitude;

                //derive position
                if (first_step)
                {
                    //eulers integration - assume old velocity was zero for first step
                    new_positions[i] = new MutablePoint(node.Position);
                    new_positions[i].Add(1.5 * acceleration * TIMESTEP_SQUARED);
                }
                else
                {
                    //verlet integration - requires constant timestep
                    new_positions[i].X = 0;
                    new_positions[i].Y = 0;

                    new_positions[i].Add((1 + DAMPING) * node.Position);
                    new_positions[i].Subtract(DAMPING * node.PreviousPosition);
                    new_positions[i].Add(acceleration * TIMESTEP_SQUARED);
                }
            }
            );

            // update node positions and sum accelerations
            double totalAccel = 0;
            for (int i = 0; i < nodes.Length; i++)
            {
                nodes[i].Position = (Point)new_positions[i];
                totalAccel += accels[i];
            }

            first_step = false;

            // i'm not sure what to call this measure...
            // but it isn't time or mass biased, which seems to make it a good indicator of a
            // local minima of... some measure of energy? My best guess is that it's a
            // really terrible and inaccurate approximation of the total acceleration of
            // the system. Approximation, since it sums forces only on a per node rather system
            // basis.
            return totalAccel;
        }