Detecting when a drawn line hits itself

Hi everyone, hoping someone can help. I’m trying to do a program where a user draws on the screen with a mouse, with the goal of the program detecting when it hits itself.

As the user moves his mouse, a line segment is drawn from the previous point to the new point, and the beginning and ending x,y coordinates are stored in an array (in this case the array is called theLine and is of class playerLine). I also do a special hit detect routine after each drawn segment, where it checks for possible intersection between all previous segments (except the closest one).

I’m drawing sloppy ellipses for the test shape. The issue I’m having is the current version detects just fine if I move the mouse slow just before I see its going to hit. But if I move the mouse quickly, it doesn’t detect the hit when the line crosses itself.

Here’s the main calling routine:

 private function drawLine(event:MouseEvent):void
{
  if (buttonDown == true)
  {
      var hitTest:Boolean = false;
      theDrawField.graphics.lineStyle(1, 0xFF0000);
      theDrawField.graphics.lineTo(mouseX, mouseY);
      hitTest = theLine.addSegment(previousX, previousY, mouseX, mouseY);
      previousX = mouseX;
      previousY = mouseY;
      if (hitTest == true)
      {
         buttonDown = false;
      }

   }
}

And here’s the line class, including the line intersection routine:

 package
{
    import flash.display.*;
    import flash.events.*;
    
    public class playerLine extends Sprite
    {
        private var lineSegment:Array;
        private var theLine:Array = new Array();
        private var numSegments:Number = 0;
        
        public function playerLine()
        {
            
        }
        
        public function addSegment(x1:Number, y1:Number, x2:Number, y2:Number):Boolean
        {
            var mpx:Number = (x1+x2)/2;
            var mpy:Number = (y1+y2)/2;
            //trace("x:" + x1 + " y:" + y1 + " x2:" + x2 + " y2:" + y2 + " mpx:" + mpx + " mpy:" + mpy);
            lineSegment = new Array(x1, y1, x2, y2, mpx, mpy);
            theLine[numSegments] = lineSegment;
            
            for (var counter:Number = 0; counter < numSegments; counter++)
            {
                //trace(theLine[counter][4] + "," + lineSegment[4]);
                if ((lineSegment[4] <= (theLine[counter][4]+2)) && (lineSegment[4] >= (theLine[counter][4]-2)))
                {
                    if ((lineSegment[5] <= (theLine[counter][5]+2)) && (lineSegment[5] >= (theLine[counter][5]-2)))
                    {
                        if (numSegments >= counter + 2)
                        {
                            //trace(lineSegment[4] + "is close to " + theLine[counter][4])
                            if (LineToLineIntersection(theLine[counter][0],theLine[counter][1], theLine[counter][2], theLine[counter][3], lineSegment[0], lineSegment[1], lineSegment[2], lineSegment[3]))
                            {
                                return true;
                            }
                        }
                    }
                }
            }
            numSegments++;
            //trace (numSegments);
            return false;
            
        }

        public function LineToLineIntersection(x1_:Number, y1_:Number, x2_:Number, y2_:Number, x3_:Number, y3_:Number, x4_:Number, y4_:Number):Boolean
        {
            var theResult:Boolean = false;
            var r:Number, s:Number, d:Number;
            d = (((x2_-x1_)*(y4_-y3_))-(y2_-y1_)*(x4_-x3_));
            
            if(d != 0)
            {
                r = (((y1_-y3_)*(x4_-x3_))-(x1_-x3_)*(y4_-y3_))/d;
                s = (((y1_-y3_)*(x2_-x1_))-(x1_-x3_)*(y2_-y1_))/d;
                if (r >=0 && r <= 1)
                {
                    if (s >= 0 && s <= 1)
                    {
                        theResult = true;
                        
                    }
                }
            }
            return theResult;
        }
    }
}