public void ExtendedNormalOfPoint(PointD mouseLocation, out PointD normalVector, out PointD nearestPoint, out double radius)
        {
            int n1;
            int n2;
            float r1;
            float r2;

            if (m_pointsInPath == null)
            {
                normalVector = PointD.Empty;
                nearestPoint = PointD.Empty;
                radius = 0;
                return;
            }

            PointF[] array = m_pointsInPath;

            NearestPoint(array, (PointF)mouseLocation, out n1, out n2, out r1, out r2);
            PointD tangent = new PointD(array[n1].X - array[n2].X, array[n1].Y - array[n2].Y);
            tangent = tangent / tangent.Magnitude();
            normalVector = PointD.Orthogonal(tangent);

            PointD vToPoint = mouseLocation - (PointD)array[n1];
            radius = PointD.DotProduct(normalVector, vToPoint);
            PointD orthVector = radius * normalVector;
            nearestPoint = mouseLocation - orthVector;

            // System.Diagnostics.Debug.WriteLine(String.Format("{0} {1}", array[n1], nearestPoint));

            //// TODO: to optimize here, instead of averaging two nearest points,
            //// we find the orthogonal vector and project to the mouseLocation
            //// onto the line to find nearest point.

            //nearestPoint = new PointD((array[n1].X + array[n2].X) / 2.0, (array[n1].Y + array[n2].Y) / 2.0);
            //normalVector = PointD.Orthogonal(tangent);
            //radius = (r1 + r2) / 2.0;
        }
        /*
        gc.DrawLine(Pens.Green, new Point(100, 100), new Point(300, 200));
        gc.DrawEllipse(Pens.Green, (float)mappedToLine.X, (float)mappedToLine.Y, 4f, 4f);
        gc.DrawLine(Pens.Green, 100f, 100f, 100f + (float)normalComponent.X, 100f + (float)normalComponent.Y);
         */
        protected override void SecondCache(Render.IDrawVisitor drawMethods)
        {
            if (m_Param.Path.PointCount == 0)
                return;

            PointF[] array = ((Tools.Model.VectorPath)m_Param.Path).InternalPath.PathPoints;

            // calculate number of lines to show for feedback
            int spacing = (int)drawMethods.Spacing(m_Param.C);
            int numLines = (int)m_Param.PathThickness / spacing;

            // build a number of trace lines
            m_traceLines = new List<PointF>[numLines];
            for (int j = 0; j < numLines; j++)
                m_traceLines[j] = new List<PointF>(array.Length);

            // render all the points
            for (int i = 1; i < array.Length; i += 2)
            {
                PointD tangent = new PointD(array[i].X - array[i - 1].X, array[i].Y - array[i - 1].Y);
                tangent = tangent / tangent.Magnitude();
                PointD normalVector = PointD.Orthogonal(tangent);

                PointD pointOnLine = new PointD((array[i].X + array[i - 1].X) / 2.0, (array[i].Y + array[i - 1].Y) / 2.0);

                for (int k = 0; k < numLines; k++)
                {
                    PointD testPt = pointOnLine + normalVector * spacing * (k - numLines / 2);
                    m_traceLines[k].Add((PointF)testPt);
                }

                //PointD testNormal1 = (testPt1 - pointOnLine);
                //testNormal1 = testNormal1 / testNormal1.Magnitude();

                //PointD testNormal2 = (testPt2 - pointOnLine);
                //testNormal2 = testNormal2 / testNormal2.Magnitude();

                //PointD scaledVector1 = testNormal1 * (GetScalar() * 7 * m_Param.C / Math.Pow((m_Param.PtRadius / 2.0) + 10, 0.5));
                //PointD scaledVector2 = testNormal2 * (GetScalar() * 7 * m_Param.C / Math.Pow((m_Param.PtRadius / 2.0) + 10, 0.5));

                //drawMethods.DrawArrow(gc, r, testPt1, scaledVector1 * Render.DrawHelper.SPEED_AMPLIFIER);
                //drawMethods.DrawArrow(gc, r, testPt2, scaledVector2 * Render.DrawHelper.SPEED_AMPLIFIER);
            }
        }