Browse Source

Fixed Several Bugs, Deletion Feature so far complete.

- Fixed Bugs causing crashes when drawing outside of the canvas
- Fixed Bug where single lines with one point could not be drawn
- Fixed Bug where dots input using drawing tables would not be
recognized
- Added Line intersection detection between ticks for the deletion
feature
- Added "Brush Size" for the deletion feature, to make deletion more
easy to use.
Martin Edlund 5 years ago
parent
commit
0d90272bd5

+ 2 - 1
SketchAssistant/SketchAssistant/Form1.Designer.cs

@@ -82,6 +82,7 @@ namespace SketchAssistant
             this.pictureBoxRight.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
             this.pictureBoxRight.TabIndex = 6;
             this.pictureBoxRight.TabStop = false;
+            this.pictureBoxRight.Click += new System.EventHandler(this.pictureBoxRight_Click);
             this.pictureBoxRight.MouseDown += new System.Windows.Forms.MouseEventHandler(this.pictureBoxRight_MouseDown);
             this.pictureBoxRight.MouseMove += new System.Windows.Forms.MouseEventHandler(this.pictureBoxRight_MouseMove);
             this.pictureBoxRight.MouseUp += new System.Windows.Forms.MouseEventHandler(this.pictureBoxRight_MouseUp);
@@ -184,7 +185,7 @@ namespace SketchAssistant
             // 
             // mouseTimer
             // 
-            this.mouseTimer.Interval = 2;
+            this.mouseTimer.Interval = 1;
             this.mouseTimer.Tick += new System.EventHandler(this.mouseTimer_Tick);
             // 
             // Form1

+ 64 - 22
SketchAssistant/SketchAssistant/Form1.cs

@@ -50,15 +50,15 @@ namespace SketchAssistant
         Point currentCursorPosition;
         //The Previous Cursor Position in the right picture box
         Point previousCursorPosition;
+        //Queue for the cursorPositions
+        Queue<Point> cursorPositions = new Queue<Point>();
         //The graphic representation of the right image
         Graphics graph = null;
         //Deletion Matrixes for checking postions of lines in the image
         bool[,] isFilledMatrix;
-        List<int>[,] linesMatrix;
+        HashSet<int>[,] linesMatrix;
         //Size of deletion area
-        int deletionSize = 10;
-        //List with all cursorPositions
-        List<Point> cursorPositions = new List<Point>();
+        uint deletionSize = 2;
 
         /******************************************/
         /*** FORM SPECIFIC FUNCTIONS START HERE ***/
@@ -138,11 +138,24 @@ namespace SketchAssistant
             }
         }
 
+        //when the picture box is clicked, add a point to the current line. Occurs f.ex. when using drawing tablets
+        private void pictureBoxRight_Click(object sender, EventArgs e)
+        {
+            if (currentState.Equals(ProgramState.Draw))
+            {
+                List<Point> singlePoint = new List<Point> { currentCursorPosition };
+                Line singlePointLine = new Line(singlePoint, lineList.Count);
+                singlePointLine.PopulateMatrixes(isFilledMatrix, linesMatrix);
+                singlePointLine.DrawLine(graph);
+                pictureBoxRight.Image = rightImage;
+            }
+        }
+
         //Lift left mouse button to stop drawing and add a new Line.
         private void pictureBoxRight_MouseUp(object sender, MouseEventArgs e)
         {
             mousePressed = false;
-            if (currentState.Equals(ProgramState.Draw))
+            if (currentState.Equals(ProgramState.Draw) && currentLine.Count > 0)
             {
                 Line newLine = new Line(currentLine, lineList.Count);
                 lineList.Add(new Tuple<bool, Line>(true, newLine));
@@ -158,12 +171,14 @@ namespace SketchAssistant
             DrawEmptyCanvas();
             //The following lines cannot be in DrawEmptyCanvas()
             isFilledMatrix = new bool[rightImage.Width, rightImage.Height];
-            linesMatrix = new List<int>[rightImage.Width, rightImage.Height];
+            linesMatrix = new HashSet<int>[rightImage.Width, rightImage.Height];
         }
 
         //add a Point on every tick to the Drawpath
         private void mouseTimer_Tick(object sender, EventArgs e)
         {
+            cursorPositions.Enqueue(currentCursorPosition);
+            previousCursorPosition = cursorPositions.Dequeue();
 
             if (currentState.Equals(ProgramState.Draw) && mousePressed)
             {
@@ -174,26 +189,19 @@ namespace SketchAssistant
             }
             if (currentState.Equals(ProgramState.Delete) && mousePressed)
             {
-
-                if (currentCursorPosition.X < rightImage.Width - 1 && currentCursorPosition.Y < rightImage.Height- 1
-                    && currentCursorPosition.X >= 0 && currentCursorPosition.Y >= 0)
+                List<Point> uncheckedPoints = Line.BresenhamLineAlgorithm(previousCursorPosition, currentCursorPosition);
+                foreach (Point currPoint in uncheckedPoints)
                 {
-                    cursorPositions.Add(currentCursorPosition);
-                    if (cursorPositions.Count > 1)
+                    HashSet<int> linesToDelete = CheckDeletionMatrixesAroundPoint(currPoint, deletionSize);
+                    if (linesToDelete.Count > 0)
                     {
-                        previousCursorPosition = cursorPositions[cursorPositions.Count - 2];
-
-                        if (isFilledMatrix[currentCursorPosition.X, currentCursorPosition.Y])
+                        foreach (int lineID in linesToDelete)
                         {
-                            foreach (int lineid in linesMatrix[currentCursorPosition.X, currentCursorPosition.Y])
-                            {
-                                lineList[lineid] = new Tuple<bool, Line>(false, lineList[lineid].Item2);
-                            }
-                            RepopulateDeletionMatrixes();
-                            RedrawRightImage();
+                            lineList[lineID] = new Tuple<bool, Line>(false, lineList[lineID].Item2);
                         }
+                        RepopulateDeletionMatrixes();
+                        RedrawRightImage();
                     }
-
                 }
             }
         }
@@ -328,7 +336,7 @@ namespace SketchAssistant
             if(rightImage != null)
             {
                 isFilledMatrix = new bool[rightImage.Width,rightImage.Height];
-                linesMatrix = new List<int>[rightImage.Width, rightImage.Height];
+                linesMatrix = new HashSet<int>[rightImage.Width, rightImage.Height];
                 foreach(Tuple<bool,Line> lineTuple in lineList)
                 {
                     if (lineTuple.Item1)
@@ -338,5 +346,39 @@ namespace SketchAssistant
                 }
             }
         }
