private void TraceHBottomLines(List <BorderPoint> points, HashSet <BorderLine> result) { int index = 0, x1, x2, y, start; while (points.Count > index) { start = index; y = points[index].mY; x1 = points[index].mX; x2 = x1; do { x1 = x2; index++; if (points.Count > index) { x2 = points[index].mX; } else { break; } } while ((x2 - x1 == 1) && (points[index].mY == y) && (index < points.Count)); index--; BorderLine line = new BorderLine(new Point(points[start].mX, points[start].mY + 1), new Point(points[index].mX + 1, points[index].mY + 1)); Thread.MemoryBarrier(); result.Add(line); index++; } }
private void TraceVRightLines(List <BorderPoint> points, HashSet <BorderLine> result) { int index = 0, y1, y2, x, start; while (points.Count > index) { start = index; x = points[index].mX; y1 = points[index].mY; y2 = y1; do { y1 = y2; index++; if (points.Count > index) { y2 = points[index].mY; } else { break; } } while ((y2 - y1 == 1) && (points[index].mX == x) && (index < points.Count)); index--; BorderLine line = new BorderLine(new Point(points[start].mX + 1, points[start].mY), new Point(points[index].mX + 1, points[index].mY + 1)); Thread.MemoryBarrier(); result.Add(line); index++; } }
/// <summary> /// Assemble the give collection of <see cref="BorderLine"/> into a <see cref="GraphicsPath"/>. /// </summary> /// <param name="lines">The collection of <see cref="BorderLine"/> that define one or more closed shapes.</param> /// <returns><see cref="GraphicsPath"/> made up of one or more closed shapes.</returns> private GraphicsPath BuildPath(HashSet <BorderLine> lines) { lines = new HashSet <BorderLine>(lines); GraphicsPath path = new GraphicsPath(); int x; BorderLine points = lines.First(); path.StartFigure(); path.AddLine(points.mStart, points.mEnd); lines.Remove(points); while (lines.Count > 0) { x = lines.Count; foreach (BorderLine line in lines.Where(line => path.GetLastPoint() == (PointF)line.mStart)) { path.AddLine(line.mStart, line.mEnd); lines.Remove(line); break; } if (x == lines.Count) { path.StartFigure(); points = lines.First(); path.AddLine(points.mStart, points.mEnd); lines.Remove(points); } } return(path); }
/// <summary> /// Update the <paramref name="provinceLines"/> collection so that it contains <see cref="BorderLine"/> present in it /// or present in the outline of a shape define by <paramref name="complementingProvince"/> color, but not in both. /// </summary> /// <remarks>If <see cref="BorderLine"/> present in both collection only partially overlap, the updated <paramref name="provinceLines"/> will /// contain the segments resulted after a <see cref="BorderLine.Exclude(BorderLine)"/> operation.</remarks> /// <param name="provinceLines">The collection to be updated.</param> /// <param name="complementingProvince">The color of the shape whose outline will be used in the complement operation.</param> public void ComplementVirtualProvince(ref HashSet <BorderLine> provinceLines, Color complementingProvince) { HashSet <BorderLine> linesToRemove = new HashSet <BorderLine>(3); HashSet <BorderLine> linesFound = new HashSet <BorderLine>(3); foreach (BorderLine lineToAddImmutable in this._mProvincesLines[complementingProvince]) { BorderLine lineToAdd = lineToAddImmutable; bool found = false; linesToRemove.Clear(); linesFound.Clear(); BorderLine foundLine = BorderLine.EmptyLine; foreach (BorderLine lineExisting in provinceLines) { //Search for any overlapping if (lineExisting.IsOverlapping(lineToAdd)) { found = true; linesFound.Add(lineExisting); } //Search if two lines are in fact a bigger line if (lineExisting.IsContinuous(lineToAdd)) { linesToRemove.Add(lineExisting); lineToAdd = lineToAdd.Concatenate(lineExisting); found = true; } } if (found == false) { provinceLines.Add(lineToAdd); } else { // Remove lines marked for removal provinceLines.ExceptWith(linesToRemove); // If found to overlap with only one line, it's easy then if (linesFound.Count == 1) { provinceLines.ExceptWith(linesFound); BorderLine[] lines = lineToAdd.Exclude(linesFound.First()); if (lines != null) { provinceLines.UnionWith(lines); } } else if (linesFound.Count > 1) { foreach (BorderLine lineFound in linesFound) { lineToAdd = lineFound.Exclude(lineToAdd)[0]; } provinceLines.ExceptWith(linesFound); provinceLines.Add(lineToAdd); } else { provinceLines.Add(lineToAdd); } } } }