예제 #1
0
        public void update(VectorPixel v)
        {
            if (!fromPnt.defined)
            {
                fromPnt = v.fromPnt;
            }
            toPnt = v.toPnt;
            int d1;
            int d2;

            if (dx > dy)
            {
                d1 = dx;
                d2 = dy;
            }
            else
            {
                d1 = dy;
                d2 = dx;
            }
            maxleft  = Math.Max(maxleft, 1.0 * (d1 - 1) / d2);
            minright = Math.Min(minright, 1.0 * (d1 + 1) / d2);
            var dmin = maxleft * (d2 + 1) + 0.5 - d1;
            var dmax = minright * (d2 + 1) - 0.5 - d1;

            if (Math.Ceiling(dmin) - dmin == 0.5)
            {
                dmin += 0.5;
            }
            if (Math.Ceiling(dmax) - dmax == 0.5)
            {
                dmax -= 0.5;
            }
            if (dx > dy)
            {
                nextmindx = (int)Math.Round(dmin);
                nextmaxdx = (int)Math.Round(dmax);
                nextmindy = 0;
                nextmaxdy = 1;
            }
            else if (dx < dy)
            {
                nextmindx = 0;
                nextmaxdx = 1;
                nextmindy = (int)Math.Round(dmin);
                nextmaxdy = (int)Math.Round(dmax);
            }
            else
            {
                nextmindx = 0;
                nextmaxdx = 2;
                nextmindy = 0;
                nextmaxdy = 2;
            }
            //Console.WriteLine("({0}, {1}) - ({2}, {3})", outerFromPnt.x, outerFromPnt.y, toPnt.x, toPnt.y);
        }
예제 #2
0
 public Line(VectorPixel v)
 {
     maxleft      = double.MinValue;
     minright     = double.MaxValue;
     outerFromPnt = v.fromPnt;
     toPnt        = v.toPnt;
     nextmindx    = 0;
     nextmaxdx    = int.MaxValue;
     nextmindy    = 0;
     nextmaxdy    = int.MaxValue;
 }
예제 #3
0
 public bool satisfiesInner(VectorPixel v)
 {
     if (!fromPnt.defined)
     {
         return(Math.Abs(toPnt.x - outerFromPnt.x) == Math.Abs(toPnt.y - outerFromPnt.y)
             ? true
             : // anything goes
                Math.Abs(v.toPnt.x - toPnt.x) >= Math.Abs(v.fromPnt.x - outerFromPnt.x) &&
                Math.Abs(v.toPnt.y - toPnt.y) >= Math.Abs(v.fromPnt.y - outerFromPnt.y));
     }
     // inner segment must be >= the outer segment
     return
         (nextmindx <= Math.Abs(v.toPnt.x - toPnt.x) && Math.Abs(v.toPnt.x - toPnt.x) <= nextmaxdx &&
          nextmindy <= Math.Abs(v.toPnt.y - toPnt.y) && Math.Abs(v.toPnt.y - toPnt.y) <= nextmaxdy);
 }
예제 #4
0
 public bool sameDir(VectorPixel v)
 {
     if (v.linkVector())
     {
         return
             (Math.Abs(Math.Sign(toPnt.x - outerFromPnt.x) - (v.toPnt.x - toPnt.x)) <= 1 &&
              Math.Abs(Math.Sign(toPnt.y - outerFromPnt.y) - (v.toPnt.y - toPnt.y)) <= 1);
     }
     if (Math.Abs(toPnt.x - outerFromPnt.x) > Math.Abs(toPnt.y - outerFromPnt.y))
     {
         return
             (Math.Sign(toPnt.x - outerFromPnt.x) == Math.Sign(v.toPnt.x - toPnt.x) &&
              Math.Abs(Math.Sign(toPnt.y - outerFromPnt.y) - (v.toPnt.y - toPnt.y)) <= 1);
     }
     if (Math.Abs(toPnt.x - outerFromPnt.x) < Math.Abs(toPnt.y - outerFromPnt.y))
     {
         return
             (Math.Abs(Math.Sign(toPnt.x - outerFromPnt.x) - (v.toPnt.x - toPnt.x)) <= 1 &&
              Math.Sign(toPnt.y - outerFromPnt.y) == Math.Sign(v.toPnt.y - toPnt.y));
     }
     return
         (Math.Abs(Math.Sign(toPnt.x - outerFromPnt.x) - Math.Sign(v.toPnt.x - toPnt.x)) <= 1 &&
          Math.Abs(Math.Sign(toPnt.y - outerFromPnt.y) - Math.Sign(v.toPnt.y - toPnt.y)) <= 1);
 }
