예제 #1
0
        private void AddShallowBump(Point2I point, fieldT currFld,
                                    LinkedList <bumpT> steepBumps, LinkedList <bumpT> shallowBumps)
        {
            // First, the far point of shallow is set to the new point.
            currFld.m_Shallow.m_Far = point;
            // Second, we need to add the new bump to the shallow bump list for
            // future steep bump handling.
            shallowBumps.AddLast(new bumpT());
            shallowBumps.Last.Value.m_Location = point;
            shallowBumps.Last.Value.m_Parent   = currFld.m_ShallowBump;
            currFld.m_ShallowBump = shallowBumps.Last.Value;
            // Now we have too look through the list of steep bumps and see if
            // any of them are below the line.
            // If there are, we need to replace near point too.
            bumpT currentBump = currFld.m_SteepBump;

            while (currentBump != null)
            {
                if (currFld.m_Shallow.IsAbove(currentBump.m_Location))
                {
                    currFld.m_Shallow.m_Near = currentBump.m_Location;
                }
                currentBump = currentBump.m_Parent;
            }
        }
예제 #2
0
 public fieldT(fieldT f)
 {
     m_Steep = new Line2I(new Point2I(f.m_Steep.m_Near.m_X, f.m_Steep.m_Near.m_Y),
                          new Point2I(f.m_Steep.m_Far.m_X, f.m_Steep.m_Far.m_Y));
     m_Shallow = new Line2I(
         new Point2I(f.m_Shallow.m_Near.m_X, f.m_Shallow.m_Near.m_Y),
         new Point2I(f.m_Shallow.m_Far.m_X, f.m_Shallow.m_Far.m_Y));
     m_SteepBump   = f.m_SteepBump;
     m_ShallowBump = f.m_ShallowBump;
 }
예제 #3
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);
        }
예제 #4
0
        private void AddSteepBump(Point2I point, fieldT currFld,
                                  LinkedList <bumpT> steepBumps, LinkedList <bumpT> shallowBumps)
        {
            currFld.m_Steep.m_Far = point;
            steepBumps.AddLast(new bumpT());
            steepBumps.Last.Value.m_Location = point;
            steepBumps.Last.Value.m_Parent   = currFld.m_SteepBump;
            currFld.m_SteepBump = steepBumps.Last.Value;
            // Now look through the list of shallow bumps and see if any of them
            // are below the line.
            bumpT currentBump = currFld.m_ShallowBump;

            while (currentBump != null)
            {
                if (currFld.m_Steep.IsBelow(currentBump.m_Location))
                {
                    currFld.m_Steep.m_Near = currentBump.m_Location;
                }
                currentBump = currentBump.m_Parent;
            }
        }
예제 #5
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);
            }
        }