+
+        /// <summary>
+        /// A function that checks the deletion matrixes at a certain point 
+        /// and returns all Line ids at that point and in a square around it in a certain range.
+        /// </summary>
+        /// <param name="p">The point around which to check.</param>
+        /// <param name="range">The range around the point. If range is 0, only the point is checked.</param>
+        /// <returns>A List of all lines.</returns>
+        private HashSet<int> CheckDeletionMatrixesAroundPoint(Point p, uint range)
+        {
+            HashSet<int> returnSet = new HashSet<int>();
+
+            if (p.X >= 0 && p.Y >= 0 && p.X < rightImage.Width && p.Y < rightImage.Height)
+            {
+                if (isFilledMatrix[p.X, p.Y])
+                {
+                    returnSet.UnionWith(linesMatrix[p.X, p.Y]);
+                }
+            }
+            for (int x_mod = (int)range*(-1); x_mod < range; x_mod++)
+            {
+                for (int y_mod = (int)range * (-1); y_mod < range; y_mod++)
+                {
+                    if (p.X + x_mod >= 0 && p.Y + y_mod >= 0 && p.X + x_mod < rightImage.Width && p.Y + y_mod < rightImage.Height)
+                    {
+                        if (isFilledMatrix[p.X + x_mod, p.Y + y_mod])
+                        {
+                            returnSet.UnionWith(linesMatrix[p.X + x_mod, p.Y + y_mod]);
+                        }
+                    }
+                }
+            }
+            return returnSet;
+        }
     }
 }

+ 33 - 31
SketchAssistant/SketchAssistant/Line.cs

@@ -66,6 +66,8 @@ namespace SketchAssistant
             {
                 canvas.DrawLine(thePen, linePoints[i], linePoints[i + 1]);
             }
+            //If there is only one point
+            if(linePoints.Count == 1){ canvas.FillRectangle(Brushes.Black, linePoints[0].X, linePoints[0].Y, 1, 1); }
             return canvas;
         }
 
@@ -74,25 +76,22 @@ namespace SketchAssistant
         /// </summary>
         /// <param name="boolMatrix">The Matrix of booleans, in which is saved wether there is a line at this position.</param>
         /// <param name="listMatrix">The Matrix of Lists of integers, in which is saved which lines are at this position</param>
-        public void PopulateMatrixes(bool[,] boolMatrix, List<int>[,] listMatrix)
+        public void PopulateMatrixes(bool[,] boolMatrix, HashSet<int>[,] listMatrix)
         {
             if(!isTemporary)
             {
                 foreach (Point currPoint in linePoints)
                 {
-                    try
+                    if (currPoint.X >= 0 && currPoint.Y >= 0 && 
+                        currPoint.X < boolMatrix.GetLength(0) && currPoint.Y < boolMatrix.GetLength(1))
                     {
                         boolMatrix[currPoint.X, currPoint.Y] = true;
                         if (listMatrix[currPoint.X, currPoint.Y] == null)
                         {
-                            listMatrix[currPoint.X, currPoint.Y] = new List<int>();
+                            listMatrix[currPoint.X, currPoint.Y] = new HashSet<int>();
                         }
                         listMatrix[currPoint.X, currPoint.Y].Add(identifier);
                     }
-                    catch (IndexOutOfRangeException e)
-                    {
-
-                    }
                 }
             }
         }