예제 #5
0
 public void update(VectorPixel v)
 {
     if (!fromPnt.defined)
         fromPnt = v.fromPnt;
     toPnt = v.toPnt;
     int d1;
     int d2;
     if (dx > dy) {
         d1 = dx;
         d2 = dy;
     } else {
         d1 = dy;
         d2 = dx;
     }
     maxleft = Math.Max(maxleft, 1.0 * (d1 - 1) / d2);
     minright = Math.Min(minright, 1.0 * (d1 + 1) / d2);
     double dmin = maxleft * (d2 + 1) + 0.5 - d1;
     double dmax = minright * (d2 + 1) - 0.5 - d1;
     if (Math.Ceiling(dmin) - dmin == 0.5)
         dmin += 0.5;
     if (Math.Ceiling(dmax) - dmax == 0.5)
         dmax -= 0.5;
     if (dx > dy) {
         nextmindx = (int)Math.Round(dmin);
         nextmaxdx = (int)Math.Round(dmax);
         nextmindy = 0;
         nextmaxdy = 1;
     } else
         if (dx < dy) {
         nextmindx = 0;
         nextmaxdx = 1;
         nextmindy = (int)Math.Round(dmin);
         nextmaxdy = (int)Math.Round(dmax);
     } else {
         nextmindx = 0;
         nextmaxdx = 2;
         nextmindy = 0;
         nextmaxdy = 2;
     }
     //Console.WriteLine("({0}, {1}) - ({2}, {3})", outerFromPnt.x, outerFromPnt.y, toPnt.x, toPnt.y);
 }
예제 #6
0
 public bool satisfiesOuter(VectorPixel v)
 {
     return
         Math.Abs(v.toPnt.x - toPnt.x) <= nextmaxdx &&
         Math.Abs(v.toPnt.y - toPnt.y) <= nextmaxdy; // outer segment must be shorter than inner segment
 }
예제 #7
0
 public bool satisfiesInner(VectorPixel v)
 {
     if (!fromPnt.defined)
         return Math.Abs(toPnt.x - outerFromPnt.x) == Math.Abs(toPnt.y - outerFromPnt.y) ?
             true : // anything goes
             Math.Abs(v.toPnt.x - toPnt.x) >= Math.Abs(v.fromPnt.x - outerFromPnt.x) &&
             Math.Abs(v.toPnt.y - toPnt.y) >= Math.Abs(v.fromPnt.y - outerFromPnt.y); // inner segment must be >= the outer segment
     return
         nextmindx <= Math.Abs(v.toPnt.x - toPnt.x) && Math.Abs(v.toPnt.x - toPnt.x) <= nextmaxdx &&
         nextmindy <= Math.Abs(v.toPnt.y - toPnt.y) && Math.Abs(v.toPnt.y - toPnt.y) <= nextmaxdy;
 }
예제 #8
0
 public bool sameDir(VectorPixel v)
 {
     if (v.linkVector())
         return
             Math.Abs(Math.Sign(toPnt.x - outerFromPnt.x) - (v.toPnt.x - toPnt.x)) <= 1 &&
             Math.Abs(Math.Sign(toPnt.y - outerFromPnt.y) - (v.toPnt.y - toPnt.y)) <= 1;
     if (Math.Abs(toPnt.x - outerFromPnt.x) > Math.Abs(toPnt.y - outerFromPnt.y))
         return
             Math.Sign(toPnt.x - outerFromPnt.x) == Math.Sign(v.toPnt.x - toPnt.x) &&
             Math.Abs(Math.Sign(toPnt.y - outerFromPnt.y) - (v.toPnt.y - toPnt.y)) <= 1;
     if (Math.Abs(toPnt.x - outerFromPnt.x) < Math.Abs(toPnt.y - outerFromPnt.y))
         return
             Math.Abs(Math.Sign(toPnt.x - outerFromPnt.x) - (v.toPnt.x - toPnt.x)) <= 1 &&
             Math.Sign(toPnt.y - outerFromPnt.y) == Math.Sign(v.toPnt.y - toPnt.y);
     return
         Math.Abs(Math.Sign(toPnt.x - outerFromPnt.x) - Math.Sign(v.toPnt.x - toPnt.x)) <= 1 &&
         Math.Abs(Math.Sign(toPnt.y - outerFromPnt.y) - Math.Sign(v.toPnt.y - toPnt.y)) <= 1;
 }
