// Checks if there are two neighboring points in a pair of silhouette pieces, and returns them public static LinkedListNode <ContourPixel>[] NeighboringStartOrEndPoints(SilhouettePiece sp1, SilhouettePiece sp2, int threshold) { LinkedListNode <ContourPixel>[] neighbors = new LinkedListNode <ContourPixel> [2]; LinkedListNode <ContourPixel> startPoint1 = sp1.Points.First; LinkedListNode <ContourPixel> endPoint1 = sp1.Points.Last; LinkedListNode <ContourPixel> startPoint2 = sp2.Points.First; LinkedListNode <ContourPixel> endPoint2 = sp2.Points.Last; if (AreNeighbors(startPoint1.Value, startPoint2.Value, threshold)) { neighbors[0] = startPoint1; neighbors[1] = startPoint2; } else if (AreNeighbors(startPoint1.Value, endPoint2.Value, threshold)) { neighbors[0] = startPoint1; neighbors[1] = endPoint2; } else if (AreNeighbors(endPoint1.Value, startPoint2.Value, threshold)) { neighbors[0] = endPoint1; neighbors[1] = startPoint2; } else if (AreNeighbors(endPoint1.Value, endPoint2.Value, threshold)) { neighbors[0] = endPoint1; neighbors[1] = endPoint2; } return(neighbors); }
// Merges all pieces in a silhouette that have neighboring end points with each other public void MergeSilhouettePieces(Silhouette silhouette) { int threshold = SilhouetteMergingThreshold; // Maximum distance between two piece endpoints for (int i = 0; i < silhouette.Pieces.Count - 1; i++) { for (int j = i + 1; j < silhouette.Pieces.Count; j++) { SilhouettePiece sp1 = silhouette.Pieces[i]; SilhouettePiece sp2 = silhouette.Pieces[j]; LinkedListNode <ContourPixel>[] neighbors = VectorUtils.NeighboringStartOrEndPoints(sp1, sp2, threshold); if (neighbors[1] != null) { //Debug.Log("Merging..."); silhouette.Pieces.Remove(sp1); silhouette.Pieces.Remove(sp2); SilhouettePiece mergedPiece = new SilhouettePiece(); LinkedListNode <ContourPixel> currentNode; LinkedListNode <ContourPixel> nodeCopy; if (neighbors[0].Next == null) { //Debug.Log("First piece 1"); currentNode = sp1.Points.First; while (currentNode.Value != neighbors[0].Value) // Add all points up to first connecting point { nodeCopy = new LinkedListNode <ContourPixel>(currentNode.Value); mergedPiece.Points.AddLast(nodeCopy); currentNode = currentNode.Next; } nodeCopy = new LinkedListNode <ContourPixel>(neighbors[0].Value); mergedPiece.Points.AddLast(nodeCopy); // Add first connecting point currentNode = currentNode.Next; nodeCopy = new LinkedListNode <ContourPixel>(neighbors[1].Value); mergedPiece.Points.AddLast(nodeCopy); // Add second connecting point if (neighbors[1].Next == null) { //Debug.Log("Second piece 1"); currentNode = sp2.Points.Last; while (currentNode != null) // Add the rest of the points in the other piece { nodeCopy = new LinkedListNode <ContourPixel>(currentNode.Value); mergedPiece.Points.AddLast(nodeCopy); currentNode = currentNode.Previous; } } else // neighbors[1].Previous == null { //Debug.Log("Second piece 1"); currentNode = sp2.Points.First; while (currentNode != null) // Add the rest of the points in the other piece { nodeCopy = new LinkedListNode <ContourPixel>(currentNode.Value); mergedPiece.Points.AddLast(nodeCopy); currentNode = currentNode.Next; } } } else // (n.previous == null) { //Debug.Log("First piece 2"); currentNode = sp1.Points.Last; while (currentNode.Value != neighbors[0].Value) // Add all points up to first connecting point { nodeCopy = new LinkedListNode <ContourPixel>(currentNode.Value); mergedPiece.Points.AddLast(nodeCopy); currentNode = currentNode.Previous; } nodeCopy = new LinkedListNode <ContourPixel>(neighbors[0].Value); mergedPiece.Points.AddLast(nodeCopy); // Add first connecting point currentNode = currentNode.Previous; nodeCopy = new LinkedListNode <ContourPixel>(neighbors[1].Value); mergedPiece.Points.AddLast(nodeCopy); // Add second connecting point if (neighbors[1].Next == null) { //Debug.Log("Second piece 2"); currentNode = sp2.Points.Last; while (currentNode != null) // Add the rest of the points in the other piece { nodeCopy = new LinkedListNode <ContourPixel>(currentNode.Value); mergedPiece.Points.AddLast(nodeCopy); currentNode = currentNode.Previous; } } else // neighbors[1].Previous == null { //Debug.Log("Second piece 2"); currentNode = sp2.Points.First; while (currentNode != null) // Add the rest of the points in the other piece { nodeCopy = new LinkedListNode <ContourPixel>(currentNode.Value); mergedPiece.Points.AddLast(nodeCopy); currentNode = currentNode.Next; } } } //Debug.Log("Added"); silhouette.Pieces.Add(mergedPiece); } } } }
// Takes a contour and draws its silhouette public Silhouette DrawSilhouette(Contour contour) { Silhouette silhouette = new Silhouette(contour.Color); int pixelCount = 0; ContourPixel dummyPixel = new ContourPixel { IsDummy = true }; int sX, sY, nX, nY; ContourPixel startPixel = FindNextStartPixel(contour, dummyPixel); ContourPixel nextPixel = startPixel; bool started; //try //{ while (startPixel != null && pixelCount != contour.NumberOfPixels) { started = false; // Add the first pixel of the new silhouette piece SilhouettePiece silhouettePiece = new SilhouettePiece(); silhouettePiece.Points.AddFirst(startPixel); sX = startPixel.XCoord; sY = startPixel.YCoord; nX = startPixel.XCoord; nY = startPixel.YCoord; // Check if outside window //--------------------------------------------------------------------------------------------- if (VectorUtils.AdjustIteration(contour, nX, nY) == "go-left-or-right") { //Debug.Log("Over eller under"); if ((contour.Pixels[nX - 1, nY] != null) && !contour.Pixels[nX - 1, nY].Visited) { nX = nX - 1; } else if ((contour.Pixels[nX + 1, nY] != null) && !contour.Pixels[nX + 1, nY].Visited) { nX = nX + 1; } } else if (VectorUtils.AdjustIteration(contour, nX, nY) == "go-up-or-right") { //Debug.Log("Venstre"); if ((contour.Pixels[nX, nY + 1] != null) && !contour.Pixels[nX, nY + 1].Visited) { nY = nY + 1; } else if ((contour.Pixels[nX + 1, nY] != null) && !contour.Pixels[nX + 1, nY].Visited) { nX = nX + 1; } } else if (VectorUtils.AdjustIteration(contour, nX, nY) == "go-up-or-left") { //Debug.Log("Høyre"); if ((contour.Pixels[nX, nY + 1] != null) && !contour.Pixels[nX, nY + 1].Visited) { nY = nY + 1; } else if ((contour.Pixels[nX - 1, nY] != null) && !contour.Pixels[nX - 1, nY].Visited) { nX = nX - 1; } } //--------------------------------------------------------------------------------------------- while (VectorUtils.MoreToDraw(contour, nX, nY) && (!(nX == sX && nY == sY) || !started)) { //previousPixel = nextPixel; nextPixel = StepToNextPixel(contour, nX, nY, nextPixel); nX = nextPixel.XCoord; nY = nextPixel.YCoord; pixelCount++; silhouettePiece.Points.AddLast(nextPixel); started = true; } startPixel = FindNextStartPixel(contour, startPixel); silhouette.Pieces.Add(silhouettePiece); } /*} catch (Exception e) * { * return silhouettes; * }*/ return(silhouette); }