@@ -102,36 +101,39 @@ namespace SketchAssistant
         /// </summary>
         private void CleanPoints()
         {
-            List<Point> newList = new List<Point>();
-            List<Point> tempList = new List<Point>();
-            //Since Point is non-nullable, we must ensure the nullPoints, 
-            //which we remove can not possibly be points of the original given line.
-            int nullValue = linePoints[0].X + 1;
-            //Fill the gaps between points
-            for (int i = 0; i < linePoints.Count - 1; i++)
+            if (linePoints.Count > 1)
             {
-                nullValue += linePoints[i + 1].X;
-                List<Point> partialList = BresenhamLineAlgorithm(linePoints[i], linePoints[i + 1]);
-                tempList.AddRange(partialList);
-            }
-            Point nullPoint = new Point(nullValue, 0);
-            //Set duplicate points to the null point
-            for (int i = 1; i < tempList.Count; i++)
-            {
-                if ((tempList[i].X == tempList[i - 1].X) && (tempList[i].Y == tempList[i - 1].Y))
+                List<Point> newList = new List<Point>();
+                List<Point> tempList = new List<Point>();
+                //Since Point is non-nullable, we must ensure the nullPoints, 
+                //which we remove can not possibly be points of the original given line.
+                int nullValue = linePoints[0].X + 1;
+                //Fill the gaps between points
+                for (int i = 0; i < linePoints.Count - 1; i++)
                 {
-                    tempList[i - 1] = nullPoint;
+                    nullValue += linePoints[i + 1].X;
+                    List<Point> partialList = BresenhamLineAlgorithm(linePoints[i], linePoints[i + 1]);
+                    tempList.AddRange(partialList);
                 }
-            }
-            //remove the null points
-            foreach(Point tempPoint in tempList)
-            {
-                if (tempPoint.X != nullValue)
+                Point nullPoint = new Point(nullValue, 0);
+                //Set duplicate points to the null point
+                for (int i = 1; i < tempList.Count; i++)
                 {
-                    newList.Add(tempPoint);
+                    if ((tempList[i].X == tempList[i - 1].X) && (tempList[i].Y == tempList[i - 1].Y))
+                    {
+                        tempList[i - 1] = nullPoint;
+                    }
+                }
+                //remove the null points
+                foreach (Point tempPoint in tempList)
+                {
+                    if (tempPoint.X != nullValue)
+                    {
+                        newList.Add(tempPoint);
+                    }
                 }
+                linePoints = new List<Point>(newList);
             }
-            linePoints = new List<Point>(newList);
         }
 
         /// <summary>

+ 5 - 5
SketchAssistant/SketchAssistantTestSuite/UnitTest1.cs

@@ -125,7 +125,7 @@ namespace SketchAssistantTestSuite
             bool[,] testBoolMatrix = new bool[5, 5];
             List<int>[,] testLineMatrix = new List<int>[5, 5];
             bool[,] resultBoolMatrix = new bool[5, 5];
-            List<int>[,] resultLineMatrix = new List<int>[5, 5];
+            HashSet<int>[,] resultLineMatrix = new HashSet<int>[5, 5];
             Line testLine = new Line(thePoints);
             testLine.PopulateMatrixes(resultBoolMatrix, resultLineMatrix);
             for (int i = 0; i < 5; i++)
@@ -146,16 +146,16 @@ namespace SketchAssistantTestSuite
             thePoints.Add(new Point(1, 1));
             thePoints.Add(new Point(3, 3));
             bool[,] testBoolMatrix = new bool[5, 5];
-            List<int>[,] testLineMatrix = new List<int>[5, 5];
+            HashSet<int>[,] testLineMatrix = new HashSet<int>[5, 5];
             for (int i = 1; i <= 3; i++)
             {
                 testBoolMatrix[i, i] = true;
-                List<int> temp = new List<int>();
+                HashSet<int> temp = new HashSet<int>();
                 temp.Add(5);
                 testLineMatrix[i, i] = temp;
             }
             bool[,] resultBoolMatrix = new bool[5, 5];
-            List<int>[,] resultLineMatrix = new List<int>[5, 5];
+            HashSet<int>[,] resultLineMatrix = new HashSet<int>[5, 5];
             Line testLine = new Line(thePoints, 5);
             testLine.PopulateMatrixes(resultBoolMatrix, resultLineMatrix);
             for (int i = 0; i < 5; i++)
@@ -167,7 +167,7 @@ namespace SketchAssistantTestSuite
                     {
                         for (int k = 0; k < resultLineMatrix[i, j].Count; k++)
                         {
-                            Assert.AreEqual(testLineMatrix[i, j][k], resultLineMatrix[i, j][k]);
+                            Assert.AreEqual(true, testLineMatrix[i, j].SetEquals(resultLineMatrix[i, j]));
                         }
                     }
                 }