//Constructs the document and places it in the provided state public NuGenDocument(DigitizeState state) { listeners = new List <NuGenImageListener>(); pointSets = new NuGenPointSetCollection(); segments = new NuGenSegmentCollection(); transform = new NuGenScreenTranslate(this); gridDisplay = new List <GridlineScreen>(); digitizeState = state; matchSet = new NuGenMatchSet(pointMatchSettings); //load all of the settings NuGenDefaultSettings rSettings = NuGenDefaultSettings.GetInstance(); coordSettings = rSettings.CoordSettings; exportSettings = rSettings.ExportSettings; segmentSettings = rSettings.SegmentSettings; pointMatchSettings = rSettings.PointMatchSettings; gridRemovalSettings = rSettings.GridRemovalSettings; gridDisplaySettings.initialized = false; gridDisplaySettings.gridSetX = rSettings.GridDisplayGridSetX; gridDisplaySettings.gridSetY = rSettings.GridDisplayGridSetY; discretizeSettings = rSettings.DiscretizeSettings; backgroundSelection = rSettings.BackgroundSelection; }
public SegmentsDialog(SegmentSettings settings) { this.settings = settings; InitializeComponent(); InitializeDefaults(); this.MaximumSize = Size; }
public List <NuGenPoint> FillPoints(SegmentSettings seg) { if (seg.fillCorners) { return(FillPointsFillingCorners(seg)); } else { return(FillPointsWithoutFillingCorners(seg)); } }
List <NuGenPoint> FillPoints(SegmentSettings seg) { List <NuGenPoint> list = new List <NuGenPoint>(); foreach (NuGenSegment segment in segments) { list.AddRange(segment.FillPoints(seg)); } return(list); }
List <NuGenPoint> FillPointsFillingCorners(SegmentSettings seg) { List <NuGenPoint> list = new List <NuGenPoint>(); if (lines.Count > 0) { double xLast = lines[0].StartPoint.X; double yLast = lines[0].StartPoint.Y; double x, y; // variables for createAcceptablePoint double xPrev = lines[0].StartPoint.X; double yPrev = lines[0].StartPoint.Y; bool firstPointOfLineSegment; foreach (SegmentLine line in lines) { firstPointOfLineSegment = true; double xNext = line.EndPoint.X; double yNext = line.EndPoint.Y; //good ol pythagorus.. or however you spell it double segmentLength = Math.Sqrt((xNext - xLast) * (xNext - xLast) + (yNext - yLast) * (yNext - yLast)); double distanceLeft = segmentLength; double s = 0.0; do { //coordinates of new point x = (1.0 - s) * xLast + s * xNext; y = (1.0 - s) * yLast + s * yNext; CreateAcceptablePoint(ref firstPointOfLineSegment, list, ref xPrev, ref yPrev, x, y); distanceLeft -= seg.pointSeparation; s += seg.pointSeparation / segmentLength; } while (distanceLeft >= seg.pointSeparation); xLast = xNext; yLast = yNext; } firstPointOfLineSegment = true; CreateAcceptablePoint(ref firstPointOfLineSegment, list, ref xPrev, ref yPrev, xLast, yLast); } return(list); }
public void MakeSegments(Image imageProcessed, SegmentSettings seg) { segments.Clear(); // for each new column of pixels, loop through the runs. a run is defined as // one or more colored pixels that are all touching, with one uncolored pixel or the // image boundary at each end of the set. for each set in the current column, count // the number of runs it touches in the adjacent (left and right) columns. here is // the pseudocode: // if ((L > 1) || (R > 1)) // "this run is at a branch point so ignore the set" // else // if (L == 0) // "this run is the start of a new segment" // else // "this run is appended to the segment on the left int width = imageProcessed.Width; int height = imageProcessed.Height; bool[] lastBool = new bool [height]; bool[] currBool = new bool [height]; bool[] nextBool = new bool [height]; NuGenSegment[] lastSegment = new NuGenSegment [height]; NuGenSegment[] currSegment = new NuGenSegment [height]; Bitmap b = new Bitmap(imageProcessed); BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadOnly, b.PixelFormat); LoadBool(lastBool, bmData, -1); LoadBool(currBool, bmData, 0); LoadBool(nextBool, bmData, 1); LoadSegment(lastSegment, height); for (int x = 0; x < width; x++) { MatchRunsToSegments(x, height, lastBool, lastSegment, currBool, currSegment, nextBool, seg); // get ready for next column ScrollBool(lastBool, currBool, height); ScrollBool(currBool, nextBool, height); if (x + 1 < width) { LoadBool(nextBool, bmData, x + 1); } ScrollSegment(lastSegment, currSegment, height); } b.UnlockBits(bmData); }
public void AppendColumn(int x, int y, SegmentSettings seg) { SegmentLine line = new SegmentLine(this); line.StartPoint = new Point(x - 1, yLast); line.EndPoint = new Point(x, y); // do not show this line or its segment. this is handled later lines.Add(line); // update total length using distance formula length += Math.Sqrt((1.0) * (1.0) + (y - yLast) * (y - yLast)); yLast = y; }
List <NuGenPoint> FillPointsWithoutFillingCorners(SegmentSettings seg) { List <NuGenPoint> list = new List <NuGenPoint>(); if (lines.Count > 0) { double xLast = lines[0].StartPoint.X; double yLast = lines[0].StartPoint.Y; double x, xNext; double y, yNext; double distanceCompleted = 0.0; // variables for createAcceptablePoint bool firstPoint = true; double xPrev = lines[0].StartPoint.X; double yPrev = lines[0].StartPoint.Y; foreach (SegmentLine line in lines) { xNext = line.EndPoint.X; yNext = line.EndPoint.Y; // distance formula double segmentLength = Math.Sqrt((xNext - xLast) * (xNext - xLast) + (yNext - yLast) * (yNext - yLast)); if (segmentLength > 0.0) { while (distanceCompleted <= segmentLength) { double s = distanceCompleted / segmentLength; x = (1.0 - s) * xLast + s * xNext; y = (1.0 - s) * yLast + s * yNext; CreateAcceptablePoint(ref firstPoint, list, ref xPrev, ref yPrev, x, y); distanceCompleted += seg.pointSeparation; } distanceCompleted -= segmentLength; } xLast = xNext; yLast = yNext; } } return(list); }
void FinishRun(bool[] lastBool, bool[] nextBool, NuGenSegment[] lastSegment, NuGenSegment[] currSegment, int x, int yStart, int yStop, int height, SegmentSettings set) { // when looking at adjacent columns, include pixels that touch diagonally since // those may also diagonally touch nearby runs in the same column (which would indicate // a branch) // count runs that touch on the left if (AdjacentRuns(lastBool, yStart, yStop, height) > 1) { return; } // count runs that touch on the right if (AdjacentRuns(nextBool, yStart, yStop, height) > 1) { return; } NuGenSegment seg; if (AdjacentSegments(lastSegment, yStart, yStop, height) == 0) { // this is the start of a new segment seg = new NuGenSegment((int)(0.5 + (yStart + yStop) / 2.0)); segments.Add(seg); } else { // this is the continuation of an existing segment seg = AdjacentSegment(lastSegment, yStart, yStop, height); seg.AppendColumn(x, (int)(0.5 + (yStart + yStop) / 2.0), set); } for (int y = yStart; y <= yStop; y++) { currSegment [y] = seg; } }
void RemoveUnneededLines(NuGenSegment[] lastSegment, NuGenSegment[] currSegment, int height, SegmentSettings seg) { NuGenSegment segLast = null; for (int yLast = 0; yLast < height; yLast++) { if ((lastSegment[yLast] != null) && (lastSegment [yLast] != segLast)) { segLast = lastSegment [yLast]; // if the segment is found in the current column then it is still in work so postpone processing bool found = false; for (int yCur = 0; yCur < height; yCur++) { if (segLast == currSegment [yCur]) { found = true; break; } } if (!found) { if (segLast.Length < (seg.minPoints - 1) * seg.pointSeparation) { segments.Remove(segLast); // autoDelete is on } else { // keep segment, but try to fold lines segLast.RemoveUnneededLines(); } } } } }
void MatchRunsToSegments(int x, int height, bool[] lastBool, NuGenSegment[] lastSegment, bool[] currBool, NuGenSegment[] currSegment, bool[] nextBool, SegmentSettings seg) { LoadSegment(currSegment, height); int yStart = 0; bool inRun = false; for (int y = 0; y < height; y++) { if (!inRun && currBool [y]) { inRun = true; yStart = y; } if ((y + 1 >= height) || !currBool [y + 1]) { if (inRun) { FinishRun(lastBool, nextBool, lastSegment, currSegment, x, yStart, y, height, seg); } inRun = false; } } RemoveUnneededLines(lastSegment, currSegment, height, seg); }