public DoubleVector2(IntVector2 v) { this.x = (double)v.x; this.y = (double)v.y; }
public VectorPixel(IntVector2 fromPnt, IntVector2 toPnt) { this.fromPnt = fromPnt; this.toPnt = toPnt; }
public bool extension(IntVector2 otherVector) { return (x * y == 0 && x * otherVector.y - y * otherVector.x == 0); // parallel to either axis AND colinear }
public Line(VectorPixel v) { maxleft = Double.MinValue; minright = Double.MaxValue; outerFromPnt = v.fromPnt; toPnt = v.toPnt; nextmindx = 0; nextmaxdx = Int32.MaxValue; nextmindy = 0; nextmaxdy = Int32.MaxValue; }
protected void saveAsBmp(String fileName) { if (polygons.Count == 0) throw new Exception("there must be at least one polygon!"); ArrayList[] inPnt = new ArrayList[ymax - ymin + 1]; for (int i = 0; i < inPnt.Length; i++) inPnt[i] = new ArrayList(20); for (int j = 0; j < polygons.Count; j++) { ArrayList vertices = (ArrayList)polygons[j]; for (int i = 0; i < vertices.Count; i++) { DoubleVector2 vertex = (DoubleVector2)vertices[i]; DoubleVector2 vertexNext = i + 1 < vertices.Count ? (DoubleVector2)vertices[i + 1] : (DoubleVector2)vertices[0]; IntVector2 pointFrom = new IntVector2((int)vertex.x - xmin, (int)vertex.y - ymin); IntVector2 pointTo = new IntVector2((int)vertexNext.x - xmin, (int)vertexNext.y - ymin); VectorPixel vect = new VectorPixel(pointFrom, pointTo); if (vect.dy != 1) { IntVector2 pointNow; for (int k = 0; k < vect.dy; k++) { if (vect.dx > vect.dy) { if (vect.sx * vect.sy == 1) pointNow = new IntVector2(pointFrom.x + vect.sx * (2 * vect.dx * k + vect.dy - 1) / (2 * vect.dy), pointFrom.y + vect.sy * k); else pointNow = new IntVector2(pointFrom.x + vect.sx * ((2 * vect.dx * (k + 1) + vect.dy - 1) / (2 * vect.dy) - 1), pointFrom.y + vect.sy * k); } else pointNow = new IntVector2(pointFrom.x + vect.sx * (2 * (vect.dx - 1) * k + vect.dy - 1) / (2 * (vect.dy - 1)), pointFrom.y + vect.sy * k); inPnt[pointNow.y].Add(new FromToInt(pointNow.x, vect.sx, vect.sy, pointFrom.x + pointTo.x)); } } } } Bitmap bmp = new Bitmap(xmax - xmin + 3, ymax - ymin + 3, PixelFormat.Format32bppRgb); BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, bmp.PixelFormat); int stride = bmpData.Stride; Int64 startPtr = bmpData.Scan0.ToInt64(); if (stride < 0) { startPtr += stride * (bmpData.Height - 1); stride = Math.Abs(stride); } byte[] rowBytes = new byte[bmpData.Stride]; for (int i = 0; i < bmpData.Height; i++) // make everything black first System.Runtime.InteropServices.Marshal.Copy(new IntPtr(startPtr + stride * i), rowBytes, 0, bmpData.Stride); for (int i = 0; i < bmpData.Stride; i++) rowBytes[i] = 255; for (int i = 0; i < inPnt.Length; i++) { inPnt[i].Sort(); for (int j = 1; j < inPnt[i].Count; j++) { FromToInt f = (FromToInt)inPnt[i][j]; FromToInt fprev = (FromToInt)inPnt[i][j - 1]; if (f.sy > 0 && fprev.sy <= 0 && f.x - (fprev.x + 1) > 0) // insert empty space where appropriate System.Runtime.InteropServices.Marshal.Copy(rowBytes, 0, new IntPtr(startPtr + stride * i + 4 * (fprev.x + 1)), 4 * (f.x - (fprev.x + 1))); f = (FromToInt)inPnt[i][j]; fprev = (FromToInt)inPnt[i][j - 1]; } } bmp.UnlockBits(bmpData); bmp.Save(fileName); }
protected SortedList createVectors(byte[,] pixelOn, Bitmap bmp) { SortedList vectors = new SortedList(bmp.Width * bmp.Height / 32); Hashtable vectorsReverse = new Hashtable(bmp.Width * bmp.Height / 32); int steps = 0; for (int j = 0; j < bmp.Height + 1; j++) for (int i = 0; i < bmp.Width + 1; i++) { printProgress(ref steps, 400000); int type = (pixelOn[i, j] & 1) + ((pixelOn[i + 1, j] & 1) << 1) + ((pixelOn[i, j + 1] & 1) << 2) + ((pixelOn[i + 1, j + 1] & 1) << 3); if (type == 1 + 8 || type == 2 + 4) { // get rid of illegal situations pixelOn[i, j] |= 1; pixelOn[i + 1, j] |= 1; pixelOn[i, j + 1] |= 1; pixelOn[i + 1, j + 1] |= 1; printWarning("\nillegal pixel configuration at [" + i + ", " + j + "]"); } } for (int j = 0; j < bmp.Height; j++) for (int i = 0; i < bmp.Width; i++) { printProgress(ref steps, 800000); if ((pixelOn[i + 1, j + 1] & 1) == 1) { int type1 = (pixelOn[i + 1, j] & 1) + (pixelOn[i + 1, j + 2] & 1); int type2 = (pixelOn[i, j + 1] & 1) + (pixelOn[i + 2, j + 1] & 1); if (type1 == 2 && type2 == 0 || type1 == 0 && type2 == 2 ) { // get rid of illegal situations pixelOn[i + 2, j + 1] |= 1; pixelOn[i + 1, j + 2] |= 1; printWarning("\nillegal pixel configuration at [" + i + ", " + j + "]"); } } } for (int j = -1; j < bmp.Height; j++) for (int i = -1; i < bmp.Width; i++) { printProgress(ref steps, 400000); int type = (pixelOn[i + 1, j + 1] & 1) + ((pixelOn[i + 2, j + 1] & 1) << 1) + ((pixelOn[i + 1, j + 2] & 1) << 2) + ((pixelOn[i + 2, j + 2] & 1) << 3); IntVector2 fromPnt = new IntVector2(); IntVector2 toPnt = new IntVector2(); switch (type) { // create horizontal and vertical vectors between adjacent pixels case 3: // xx // -- fromPnt = new IntVector2(i, j); toPnt = new IntVector2(i + 1, j); break; case 12: // -- // xx fromPnt = new IntVector2(i + 1, j + 1); toPnt = new IntVector2(i, j + 1); break; case 5: // x- // x- fromPnt = new IntVector2(i, j + 1); toPnt = new IntVector2(i, j); break; case 10: // -x // -x fromPnt = new IntVector2(i + 1, j); toPnt = new IntVector2(i + 1, j + 1); break; case 14: // -x // xx fromPnt = new IntVector2(i + 1, j); toPnt = new IntVector2(i, j + 1); break; case 13: // x- // xx fromPnt = new IntVector2(i + 1, j + 1); toPnt = new IntVector2(i, j); break; case 11: // xx // -x fromPnt = new IntVector2(i, j); toPnt = new IntVector2(i + 1, j + 1); break; case 7: // xx // x- fromPnt = new IntVector2(i, j + 1); toPnt = new IntVector2(i + 1, j); break; } if (fromPnt.defined) { if (vectorsReverse.Contains(fromPnt)) { VectorPixel oldVP = (VectorPixel)vectorsReverse[fromPnt]; if ((toPnt - fromPnt).extension(oldVP.toPnt - oldVP.fromPnt)) { vectors.Remove(oldVP.fromPnt); vectorsReverse.Remove(oldVP.toPnt); fromPnt = oldVP.fromPnt; } } if (vectors.Contains(toPnt)) { VectorPixel oldVP = (VectorPixel)vectors[toPnt]; if ((toPnt - fromPnt).extension(oldVP.toPnt - oldVP.fromPnt)) { vectors.Remove(oldVP.fromPnt); vectorsReverse.Remove(oldVP.toPnt); toPnt = oldVP.toPnt; } } if (!fromPnt.Equals(toPnt)) { // do not add null vectors, they ugly :/ VectorPixel newVP = new VectorPixel(fromPnt, toPnt); if (vectors.Contains(newVP.fromPnt)) throw new Exception("illegal edge configuration at pixel [" + newVP.fromPnt.x + ", " + newVP.fromPnt.y + "]"); else vectors.Add(newVP.fromPnt, newVP); if (vectorsReverse.Contains(newVP.toPnt)) throw new Exception("illegal edge configuration at pixel [" + newVP.toPnt.x + ", " + newVP.toPnt.y + "]"); else vectorsReverse.Add(newVP.toPnt, newVP); } } } return vectors; }
public DoubleVector2(IntVector2 v) { x = v.x; y = v.y; }
public bool extension(IntVector2 otherVector) { return(x * y == 0 && x * otherVector.y - y * otherVector.x == 0); // parallel to either axis AND colinear }