public void FillPolygonTests7() { var dimX = 5; var dimY = 5; var expectedArray = new byte[] { 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, }; var volume2D = new Volume2D <byte>(expectedArray, 5, 5, 1, 1, new Point2D(), new Matrix2()); var extractContour = ExtractContours.PolygonsFilled(volume2D); var output1 = new byte[dimX * dimY]; var polygon = extractContour.First().Points.Select(x => CreatePoint(x.X + 0.00002, x.Y - 0.00001)).ToArray(); FillPolygon.Fill(polygon, output1, dimX, dimY, 0, 0, (byte)1); for (var i = 0; i < output1.Length; i++) { Assert.AreEqual(expectedArray[i], output1[i]); } }
public void GetPointsOnDiagonalLineTests() { var point1 = CreatePoint(0, 0); var point2 = CreatePoint(2, 4); var result1 = FillPolygon.GetPointsOnLine(point1, point2); CompareArrays(result1, new List <Point>() { new Point(0, 0), new Point(0, 1), new Point(1, 2), new Point(1, 3), new Point(2, 4) }); var result2 = FillPolygon.GetPointsOnLine(point2, point1); CompareArrays(result2, new List <Point>() { new Point(0, 0), new Point(0, 1), new Point(1, 2), new Point(1, 3), new Point(2, 4) }); }
public void GetBoundingBoxTest() { var boundingBox = FillPolygon.GetBoundingBox(new[] { CreatePoint(1, 1), CreatePoint(2, 4) }); Assert.AreEqual(3, boundingBox.Height); Assert.AreEqual(1, boundingBox.Width); Assert.AreEqual(1, boundingBox.X); Assert.AreEqual(1, boundingBox.Y); boundingBox = FillPolygon.GetBoundingBox(new[] { CreatePoint(1, 1), CreatePoint(2, 1), CreatePoint(2, 2), CreatePoint(3, 2), CreatePoint(3, 1), CreatePoint(4, 1), CreatePoint(2, 7), }); Assert.AreEqual(6, boundingBox.Height); Assert.AreEqual(3, boundingBox.Width); Assert.AreEqual(1, boundingBox.X); Assert.AreEqual(1, boundingBox.Y); boundingBox = FillPolygon.GetBoundingBox(new[] { CreatePoint(2, 1), CreatePoint(1, 2), CreatePoint(3, 2), }); Assert.AreEqual(1, boundingBox.Height); Assert.AreEqual(2, boundingBox.Width); Assert.AreEqual(1, boundingBox.X); Assert.AreEqual(1, boundingBox.Y); }
public void FloodFillTest2(string filename) { var path = GetTestDataPath(filename); var image = new Bitmap(path); var mask = image.ToByteArray(); Assert.IsTrue(mask.Any(x => x == 0)); Assert.IsTrue(mask.Any(x => x == 1)); Assert.IsTrue(mask.Length == image.Width * image.Height); var actual = new Volume2D <byte>(mask, image.Width, image.Height, 1, 1, new Point2D(), new Matrix2()); var contoursFilled = actual.ContoursFilled(); var expected = actual.CreateSameSize <byte>(); expected.Fill(contoursFilled, (byte)1); var stopwatch = Stopwatch.StartNew(); FillPolygon.FloodFillHoles(actual.Array, expected.DimX, expected.DimY, 0, 0, 1, 0); stopwatch.Stop(); actual.SaveBrushVolumeToPng(@"C:\Temp\Actual.png"); expected.SaveBrushVolumeToPng(@"C:\Temp\Expected.png"); Assert.AreEqual(expected.Array, actual.Array, "Extracting filled contours and filling those should give the same result as flood filling holes."); var contoursWithHoles = actual.ContoursWithHoles(); var filledWithHoles = actual.CreateSameSize <byte>(); filledWithHoles.Fill(contoursWithHoles, (byte)1); Assert.AreEqual(actual.Array, filledWithHoles.Array, "Extracting contours with holes and filling those in should not change the mask"); }
public void TestPointNearLine() { Assert.IsFalse(FillPolygon.PointOnLine(CreatePoint(1.5, 1.5), CreatePoint(1.5, 1.5), CreatePoint(2.0, 2.0), 0.01f)); Assert.IsTrue(FillPolygon.PointOnLine(CreatePoint(1.5, 1.5), CreatePoint(1.5, 1.5), CreatePoint(1.5, 1.5), 0.01f)); Assert.IsTrue(FillPolygon.PointOnLine(CreatePoint(1.5, 1.5), CreatePoint(1.5, 1.5), CreatePoint(1.5001, 1.5001), 0.01f)); // On line to float precision Assert.IsTrue(FillPolygon.PointOnLine(CreatePoint(1, 1), CreatePoint(2, 2), CreatePoint(1.5f, 1.5f), 0.01f)); Assert.IsTrue(FillPolygon.PointOnLine(CreatePoint(2, 2), CreatePoint(1, 1), CreatePoint(1.5f, 1.5f), 0.01f)); // Near line within tolerance Assert.IsTrue(FillPolygon.PointOnLine(CreatePoint(1, 1), CreatePoint(2, 2), CreatePoint(1.50f, 1.55f), 0.1f)); Assert.IsTrue(FillPolygon.PointOnLine(CreatePoint(1, 1), CreatePoint(2, 2), CreatePoint(1.50f, 1.45f), 0.1f)); // Near line but outside tolerance Assert.IsFalse(FillPolygon.PointOnLine(CreatePoint(1, 1), CreatePoint(2, 2), CreatePoint(1.50f, 1.55f), 0.01f)); Assert.IsFalse(FillPolygon.PointOnLine(CreatePoint(1, 1), CreatePoint(2, 2), CreatePoint(1.50f, 1.45f), 0.01f)); // On line but just past end with different accuracy Assert.IsTrue(FillPolygon.PointOnLine(CreatePoint(1, 1), CreatePoint(2, 2), CreatePoint(2.001f, 2.001f), 0.1f)); Assert.IsTrue(FillPolygon.PointOnLine(CreatePoint(1, 1), CreatePoint(2, 2), CreatePoint(0.999f, 0.999f), 0.1f)); Assert.IsFalse(FillPolygon.PointOnLine(CreatePoint(1, 1), CreatePoint(2, 2), CreatePoint(2.001f, 2.001f), 0.0001f)); Assert.IsFalse(FillPolygon.PointOnLine(CreatePoint(1, 1), CreatePoint(2, 2), CreatePoint(0.999f, 0.999f), 0.0001f)); Assert.IsTrue(FillPolygon.PointOnLine(CreatePoint(1, 1), CreatePoint(2, 1), CreatePoint(1.5f, 1.01f), 0.05f)); Assert.IsTrue(FillPolygon.PointOnLine(CreatePoint(1, 1), CreatePoint(1, 2), CreatePoint(1.0f, 1.01f), 0.05f)); }
public void FillPolygonTests1() { // Figure of 8 var polygon = new[] { CreatePoint(2, 1), CreatePoint(3, 2), CreatePoint(3, 6), CreatePoint(3, 6), // Double point - interesting case CreatePoint(5, 6), CreatePoint(5, 3), CreatePoint(2, 4), CreatePoint(1, 2), CreatePoint(2, 1), }; polygon = polygon.Select(x => CreatePoint(x.X - 0.5, x.Y - 0.5)).ToArray(); var dimX = 6; var dimY = 7; var output = new byte[dimX * dimY]; FillPolygon.Fill(polygon, output, dimX, dimY, 0, 0, (byte)1); var resultArray = new byte[] { 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, }; Assert.AreEqual(resultArray.Length, output.Length); for (var i = 0; i < output.Length; i++) { Assert.AreEqual(resultArray[i], output[i]); } polygon = new[] { CreatePoint(0, 0), CreatePoint(dimX, 0), CreatePoint(dimX, dimY), CreatePoint(0, dimY), CreatePoint(0, 0), }; polygon = polygon.Select(x => CreatePoint(x.X - 0.5, x.Y - 0.5)).ToArray(); FillPolygon.Fill(polygon, output, dimX, dimY, 0, 0, (byte)1); for (var i = 0; i < output.Length; i++) { Assert.AreEqual(1, output[i]); } }
/// <summary> /// Extracts axial contours for the foreground values in the given volume. After extracting the contours, /// a check is conducted if the contours truthfully represent the actual volume. This will throw exceptions /// for example if the incoming volume has "doughnut shape" structures. /// </summary> /// <param name="volume">The mask volume to extract contours from.</param> /// <param name="maxAbsoluteDifference">The maximum allowed difference in foreground voxels when going /// from mask to contours to mask.</param> /// <param name="maxRelativeDifference">The maximum allowed relative in foreground voxels (true - rendered)/true /// when going from mask to contours to mask.</param> /// <returns></returns> public static ContoursPerSlice ExtractContoursAndCheck(this Volume3D <byte> volume, int?maxAbsoluteDifference = 10, double?maxRelativeDifference = 0.15 ) { var contours = ExtractContours.ContoursWithHolesPerSlice( volume, foregroundId: ModelConstants.MaskForegroundIntensity, sliceType: SliceType.Axial, filterEmptyContours: true, regionOfInterest: null, axialSmoothingType: ContourSmoothingType.Small); var slice = new byte[volume.DimX * volume.DimY]; void ClearSlice() { for (var index = 0; index < slice.Length; index++) { slice[index] = ModelConstants.MaskBackgroundIntensity; } } foreach (var contourPerSlice in contours) { var indexZ = contourPerSlice.Key; var offsetZ = indexZ * volume.DimXY; ClearSlice(); foreach (var contour in contourPerSlice.Value) { FillPolygon.Fill(contour.ContourPoints, slice, volume.DimX, volume.DimY, 1, 0, ModelConstants.MaskForegroundIntensity); } var true1 = 0; var rendered1 = 0; for (var index = 0; index < slice.Length; index++) { if (volume[offsetZ + index] == ModelConstants.MaskForegroundIntensity) { true1++; } if (slice[index] == ModelConstants.MaskForegroundIntensity) { rendered1++; } } CheckContourRendering(true1, rendered1, maxAbsoluteDifference, maxRelativeDifference, $"Slice z={indexZ}"); } ; return(contours); }
public void FillPolygonTests3() { var polygon = new[] { CreatePoint(0.994356, 1.00136305698), CreatePoint(3.0002425, 0.99924525), CreatePoint(2.999235236, 2.999252346), CreatePoint(1.00135357, 3.001232363) }; var boundingBox = FillPolygon.GetBoundingBox(polygon); Assert.AreEqual(0, FillPolygon.PointInComplexPolygon(polygon, CreatePoint(1, 1), boundingBox)); Assert.AreEqual(0, FillPolygon.PointInComplexPolygon(polygon, CreatePoint(2, 1), boundingBox)); Assert.AreEqual(0, FillPolygon.PointInComplexPolygon(polygon, CreatePoint(3, 1), boundingBox)); Assert.AreEqual(0, FillPolygon.PointInComplexPolygon(polygon, CreatePoint(3, 2), boundingBox)); Assert.AreEqual(0, FillPolygon.PointInComplexPolygon(polygon, CreatePoint(3, 3), boundingBox)); Assert.AreEqual(0, FillPolygon.PointInComplexPolygon(polygon, CreatePoint(2, 3), boundingBox)); Assert.AreEqual(0, FillPolygon.PointInComplexPolygon(polygon, CreatePoint(1, 3), boundingBox)); Assert.AreEqual(0, FillPolygon.PointInComplexPolygon(polygon, CreatePoint(1, 2), boundingBox)); }
public void FillPolygonTests2() { var dimX = 5; var dimY = 5; var polygon1 = new[] { CreatePoint(-0.5, -0.5), CreatePoint(dimX + 0.5, -0.5), CreatePoint(dimX + 0.5, dimY + 0.5), CreatePoint(-0.5, dimY + 0.5) }; var output1 = new byte[dimX * dimY]; FillPolygon.Fill(polygon1, output1, dimX, dimY, 0, 0, (byte)1); for (var i = 0; i < output1.Length; i++) { Assert.AreEqual(1, output1[i]); } var polygon = new[] { CreatePoint(0.1, 0.1), CreatePoint(dimX - 1.1, 0.1), CreatePoint(dimX - 1.1, dimY - 1.1), CreatePoint(0.1, dimY - 1.1) }; var output = new byte[dimX * dimY]; FillPolygon.Fill(polygon, output, dimX, dimY, 0, 0, (byte)1); for (var y = 0; y < dimY; y++) { for (var x = 0; x < dimX; x++) { Assert.AreEqual(y == 0 || y == dimY - 1 || x == 0 || x == dimX - 1 ? 0 : 1, output[x + y * dimX]); } } }
public void FillPolygonOutsideVolume() { var dimX = 5; var dimY = 5; var polygon1 = new[] { CreatePoint(-10.5, -10.5), // Check that if a point is outside the volume this code still works CreatePoint(dimX + 0.5, -0.5), CreatePoint(dimX + 0.5, dimY + 0.5), CreatePoint(-0.5, dimY + 0.5) }; var output1 = new byte[dimX * dimY]; FillPolygon.Fill(polygon1, output1, dimX, dimY, 0, 0, (byte)1); for (var i = 0; i < output1.Length; i++) { Assert.AreEqual(1, output1[i]); } var polygon = new[] { CreatePoint(0.1, 0.1), CreatePoint(dimX - 1.1, 0.1), CreatePoint(dimX - 1.1, dimY - 1.1), CreatePoint(0.1, dimY - 1.1) }; var output = new byte[dimX * dimY]; FillPolygon.Fill(polygon, output, dimX, dimY, 0, 0, (byte)1); for (var y = 0; y < dimY; y++) { for (var x = 0; x < dimX; x++) { Assert.AreEqual(y == 0 || y == dimY - 1 || x == 0 || x == dimX - 1 ? 0 : 1, output[x + y * dimX]); } } }
public void GetPointsOnStraightLineTests() { var point1 = CreatePoint(1, 1); var point2 = CreatePoint(4, 1); CompareArrays(FillPolygon.GetPointsOnLine(point1, point2), new List <Point>() { new Point(1, 1), new Point(2, 1), new Point(3, 1), new Point(4, 1), }); CompareArrays(FillPolygon.GetPointsOnLine(point2, point1), new List <Point>() { new Point(1, 1), new Point(2, 1), new Point(3, 1), new Point(4, 1), }); }
/// <summary> /// Applies flood filling to all holes in the given volume. /// </summary> /// <param name="volume"></param> /// <param name="foregroundId"></param> /// <param name="backgroundId"></param> public static void FillHoles( this Volume2D <byte> volume, byte foregroundId = ModelConstants.MaskForegroundIntensity, byte backgroundId = ModelConstants.MaskBackgroundIntensity) => FillPolygon.FloodFillHoles(volume, foregroundId, backgroundId);
public void CreateAShape(MouseEventArgs e) { switch (status) { case Status.Line: { Shape shape = new Line(); shape.ItsPen = new Pen(btnColor.BackColor, Convert.ToInt16(numThickness.Value)); shape.ItsPen.DashStyle = (DashStyle)cbbStyle.SelectedIndex; shape.ListPoints[0] = shape.ListPoints[1] = e.Location; listShapes.Add(shape); break; } case Status.Rectangle: { Shape shape = new Rectangle(); shape.ItsPen = new Pen(btnColor.BackColor, Convert.ToInt16(numThickness.Value)); shape.ItsPen.DashStyle = (DashStyle)cbbStyle.SelectedIndex; shape.ListPoints[0] = shape.ListPoints[1] = e.Location; listShapes.Add(shape); break; } case Status.FillRectangle: { Shape shape = new FillRectangle(); shape.ItsPen = new Pen(btnColor.BackColor, Convert.ToInt16(numThickness.Value)); shape.ItsPen.DashStyle = (DashStyle)cbbStyle.SelectedIndex; shape.SolidBrush = solidBrush; shape.HatchBrush = hatchBrush; shape.ListPoints[0] = shape.ListPoints[1] = e.Location; listShapes.Add(shape); break; } case Status.Ellipse: { Shape shape = new Ellipse(); shape.ItsPen = new Pen(btnColor.BackColor, Convert.ToInt16(numThickness.Value)); shape.ItsPen.DashStyle = (DashStyle)cbbStyle.SelectedIndex; shape.ListPoints[0] = shape.ListPoints[1] = e.Location; listShapes.Add(shape); break; } case Status.FillEllipse: { Shape shape = new FillEllipse(); shape.ItsPen = new Pen(btnColor.BackColor, Convert.ToInt16(numThickness.Value)); shape.ItsPen.DashStyle = (DashStyle)cbbStyle.SelectedIndex; shape.SolidBrush = solidBrush; shape.HatchBrush = hatchBrush; shape.ListPoints[0] = shape.ListPoints[1] = e.Location; listShapes.Add(shape); break; } case Status.Curve: { if (isCurve) { if (isSecondClickCurve) { listShapes[listShapes.Count - 1].ListPoints[2] = e.Location; } else { listShapes[listShapes.Count - 1].ListPoints[1] = e.Location; } } else { Shape shape = new Curve(); shape.ItsPen = new Pen(btnColor.BackColor, Convert.ToInt16(numThickness.Value)); shape.ItsPen.DashStyle = (DashStyle)cbbStyle.SelectedIndex; shape.ListPoints[0] = shape.ListPoints[1] = shape.ListPoints[2] = shape.ListPoints[3] = e.Location; listShapes.Add(shape); } break; } case Status.Polygon: { if (stopDrawPolygon) { Shape shape = new Polygon(); shape.ItsPen = new Pen(btnColor.BackColor, Convert.ToInt16(numThickness.Value)); shape.ItsPen.DashStyle = (DashStyle)cbbStyle.SelectedIndex; listShapes.Add(shape); listShapes[listShapes.Count - 1].ListPoints[0] = e.Location; stopDrawPolygon = false; } Point point = e.Location; listShapes[listShapes.Count - 1].ListPoints.Add(point); listShapes[listShapes.Count - 1].ListDxDy.Add(point); break; } case Status.FillPolygon: { if (stopFillPolygon) { Shape shape = new FillPolygon(); shape.ItsPen = new Pen(btnColor.BackColor, Convert.ToInt16(numThickness.Value)); shape.ItsPen.DashStyle = (DashStyle)cbbStyle.SelectedIndex; shape.SolidBrush = solidBrush; shape.HatchBrush = hatchBrush; listShapes.Add(shape); listShapes[listShapes.Count - 1].ListPoints[0] = e.Location; stopFillPolygon = false; } Point point = e.Location; listShapes[listShapes.Count - 1].ListPoints.Add(point); listShapes[listShapes.Count - 1].ListDxDy.Add(point); break; } } }
/// <summary> /// Modifies the present volume by filling all points that fall inside of the given contours, /// using the provided fill value. Contours are filled on axial slices. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="volume">The volume that should be modified.</param> /// <param name="contours">The contours per axial slice.</param> /// <param name="value">The value that should be used to fill all points that fall inside of /// the given contours.</param> public static void Fill <T>(this Volume3D <T> volume, ContoursPerSlice contours, T value) => FillPolygon.FillContours(volume, contours, value);
/// <summary> /// Modifies the present volume by filling all points that fall inside of the given contours, /// using the provided fill value. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="volume">The volume that should be modified.</param> /// <param name="contours">The contours that should be used for filling.</param> /// <param name="value">The value that should be used to fill all points that fall inside of /// any of the given contours.</param> public static void Fill <T>(this Volume2D <T> volume, IEnumerable <ContourPolygon> contours, T value) => FillPolygon.FillContours(volume, contours, value);
public void LCDLibTests(string argument, UpdateType updateSource) { switch (argument) { case "DrawCircle": int ranX = random.Next(0, 174); int ranY = random.Next(0, 174); Vector2I pos = new Vector2I(ranX, ranY); var circle = new FillCircle(pos, random.Next(1, 50), Color.White); drawingLib.AddElement(circle); break; case "DrawLine": int ranX0 = random.Next(0, 174); int ranY0 = random.Next(0, 174); int ranX1 = random.Next(0, 174); int ranY1 = random.Next(0, 174); Vector2I pointOne = new Vector2I(ranX0, ranY0); Vector2I pointTwo = new Vector2I(ranX1, ranY1); var line = new Line(pointOne, pointTwo, Color.White); drawingLib.AddElement(line); break; case "DrawEllipse": int ranEX0 = random.Next(0, 174); int ranEY0 = random.Next(0, 174); int ranEX1 = random.Next(0, 174); int ranEY1 = random.Next(0, 174); Vector2I pointEOne = new Vector2I(ranEX0, ranEY0); Vector2I pointETwo = new Vector2I(ranEX1, ranEY1); var elipse = new FillEllipse(pointEOne, pointETwo, Color.White); drawingLib.AddElement(elipse); break; case "DrawRect": int ranRX0 = random.Next(0, 174); int ranRY0 = random.Next(0, 174); int ranRX1 = random.Next(0, 174); int ranRY1 = random.Next(0, 174); Vector2I pointROne = new Vector2I(ranRX0, ranRY0); Vector2I pointRTwo = new Vector2I(ranRX1, ranRY1); var rectangle = new FillRectangle(pointROne, pointRTwo, Color.White); drawingLib.AddElement(rectangle); break; case "DrawPolygon": var positions = new List <Vector2I>(); for (int i = 0; i < random.Next(3, 16); i++) { positions.Add(VectorUtils.GenerateRandomVector2I(random)); } var polygon = new FillPolygon(positions, Color.White); drawingLib.AddElement(polygon); break; case "DrawTriangle": positions = new List <Vector2I>(); positions.Add(new Vector2I(100, 1)); positions.Add(new Vector2I(100, 100)); positions.Add(new Vector2I(200, 150)); polygon = new FillPolygon(positions, Color.White); drawingLib.AddElement(polygon); break; case "DrawCharacter": int ranCX0 = random.Next(0, 174); int ranCY0 = random.Next(0, 174); Vector2I posChar = new Vector2I(ranCX0, ranCY0); var character = new ResizableCharacter(posChar, 'E', Color.White, 1); drawingLib.AddElement(character); break; case "HelloWorld": int ranTX0 = random.Next(0, 174); int ranTY0 = random.Next(0, 174); Vector2I posT = new Vector2I(ranTX0, ranTY0); text = new Text(posT, "0123456789", Color.White, 1, true); drawingLib.AddElement(text); break; case "UpdateText": if (text != null) { text.UpdateValue("Hello World!"); } break; case "Clear": drawingLib.Clear(); break; } drawingLib.RunRenderer(); Echo($"Tasks Left in Queue: {drawingLib.RenderQueueSize}"); }
public void PointInPolygonTests() { var polygon = new[] { CreatePoint(1, 1), CreatePoint(10, 1), CreatePoint(10, 10), CreatePoint(1, 10), // Non repeating last value }; var bounds = FillPolygon.GetBoundingBox(polygon); Assert.AreEqual(0, FillPolygon.PointInComplexPolygon(polygon, CreatePoint(1, 5), bounds)); // On the last point pair Assert.AreEqual(0, FillPolygon.PointInComplexPolygon(polygon, CreatePoint(5, 10), bounds)); Assert.AreEqual(1, FillPolygon.PointInComplexPolygon(polygon, CreatePoint(5, 5), bounds)); polygon = new[] { CreatePoint(1, 1), CreatePoint(10, 1), CreatePoint(10, 10), CreatePoint(9, 10), CreatePoint(8, 10), CreatePoint(7, 10), CreatePoint(6, 10), CreatePoint(5, 10), CreatePoint(4, 10), CreatePoint(3, 10), CreatePoint(2, 10), CreatePoint(1, 10), CreatePoint(1, 9), CreatePoint(1, 8), CreatePoint(1, 7), CreatePoint(1, 3), CreatePoint(1, 2), }; Assert.AreEqual(1, FillPolygon.PointInComplexPolygon(polygon, CreatePoint(5, 5))); polygon = new[] { CreatePoint(1, 1), CreatePoint(1, 1), }; Assert.AreEqual(0, FillPolygon.PointInComplexPolygon(polygon, CreatePoint(1, 1))); Assert.AreEqual(0, FillPolygon.PointInComplexPolygon(polygon, CreatePoint(1.0001, 1.00001))); // Check all surrounding points Assert.AreEqual(-1, FillPolygon.PointInComplexPolygon(polygon, CreatePoint(0, 0))); Assert.AreEqual(-1, FillPolygon.PointInComplexPolygon(polygon, CreatePoint(1, 0))); Assert.AreEqual(-1, FillPolygon.PointInComplexPolygon(polygon, CreatePoint(2, 0))); Assert.AreEqual(-1, FillPolygon.PointInComplexPolygon(polygon, CreatePoint(2, 1))); Assert.AreEqual(-1, FillPolygon.PointInComplexPolygon(polygon, CreatePoint(2, 2))); Assert.AreEqual(-1, FillPolygon.PointInComplexPolygon(polygon, CreatePoint(1, 2))); Assert.AreEqual(-1, FillPolygon.PointInComplexPolygon(polygon, CreatePoint(0, 2))); Assert.AreEqual(-1, FillPolygon.PointInComplexPolygon(polygon, CreatePoint(0, 1))); polygon = new[] { CreatePoint(1, 1), CreatePoint(2, 1), CreatePoint(2, 2), CreatePoint(3, 2), CreatePoint(4, 2), CreatePoint(4, 1), CreatePoint(5, 1), CreatePoint(5, 4), CreatePoint(3, 3), CreatePoint(1, 4), CreatePoint(1, 1), }; bounds = FillPolygon.GetBoundingBox(polygon); Assert.AreEqual(0, FillPolygon.PointInComplexPolygon(polygon, CreatePoint(1, 1), bounds)); Assert.AreEqual(-1, FillPolygon.PointInComplexPolygon(polygon, CreatePoint(3.5, 1.5), bounds)); Assert.AreEqual(-1, FillPolygon.PointInComplexPolygon(polygon, CreatePoint(2, 4), bounds)); Assert.AreEqual(0, FillPolygon.PointInComplexPolygon(polygon, CreatePoint(2, 1), bounds)); polygon = new[] { CreatePoint(1, 1), CreatePoint(1, 2), CreatePoint(2, 2), CreatePoint(1, 1), }; Assert.AreEqual(0, FillPolygon.PointInComplexPolygon(polygon, CreatePoint(1.5, 1.5))); Assert.AreEqual(0, FillPolygon.PointInComplexPolygon(polygon, CreatePoint(1.6, 1.6))); Assert.AreEqual(-1, FillPolygon.PointInComplexPolygon(polygon, CreatePoint(1.6, 1.5))); // Figure of 8 polygon = new[] { CreatePoint(2, 1), CreatePoint(3, 2), CreatePoint(3, 6), CreatePoint(3, 6), // Double point - interesting case CreatePoint(5, 6), CreatePoint(5, 3), CreatePoint(2, 4), CreatePoint(1, 2), CreatePoint(2, 1), }; Assert.AreEqual(1, FillPolygon.PointInComplexPolygon(polygon, CreatePoint(2, 3))); Assert.AreEqual(1, FillPolygon.PointInComplexPolygon(polygon, CreatePoint(4, 4))); Assert.AreEqual(-1, FillPolygon.PointInComplexPolygon(polygon, CreatePoint(4, 2))); }
/// <summary> /// Fills the contour using high accuracy (point in polygon testing). /// </summary> /// <typeparam name="T">The volume type.</typeparam> /// <param name="volume">The volume.</param> /// <param name="contourPoints">The points that defines the contour we are filling.</param> /// <param name="region">The value we will mark in the volume when a point is within the contour.</param> /// <returns>The number of points filled.</returns> public static int FillContour <T>(this Volume2D <T> volume, PointF[] contourPoints, T value) { return(FillPolygon.Fill(contourPoints, volume.Array, volume.DimX, volume.DimY, 0, 0, value)); }