예제 #1
0
        private bool CheckField(CLikeIterator <fieldT> currentField)
        {
            // If the two slopes are colinear, and if they pass through either
            // extremity, remove the field of view.
            fieldT currFld = currentField.GetCurrent();
            bool   ret     = false;

            if (currFld.m_Shallow.DoesContain(currFld.m_Steep.m_Near) &&
                currFld.m_Shallow.DoesContain(currFld.m_Steep.m_Far) &&
                (currFld.m_Shallow.DoesContain(new Point2I(0, 1)) || currFld.m_Shallow
                 .DoesContain(new Point2I(1, 0))))
            {
                currentField.RemoveCurrent();
                ret = true;
            }
            return(ret);
        }
예제 #2
0
        private void VisitSquare(fovStateT state, Point2I dest,
                                 CLikeIterator <fieldT> currentField, LinkedList <bumpT> steepBumps,
                                 LinkedList <bumpT> shallowBumps, LinkedList <fieldT> activeFields)
        {
            // The top-left and bottom-right corners of the destination square.
            Point2I topLeft     = new Point2I(dest.m_X, dest.m_Y + 1);
            Point2I bottomRight = new Point2I(dest.m_X + 1, dest.m_Y);

            while (!currentField.IsAtEnd() &&
                   currentField.GetCurrent().m_Steep
                   .IsBelowOrContains(bottomRight))
            {
                // case ABOVE
                // The square is in case 'above'. This means that it is ignored
                // for the currentField. But the steeper fields might need it.
                currentField.GotoNext();
            }
            if (currentField.IsAtEnd())
            {
                // The square was in case 'above' for all fields. This means that
                // we no longer care about it or any squares in its diagonal rank.
                return;
            }

            // Now we check for other cases.
            if (currentField.GetCurrent().m_Shallow.IsAboveOrContains(topLeft))
            {
                // case BELOW
                // The shallow line is above the extremity of the square, so that
                // square is ignored.
                return;
            }
            // The square is between the lines in some way. This means that we
            // need to visit it and determine whether it is blocked.
            bool isBlocked = ActIsBlocked(state, dest);

            if (!isBlocked)
            {
                // We don't care what case might be left, because this square does
                // not obstruct.
                return;
            }

            if (currentField.GetCurrent().m_Shallow.IsAbove(bottomRight) &&
                currentField.GetCurrent().m_Steep.IsBelow(topLeft))
            {
                // case BLOCKING
                // Both lines intersect the square. This current field has ended.
                currentField.RemoveCurrent();
            }
            else if (currentField.GetCurrent().m_Shallow.IsAbove(bottomRight))
            {
                // case SHALLOW BUMP
                // The square intersects only the shallow line.
                AddShallowBump(topLeft, currentField.GetCurrent(), steepBumps,
                               shallowBumps);
                CheckField(currentField);
            }
            else if (currentField.GetCurrent().m_Steep.IsBelow(topLeft))
            {
                // case STEEP BUMP
                // The square intersects only the steep line.
                AddSteepBump(bottomRight, currentField.GetCurrent(), steepBumps,
                             shallowBumps);
                CheckField(currentField);
            }
            else
            {
                // case BETWEEN
                // The square intersects neither line. We need to split into two
                // fields.
                fieldT steeperField   = currentField.GetCurrent();
                fieldT shallowerField = new fieldT(currentField.GetCurrent());
                currentField.InsertBeforeCurrent(shallowerField);
                AddSteepBump(bottomRight, shallowerField, steepBumps, shallowBumps);
                currentField.GotoPrevious();
                if (!CheckField(currentField)) // did not remove
                {
                    currentField.GotoNext();   // point to the original element
                }
                AddShallowBump(topLeft, steeperField, steepBumps, shallowBumps);
                CheckField(currentField);
            }
        }