예제 #9
0
 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;
 }
예제 #10
0
 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);
 }
예제 #11
0
 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;
 }
예제 #12
0
        protected void saveAsBmp(string fileName)
        {
            if (polygons.Count == 0)
            {
                throw new Exception("there must be at least one polygon!");
            }
            var inPnt = new ArrayList[ymax - ymin + 1];

            for (var i = 0; i < inPnt.Length; i++)
            {
                inPnt[i] = new ArrayList(20);
            }
            for (var j = 0; j < polygons.Count; j++)
            {
                var vertices = (ArrayList)polygons[j];
                for (var i = 0; i < vertices.Count; i++)
                {
                    var vertex     = (DoubleVector2)vertices[i];
                    var vertexNext = i + 1 < vertices.Count
                        ? (DoubleVector2)vertices[i + 1]
                        : (DoubleVector2)vertices[0];
                    var pointFrom = new IntVector2((int)vertex.x - xmin, (int)vertex.y - ymin);
                    var pointTo   = new IntVector2((int)vertexNext.x - xmin, (int)vertexNext.y - ymin);
                    var vect      = new VectorPixel(pointFrom, pointTo);
                    if (vect.dy != 1)
                    {
                        IntVector2 pointNow;
                        for (var 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));
                        }
                    }
                }
            }
            var bmp     = new Bitmap(xmax - xmin + 3, ymax - ymin + 3, PixelFormat.Format32bppRgb);
            var bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly,
                                       bmp.PixelFormat);
            var stride   = bmpData.Stride;
            var startPtr = bmpData.Scan0.ToInt64();

            if (stride < 0)
            {
                startPtr += stride * (bmpData.Height - 1);
                stride    = Math.Abs(stride);
            }
            var rowBytes = new byte[bmpData.Stride];

            for (var i = 0; i < bmpData.Height; i++) // make everything black first
            {
                Marshal.Copy(new IntPtr(startPtr + stride * i), rowBytes, 0, bmpData.Stride);
            }
            for (var i = 0; i < bmpData.Stride; i++)
            {
                rowBytes[i] = 255;
            }
            for (var i = 0; i < inPnt.Length; i++)
            {
                inPnt[i].Sort();
                for (var j = 1; j < inPnt[i].Count; j++)
                {
                    var f     = (FromToInt)inPnt[i][j];
                    var fprev = (FromToInt)inPnt[i][j - 1];
                    if (f.sy > 0 && fprev.sy <= 0 && f.x - (fprev.x + 1) > 0) // insert empty space where appropriate
                    {
                        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);
        }
예제 #13
0
        public SortedList createVectors(byte[,] pixelOn, Bitmap bmp)
        {
            var vectors        = new SortedList(bmp.Width * bmp.Height / 32);
            var vectorsReverse = new Hashtable(bmp.Width * bmp.Height / 32);
            var steps          = 0;

            for (var j = 0; j < bmp.Height + 1; j++)
            {
                for (var i = 0; i < bmp.Width + 1; i++)
                {
                    printProgress(ref steps, 400000);
                    var 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 (var j = 0; j < bmp.Height; j++)
            {
                for (var i = 0; i < bmp.Width; i++)
                {
                    printProgress(ref steps, 800000);
                    if ((pixelOn[i + 1, j + 1] & 1) == 1)
                    {
                        var type1 =
                            (pixelOn[i + 1, j] & 1) +
                            (pixelOn[i + 1, j + 2] & 1);
                        var 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 (var j = -1; j < bmp.Height; j++)
            {
                for (var i = -1; i < bmp.Width; i++)
                {
                    printProgress(ref steps, 400000);
                    var 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);
                    var fromPnt = new IntVector2();
                    var 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))
                        {
                            var 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))
                        {
                            var 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 :/
                            var newVP = new VectorPixel(fromPnt, toPnt);
                            if (vectors.Contains(newVP.fromPnt))
                            {
                                throw new Exception("illegal edge configuration at pixel [" + newVP.fromPnt.x + ", " +
                                                    newVP.fromPnt.y + "]");
                            }
                            vectors.Add(newVP.fromPnt, newVP);
                            if (vectorsReverse.Contains(newVP.toPnt))
                            {
                                throw new Exception("illegal edge configuration at pixel [" + newVP.toPnt.x + ", " +
                                                    newVP.toPnt.y + "]");
                            }
                            vectorsReverse.Add(newVP.toPnt, newVP);
                        }
                    }
                }
            }
            return(vectors);
        }
예제 #14
0
        public void collapseVectors(SortedList vectors)
        {
            ArrayList vertices;
            var       steps = 0;

            while (vectors.Count > 0)
            {
                var vectorOld = (VectorPixel)vectors.GetByIndex(0);
                // ensures we begin at start/end of some line (as opposed to an inner segment)
                var         startPnt = vectorOld.fromPnt;
                VectorPixel vectorNow;
                VectorPixel vectorNew;
                VectorPixel vectorPrev = null;
                var         line       = new Line(vectorOld);
                vertices = new ArrayList(1000);
                do
                {
                    printProgress(ref steps, 2000);
                    vectorNow = (VectorPixel)vectors[vectorOld.toPnt];
                    vectorNew = (VectorPixel)vectors[vectorNow.toPnt];
                    if (!vectorNow.fromPnt.Equals(startPnt) && !vectorNow.toPnt.Equals(startPnt) &&
                        vectorNow.linkVector() && line.sameDir(vectorNow) && !vectorNew.linkVector() &&
                        line.sameDir(vectorNew))
                    {
                        if (line.satisfiesInner(vectorNew))
                        {
                            // new segment ok, let's try the next one
                            line.update(vectorNew);
                            vectors.Remove(vectorNow.fromPnt);
                            vectorOld = vectorNew;
                        }
                        else if (line.satisfiesOuter(vectorNew))
                        {
                            // vectorNow can be an outer segment
                            line.update(vectorNew);

                            vertices.Add(new DoubleVector2(line.toPnt));
                            vectors.Remove(vectorNew.fromPnt);
                            vectors.Remove(vectorNow.fromPnt);
                            vectorOld = (VectorPixel)vectors[vectorNew.toPnt];
                            line      = new Line(vectorOld);
                        }
                        else
                        {
                            // new segment off, but link is ok as an outer segment
                            line.update(vectorNow);
                            vertices.Add(new DoubleVector2(line.toPnt));
                            vectors.Remove(vectorNow.fromPnt);
                            vectorOld = vectorNew;
                            line      = new Line(vectorOld);
                        }
                    }
                    else if (!vectorNow.fromPnt.Equals(startPnt) && line.sameDir(vectorNow))
                    {
                        // vectorNow is not a simple link between two segments
                        if (line.satisfiesInner(vectorNow))
                        {
                            // new segment ok, let's try the next one
                            line.update(vectorNow);
                            vectorOld = vectorNow;
                        }
                        else if (line.satisfiesOuter(vectorNow))
                        {
                            // vectorNow can be an outer segment
                            line.update(vectorNow);
                            vertices.Add(new DoubleVector2(line.toPnt));
                            vectors.Remove(vectorNow.fromPnt);
                            vectorOld = vectorNew;
                            line      = new Line(vectorOld);
                        }
                        else
                        {
                            // vectorNow just won't fit - process it separately
                            vertices.Add(new DoubleVector2(line.toPnt));
                            vectorOld = vectorNow;
                            line      = new Line(vectorOld);
                        }
                    }
                    else
                    {
                        // vectorNow just won't fit - process it separately
                        vertices.Add(new DoubleVector2(line.toPnt));
                        vectorOld = vectorNow;
                        line      = new Line(vectorOld);
                    }
                    if (vectorPrev != null)
                    {
                        vectors.Remove(vectorPrev.fromPnt);
                    }
                    vectorPrev = vectorOld;
                } while (!vectorOld.fromPnt.Equals(startPnt));
                vectors.Remove(startPnt);
                vertices.TrimToSize();
                polygons.Add(vertices);
            }
        }
예제 #15
0
 public bool satisfiesOuter(VectorPixel v)
 {
     return
         (Math.Abs(v.toPnt.x - toPnt.x) <= nextmaxdx &&
          Math.Abs(v.toPnt.y - toPnt.y) <= nextmaxdy); // outer segment must be shorter than inner segment
 }