Beispiel #1
0
 public static Pointf Reflect(Pointf inDirection, Pointf inNormal)
 {
     return(-2 * Pointf.Dot(inNormal, inDirection) * inNormal + inDirection);
 }
    void CalcGraphStats()
    {
        double segmentLengthSum = 0;
        int    segmentCount     = 0;

        double extremeLength = 0;
        Pointf extreme1      = Pointf.zero;
        Pointf extreme2      = Pointf.zero;

        int n = puzzle.stateNodes.Count;

        for (int i = 0; i < n; i++)
        {
            PuzzleStateNode node1 = puzzle.stateNodes[i];
            for (int j = 0; j < i; j++)
            {
                PuzzleStateNode node2  = puzzle.stateNodes[j];
                Pointf          vector = node2.point - node1.point;
                double          len    = vector.magnitude;

                double dist = distances[i, j];
                if (dist == 1)
                {
                    segmentCount++;
                    segmentLengthSum += len;
                }

                if (len > extremeLength)
                {
                    extremeLength = len;
                    extreme1      = node1.point;
                    extreme2      = node2.point;
                }
            }
        }

        if (segmentCount == 0)
        {
            centerTarget   = Pointf.zero;
            diameterTarget = 0;
            angleTarget    = 0;
        }
        else
        {
            segmentLength = segmentLengthSum / segmentCount;
            centerTarget  = (extreme2 + extreme1) * 0.5;
            Pointf mainAxis = (extreme2 - extreme1);
            diameterTarget = mainAxis.magnitude;
            mainAxis       = mainAxis / diameterTarget;
            Pointf axis2 = new Pointf(-mainAxis.y, mainAxis.x);

            double projectedMin = double.MaxValue;
            double projectedMax = double.MinValue;
            for (int i = 0; i < n; i++)
            {
                Pointf p          = puzzle.stateNodes[i].point;
                Pointf rel        = p - centerTarget;
                double relOnAxis2 = Pointf.Dot(rel, axis2);
                projectedMin = Math.Min(projectedMin, relOnAxis2);
                projectedMax = Math.Max(projectedMax, relOnAxis2);
            }

            angleTarget   = Math.Atan2(mainAxis.x, -mainAxis.y);
            centerTarget += axis2 * (projectedMin + projectedMax) * 0.5;

            diameterTarget /= segmentLength;
        }
    }