public void Build(QuadTreeNode Mask, double compensateangle = 0.0) { // M = new Mesh(); Lines.Clear(); Mask.NodeWalker(GetAllCorners, true, true); var GM = new TriangleNet.Meshing.GenericMesher(); if (IG.Count < 3) { M = null; return; } else { M = GM.Triangulate(IG); } //M.Triangulate(IG); //M.Smooth(); //M.Refine(); //M.Refine(); double S = Math.Sin(compensateangle); double C = Math.Cos(compensateangle); foreach (var a in M.Triangles) { var V1 = M.Vertices.ElementAt(a.GetVertexID(0)); var V2 = M.Vertices.ElementAt(a.GetVertexID(1)); var V3 = M.Vertices.ElementAt(a.GetVertexID(2)); QuadTreeNode N = Mask.GetNode((V1.X + V2.X + V3.X) / 3.0, (V1.Y + V2.Y + V3.Y) / 3.0); if (N != null && N.Items.Count == 0) { var D1 = MathHelpers.Difference(new PointF((float)V1.X, (float)V1.Y), new PointF((float)V2.X, (float)V2.Y)); var D2 = MathHelpers.Difference(new PointF((float)V2.X, (float)V2.Y), new PointF((float)V3.X, (float)V3.Y)); var D3 = MathHelpers.Difference(new PointF((float)V3.X, (float)V3.Y), new PointF((float)V1.X, (float)V1.Y)); var D1L = MathHelpers.Length(D1); var D2L = MathHelpers.Length(D2); var D3L = MathHelpers.Length(D3); if (D1L < D2L && D1L < D3L) { // Lines.Add(new Tuple<PointF, PointF>(new PointF((float)V2.X, (float)V2.Y), new PointF((float)V3.X, (float)V3.Y))); // Lines.Add(new Tuple<PointF, PointF>(new PointF((float)V3.X, (float)V3.Y), new PointF((float)V1.X, (float)V1.Y))); Lines.Add(new Tuple <PointF, PointF>(new PointF((float)V1.X, (float)V1.Y), new PointF((float)V2.X, (float)V2.Y))); } if (D2L < D1L && D2L < D3L) { Lines.Add(new Tuple <PointF, PointF>(new PointF((float)V2.X, (float)V2.Y), new PointF((float)V3.X, (float)V3.Y))); // Lines.Add(new Tuple<PointF, PointF>(new PointF((float)V1.X, (float)V1.Y), new PointF((float)V2.X, (float)V2.Y))); // Lines.Add(new Tuple<PointF, PointF>(new PointF((float)V3.X, (float)V3.Y), new PointF((float)V1.X, (float)V1.Y))); } if (D3L < D2L && D3L < D1L) { Lines.Add(new Tuple <PointF, PointF>(new PointF((float)V3.X, (float)V3.Y), new PointF((float)V1.X, (float)V1.Y))); // Lines.Add(new Tuple<PointF, PointF>(new PointF((float)V1.X, (float)V1.Y), new PointF((float)V2.X, (float)V2.Y))); // Lines.Add(new Tuple<PointF, PointF>(new PointF((float)V2.X, (float)V2.Y), new PointF((float)V3.X, (float)V3.Y))); } } } Matrix mM = new Matrix(); mM.Rotate((float)compensateangle); List <Tuple <PointF, PointF> > l2 = new List <Tuple <PointF, PointF> >(); foreach (var a in Lines) { PointF[] A = new PointF[2] { a.Item1, a.Item2 }; mM.TransformPoints(A); l2.Add(new Tuple <PointF, PointF>(A[0], A[1])); } Lines = l2; }
private void GetAllCorners(QuadTreeNode obj) { IG.Add(new TriangleNet.Geometry.Vertex((obj.xstart + obj.xend) / 2.0, (obj.ystart + obj.yend) / 2.0, 1)); }
public int BuildStuff(Bitmap aMask, Settings TheSettings) { DirectBitmap Mask = new DirectBitmap(aMask.Width, aMask.Height); Graphics mg = Graphics.FromImage(Mask.Bitmap); mg.DrawImage(aMask, 0, 0); int i = Math.Max(Mask.Width, Mask.Height); int R = 1; while (R < i) { R *= 2; } ArtTree = null; float ThresholdLevel = TheSettings.Threshold * 0.01f; switch (TheSettings.Mode) { case Settings.ArtMode.QuadTree: { DateTime rR = DateTime.Now; ArtTree = new QuadTreeNode() { xstart = -1000, ystart = -1000, xend = R, yend = R }; float hoek = (float)((6.283 * TheSettings.DegreesOff) / 360.0); for (int x = 0; x < Mask.Width; x++) { for (int y = 0; y < Mask.Height; y++) { var C = Mask.GetPixelFast(x, y); bool doit = false; if (TheSettings.InvertSource) { doit = C.GetBrightness() > ThresholdLevel; } else { doit = C.GetBrightness() < ThresholdLevel; } if (doit) { double cx = Math.Cos(hoek) * x + Math.Sin(hoek) * y; double cy = Math.Sin(hoek) * -x + Math.Cos(hoek) * y; ArtTree.Insert((int)cx, (int)cy, new SolidQuadTreeItem() { x = (int)cx, y = (int)cy }, TheSettings.MaxSubDiv); } } } var Elapsed = DateTime.Now - rR; return((int)Elapsed.TotalMilliseconds); } case Settings.ArtMode.Delaunay: { DateTime rR = DateTime.Now; ArtTree = new QuadTreeNode() { xstart = -1000, ystart = -1000, xend = R, yend = R }; float hoek = (float)((6.283 * TheSettings.DegreesOff) / 360.0); for (int x = 0; x < Mask.Width; x++) { for (int y = 0; y < Mask.Height; y++) { var C = Mask.GetPixelFast(x, y); bool doit = false; if (TheSettings.InvertSource) { doit = C.GetBrightness() > ThresholdLevel; } else { doit = C.GetBrightness() < ThresholdLevel; } if (doit) { double cx = Math.Cos(hoek) * x + Math.Sin(hoek) * y; double cy = Math.Sin(hoek) * -x + Math.Cos(hoek) * y; ArtTree.Insert((int)cx, (int)cy, new SolidQuadTreeItem() { x = (int)cx, y = (int)cy }, TheSettings.MaxSubDiv); } } } Delaunay.Build(ArtTree, TheSettings.DegreesOff); var Elapsed = DateTime.Now - rR; return((int)Elapsed.TotalMilliseconds); }; case Settings.ArtMode.Tiling: { TD.Create(TheSettings.TileType); var P = TD.CreateBaseTriangle(TheSettings.BaseTile, 1000); var P2 = TD.CreateBaseTriangle(TheSettings.BaseTile, 1000); P.Rotate(TheSettings.DegreesOff); P.AlterToFit(Mask.Width, Mask.Height); P2.Rotate(TheSettings.DegreesOff); P2.AlterToFit(Mask.Width, Mask.Height); if (TheSettings.Symmetry) { P.ShiftToEdge(Mask.Width / 2, Mask.Height / 2); P2.ShiftToEdge(Mask.Width / 2, Mask.Height / 2); P2.Flip(Mask.Width / 2, Mask.Height / 2); if (TheSettings.SuperSymmetry) { P2.MirrorAround(Mask.Width / 2, Mask.Height / 2); } } DateTime rR = DateTime.Now; SubDivPoly = TD.SubdivideAdaptive(P, TheSettings.MaxSubDiv, MaskTree, TheSettings.alwayssubdivide); if (TheSettings.Symmetry) { SubDivPoly.AddRange(TD.SubdivideAdaptive(P2, TheSettings.MaxSubDiv, MaskTree, TheSettings.alwayssubdivide)); } if (TheSettings.xscalesmallerlevel != 0) { float midx = Mask.Width / 2.0f; float width = Mask.Width; float offs = TheSettings.xscalecenter * 0.01f * width; foreach (var A in SubDivPoly) { var M = A.Mid(); float scaler = 1.0f - ((float)(M.x - offs) / width) * TheSettings.xscalesmallerlevel * 0.01f; //scaler = Math.Max(0, Math.Min(1.0f, scaler)); A.ScaleDown(TheSettings.scalingMode, scaler); } } if (TheSettings.scalesmallerfactor != 1.0f) { foreach (var A in SubDivPoly) { A.ScaleDown(Settings.TriangleScaleMode.Balanced, TheSettings.scalesmallerfactor); } } if (TheSettings.scalesmaller != 0) { float scaler = Math.Abs(TheSettings.scalesmaller); if (TheSettings.scalesmaller > 0) { scaler = scaler / 10.0f; } else { scaler = -scaler / 10.0f; } foreach (var A in SubDivPoly) { if (A.depth - TheSettings.scalesmallerlevel <= 1) { } else { A.ScaleDown(TheSettings.scalingMode, (1 + scaler * (1.0f / (A.depth - TheSettings.scalesmallerlevel)))); } } } if (TheSettings.distanceToMaskScale != 0) { float scaler = Math.Abs(TheSettings.distanceToMaskScale); if (TheSettings.distanceToMaskScale > 0) { scaler = scaler / 10.0f; } else { scaler = -scaler / 10.0f; } float aThresholdLevel = TheSettings.Threshold * 0.01f; foreach (var A in SubDivPoly) { var m = A.Mid(); float sum = GetPixelSum(m, Mask, TheSettings.distanceToMaskRange, aThresholdLevel, TheSettings.InvertSource); //if (sum > 1) sum = 1; A.ScaleDown(TheSettings.scalingMode, (scaler * sum)); } } if (TheSettings.MarcelPlating) { List <Tiling.Polygon> MarcelShapes = new List <Tiling.Polygon>(); foreach (var A in SubDivPoly) { MarcelShape MS = new MarcelShape(); MarcelShape MS2 = new MarcelShape(); foreach (var v in A.Vertices) { MS2.Vertices.Add(new ClipperLib.IntPoint((long)((v.x + 1000) * 1000), (long)((v.y + 1000) * 1000))); } MS.ShrinkFromShape(MS2.Vertices, TheSettings.Gap / 2 + TheSettings.Rounding / 2); Paths Ps = new Paths(); Ps.AddRange(MS.BuildOutlines(TheSettings.Rounding / 2.0f)); if (TheSettings.BallRadius > 0) { Ps.AddRange(MS.BuildHoles(TheSettings.BallRadius)); } foreach (var p in Ps) { Tiling.Polygon Poly = new Tiling.Polygon(); Poly.Vertices.AddRange(from a in p select new vec2((a.X) * 0.001f - 1000, (a.Y) * 0.001f - 1000)); MarcelShapes.Add(Poly); } } SubDivPoly.Clear(); SubDivPoly = MarcelShapes; } var Elapsed = DateTime.Now - rR; return((int)Elapsed.TotalMilliseconds); } } ; return(0); }
public void BuildTree(Bitmap Mask, Settings TheSettings) { int i = Math.Max(Mask.Width, Mask.Height); int R = 1; while (R < i) { R *= 2; } MaskTree = new QuadTreeNode() { xstart = 0, ystart = 0, xend = R, yend = R }; float ThresholdLevel = TheSettings.Threshold * 0.01f; try { BitmapData srcData = Mask.LockBits(new Rectangle(0, 0, Mask.Width, Mask.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); unsafe { byte *srcPointer = (byte *)srcData.Scan0; for (int yy = 0; yy < Mask.Height; yy++) { for (int xx = 0; xx < Mask.Width; xx++) { byte B = srcPointer[0]; // Blue Color C = Color.FromArgb(srcPointer[2], srcPointer[1], srcPointer[0]); bool doit = false; if (TheSettings.InvertSource) { doit = C.GetBrightness() > ThresholdLevel; } else { doit = C.GetBrightness() < ThresholdLevel; } if (doit) { MaskTree.Insert(xx, yy, new SolidQuadTreeItem() { x = (int)xx, y = (int)yy }, 8); } srcPointer += 4; } srcPointer += (srcData.Stride - (Mask.Width * 4)); } } Mask.UnlockBits(srcData); } catch (InvalidOperationException e) { } /* * * for (int x = 0; x < Mask.Width; x++) * { * for (int y = 0; y < Mask.Height; y++) * { * var C = Mask.GetPixel(x, y); * bool doit = false; * if (TheSettings.InvertSource) * { * doit = C.GetBrightness() > ThresholdLevel; * } * else * { * doit = C.GetBrightness() < ThresholdLevel; * } * if (doit) * { * MaskTree.Insert(x, y, new SolidQuadTreeItem() { x = (int)x, y = (int)y }, 8); * } * } * } * */ }
public int BuildStuff(Bitmap Mask, Settings TheSettings) { int i = Math.Max(Mask.Width, Mask.Height); int R = 1; while (R < i) { R *= 2; } ArtTree = null; float ThresholdLevel = TheSettings.Threshold * 0.01f; switch (TheSettings.Mode) { case Settings.ArtMode.QuadTree: { DateTime rR = DateTime.Now; ArtTree = new QuadTreeNode() { xstart = -1000, ystart = -1000, xend = R, yend = R }; float hoek = (float)((6.283 * TheSettings.DegreesOff) / 360.0); for (int x = 0; x < Mask.Width; x++) { for (int y = 0; y < Mask.Height; y++) { var C = Mask.GetPixel(x, y); bool doit = false; if (TheSettings.InvertSource) { doit = C.GetBrightness() > ThresholdLevel; } else { doit = C.GetBrightness() < ThresholdLevel; } if (doit) { double cx = Math.Cos(hoek) * x + Math.Sin(hoek) * y; double cy = Math.Sin(hoek) * -x + Math.Cos(hoek) * y; ArtTree.Insert((int)cx, (int)cy, new SolidQuadTreeItem() { x = (int)cx, y = (int)cy }, TheSettings.MaxSubDiv); } } } var Elapsed = DateTime.Now - rR; return((int)Elapsed.TotalMilliseconds); } case Settings.ArtMode.Delaunay: { DateTime rR = DateTime.Now; ArtTree = new QuadTreeNode() { xstart = -1000, ystart = -1000, xend = R, yend = R }; float hoek = (float)((6.283 * TheSettings.DegreesOff) / 360.0); for (int x = 0; x < Mask.Width; x++) { for (int y = 0; y < Mask.Height; y++) { var C = Mask.GetPixel(x, y); bool doit = false; if (TheSettings.InvertSource) { doit = C.GetBrightness() > ThresholdLevel; } else { doit = C.GetBrightness() < ThresholdLevel; } if (doit) { double cx = Math.Cos(hoek) * x + Math.Sin(hoek) * y; double cy = Math.Sin(hoek) * -x + Math.Cos(hoek) * y; ArtTree.Insert((int)cx, (int)cy, new SolidQuadTreeItem() { x = (int)cx, y = (int)cy }, TheSettings.MaxSubDiv); } } } Delaunay.Build(ArtTree, TheSettings.DegreesOff); var Elapsed = DateTime.Now - rR; return((int)Elapsed.TotalMilliseconds); }; case Settings.ArtMode.Tiling: { TD.Create(TheSettings.TileType); var P = TD.CreateBaseTriangle(TheSettings.BaseTile, 1000); var P2 = TD.CreateBaseTriangle(TheSettings.BaseTile, 1000); P.Rotate(TheSettings.DegreesOff); P.AlterToFit(Mask.Width, Mask.Height); P2.Rotate(TheSettings.DegreesOff); P2.AlterToFit(Mask.Width, Mask.Height); if (TheSettings.Symmetry) { P.ShiftToEdge(Mask.Width / 2, Mask.Height / 2); P2.ShiftToEdge(Mask.Width / 2, Mask.Height / 2); P2.Flip(Mask.Width / 2, Mask.Height / 2); if (TheSettings.SuperSymmetry) { P2.MirrorAround(Mask.Width / 2, Mask.Height / 2); } } DateTime rR = DateTime.Now; SubDivPoly = TD.SubdivideAdaptive(P, TheSettings.MaxSubDiv, MaskTree, TheSettings.alwayssubdivide); if (TheSettings.Symmetry) { SubDivPoly.AddRange(TD.SubdivideAdaptive(P2, TheSettings.MaxSubDiv, MaskTree, TheSettings.alwayssubdivide)); } if (TheSettings.xscalesmallerlevel != 0) { float midx = Mask.Width / 2.0f; float width = Mask.Width; float offs = TheSettings.xscalecenter * 0.01f * width; foreach (var A in SubDivPoly) { var M = A.Mid(); float scaler = 1.0f - ((float)(M.x - offs) / width) * TheSettings.xscalesmallerlevel * 0.01f; //scaler = Math.Max(0, Math.Min(1.0f, scaler)); A.ScaleDown(TheSettings.scalingMode, scaler); } } if (TheSettings.scalesmallerfactor != 1.0f) { foreach (var A in SubDivPoly) { A.ScaleDown(Settings.TriangleScaleMode.Balanced, TheSettings.scalesmallerfactor); } } if (TheSettings.scalesmaller != 0) { float scaler = Math.Abs(TheSettings.scalesmaller); if (TheSettings.scalesmaller > 0) { scaler = scaler / 10.0f; } else { scaler = -scaler / 10.0f; } foreach (var A in SubDivPoly) { if (A.depth - TheSettings.scalesmallerlevel <= 1) { } else { A.ScaleDown(TheSettings.scalingMode, (1 + scaler * (1.0f / (A.depth - TheSettings.scalesmallerlevel)))); } } } var Elapsed = DateTime.Now - rR; return((int)Elapsed.TotalMilliseconds); } } ; return(0); }
public int BuildStuff(Bitmap Mask, Settings TheSettings) { int i = Math.Max(Mask.Width, Mask.Height); int R = 1; while (R < i) { R *= 2; } ArtTree = null; float ThresholdLevel = TheSettings.Threshold * 0.01f; switch (TheSettings.Mode) { case Settings.ArtMode.QuadTree: { DateTime rR = DateTime.Now; ArtTree = new QuadTreeNode() { xstart = -1000, ystart = -1000, xend = R, yend = R }; float hoek = (float)((6.283 * TheSettings.DegreesOff) / 360.0); for (int x = 0; x < Mask.Width; x++) { for (int y = 0; y < Mask.Height; y++) { var C = Mask.GetPixel(x, y); bool doit = false; if (TheSettings.InvertSource) { doit = C.GetBrightness() > ThresholdLevel; } else { doit = C.GetBrightness() < ThresholdLevel; } if (doit) { double cx = Math.Cos(hoek) * x + Math.Sin(hoek) * y; double cy = Math.Sin(hoek) * -x + Math.Cos(hoek) * y; ArtTree.Insert((int)cx, (int)cy, new SolidQuadTreeItem() { x = (int)cx, y = (int)cy }, TheSettings.MaxSubDiv); } } } var Elapsed = DateTime.Now - rR; return((int)Elapsed.TotalMilliseconds); } case Settings.ArtMode.Delaunay: { DateTime rR = DateTime.Now; ArtTree = new QuadTreeNode() { xstart = -1000, ystart = -1000, xend = R, yend = R }; float hoek = (float)((6.283 * TheSettings.DegreesOff) / 360.0); for (int x = 0; x < Mask.Width; x++) { for (int y = 0; y < Mask.Height; y++) { var C = Mask.GetPixel(x, y); bool doit = false; if (TheSettings.InvertSource) { doit = C.GetBrightness() > ThresholdLevel; } else { doit = C.GetBrightness() < ThresholdLevel; } if (doit) { double cx = Math.Cos(hoek) * x + Math.Sin(hoek) * y; double cy = Math.Sin(hoek) * -x + Math.Cos(hoek) * y; ArtTree.Insert((int)cx, (int)cy, new SolidQuadTreeItem() { x = (int)cx, y = (int)cy }, TheSettings.MaxSubDiv); } } } Delaunay.Build(ArtTree, TheSettings.DegreesOff); var Elapsed = DateTime.Now - rR; return((int)Elapsed.TotalMilliseconds); }; case Settings.ArtMode.Tiling: { TD.Create(TheSettings.TileType); var P = TD.CreateBaseTriangle(TheSettings.BaseTile, 1000); P.Rotate(TheSettings.DegreesOff); P.AlterToFit(Mask.Width, Mask.Height); DateTime rR = DateTime.Now; SubDivPoly = TD.SubdivideAdaptive(P, TheSettings.MaxSubDiv, MaskTree); var Elapsed = DateTime.Now - rR; return((int)Elapsed.TotalMilliseconds); } } ; return(0); }