public static int CalculateMatchAngle(ConnectionDirection[] From, ConnectionDirection[] To)
        {
            Dictionary <int, int> Result = new Dictionary <int, int> ();

            for (int i = 0; i < From.Length; i++)
            {
                Vector3 F = ModularPieceExtensions.DirectionToVector(From[i]);
                for (int x = 0; x < To.Length; x++)
                {
                    Vector3 T     = ModularPieceExtensions.DirectionToVector(To[x]);
                    int     Angle = SignedAngle(F, T);
                    if (!Result.ContainsKey(Angle))
                    {
                        Result.Add(Angle, 1);
                    }
                    else
                    {
                        Result [Angle] = Result[Angle] + 1;
                    }
                }
            }
            var Highest = Result.OrderBy(kvp => kvp.Value).Last();               // find highest count

            return((int)Highest.Key);
        }
        private static ConnectionDirection[] DirectionsToConnectionDirections(Vector3[] Directions)
        {
            List <ConnectionDirection> Dirs = new List <ConnectionDirection> ();

            for (int i = 0; i < Directions.Length; i++)
            {
                Dirs.Add(ModularPieceExtensions.VectorToDirection(Directions[i]));
            }
            return(Dirs.ToArray());
        }
        public static ConnectionDirection[] ConnectionToWorldConnection(ConnectionDirection[] ConnectionDirections, Quaternion LocalRotation)
        {
            int        Rotation       = GlobalCalulations.RoundToWholeNumbers(90f, LocalRotation.eulerAngles.y);
            Quaternion OffsetRotation = Quaternion.Euler(0, Rotation, 0);                                   // calcualte offset rotation

            Vector3[] Vectors = ModularPieceExtensions.DirectionsToVectors(ConnectionDirections.ToArray()); // convert to vector3 array
            for (int i = 0; i < Vectors.Length; i++)
            {
                Vectors [i] = OffsetRotation * Vectors [i];
            }                                                                                                  // offset vectors
            return(ModularPieceExtensions.VectorsToDirections(Vectors));
        }
        public static HashSet <IStrokeConnection> UpdateCurrentlyConnected(this IStrokeConnection Self, HashSet <IStrokeConnection> CurrentlyConnected, float CheckDistance, Vector3 CenterPosition, LayerMask Layers)
        {
            HashSet <IStrokeConnection> TempConnections = new HashSet <IStrokeConnection> ();

            ModularPieceExtensions.ForEachConnection((IStrokeConnection Connection, Vector3 Pos) => {
                TempConnections.Add(Connection);
                if (!CurrentlyConnected.Contains(Connection))                 // new connection wasnt in last connections meaning its added
                {
                    Connection.OnSurroundingAdded(Self);
                }
            }, Self.StrokeCategory, CheckDistance, CenterPosition, Layers);

            foreach (IStrokeConnection Connection in CurrentlyConnected)
            {
                if (!TempConnections.Contains(Connection))                    // old connection is not in the new connections anymore meaning its gone
                {
                    Connection.OnSurroundingRemoved(Self);
                }
            }

            return(TempConnections);            // set temp connections
        }