Ejemplo n.º 1
0
        public void Set(Scanline scan, bool newValue)
        {
            int x = scan.X;

            while (x < scan.X + scan.Length)
            {
                Set(x, scan.Y, newValue);
                ++x;
            }
        }
Ejemplo n.º 2
0
        public void Invert(Scanline scan)
        {
            int x = scan.X;

            while (x < scan.X + scan.Length)
            {
                Invert(x, scan.Y);
                ++x;
            }
        }
Ejemplo n.º 3
0
 public override bool Equals(object?obj)
 {
     if (obj is Scanline)
     {
         Scanline rhs = (Scanline)obj;
         return(x == rhs.x && y == rhs.y && length == rhs.length);
     }
     else
     {
         return(false);
     }
 }
Ejemplo n.º 4
0
        public static Scanline[] GetScans(this Point[] points)
        {
            int ymax = 0;

            // Build edge table
            Edge[] edgeTable = new Edge[points.Length];
            int edgeCount = 0;

            for (int i = 0; i < points.Length; ++i) {
                Point top = points[i];
                Point bottom = points[(i + 1) % points.Length];
                int dy;

                if (top.Y > bottom.Y) {
                    Point temp = top;
                    top = bottom;
                    bottom = temp;
                }

                dy = bottom.Y - top.Y;

                if (dy != 0) {
                    edgeTable[edgeCount] = new Edge (top.Y, bottom.Y, top.X << 8, (((bottom.X - top.X) << 8) / dy));
                    ymax = Math.Max (ymax, bottom.Y);
                    ++edgeCount;
                }
            }

            // Sort edge table by miny
            for (int i = 0; i < edgeCount - 1; ++i) {
                int min = i;

                for (int j = i + 1; j < edgeCount; ++j)
                    if (edgeTable[j].miny < edgeTable[min].miny)
                        min = j;

                if (min != i) {
                    Edge temp = edgeTable[min];
                    edgeTable[min] = edgeTable[i];
                    edgeTable[i] = temp;
                }
            }

            // Compute how many scanlines we will be emitting
            int scanCount = 0;
            int activeLow = 0;
            int activeHigh = 0;
            int yscan1 = edgeTable[0].miny;

            // we assume that edgeTable[0].miny == yscan
            while (activeHigh < edgeCount - 1 &&
                   edgeTable[activeHigh + 1].miny == yscan1) {
                ++activeHigh;
            }

            while (yscan1 <= ymax) {
                // Find new edges where yscan == miny
                while (activeHigh < edgeCount - 1 &&
                       edgeTable[activeHigh + 1].miny == yscan1) {
                    ++activeHigh;
                }

                int count = 0;
                for (int i = activeLow; i <= activeHigh; ++i) {
                    if (edgeTable[i].maxy > yscan1) {
                        ++count;
                    }
                }

                scanCount += count / 2;
                ++yscan1;

                // Remove edges where yscan == maxy
                while (activeLow < edgeCount - 1 &&
                       edgeTable[activeLow].maxy <= yscan1) {
                    ++activeLow;
                }

                if (activeLow > activeHigh)
                    activeHigh = activeLow;
            }

            // Allocate scanlines that we'll return
            Scanline[] scans = new Scanline[scanCount];

            // Active Edge Table (AET): it is indices into the Edge Table (ET)
            int[] active = new int[edgeCount];
            int activeCount = 0;
            int yscan2 = edgeTable[0].miny;
            int scansIndex = 0;

            // Repeat until both the ET and AET are empty
            while (yscan2 <= ymax) {
                // Move any edges from the ET to the AET where yscan == miny
                for (int i = 0; i < edgeCount; ++i) {
                    if (edgeTable[i].miny == yscan2) {
                        active[activeCount] = i;
                        ++activeCount;
                    }
                }

                // Sort the AET on x
                for (int i = 0; i < activeCount - 1; ++i) {
                    int min = i;

                    for (int j = i + 1; j < activeCount; ++j)
                        if (edgeTable[active[j]].x < edgeTable[active[min]].x)
                            min = j;

                    if (min != i) {
                        int temp = active[min];
                        active[min] = active[i];
                        active[i] = temp;
                    }
                }

                // For each pair of entries in the AET, fill in pixels between their info
                for (int i = 0; i < activeCount; i += 2) {
                    Edge el = edgeTable[active[i]];
                    Edge er = edgeTable[active[i + 1]];
                    int startx = (el.x + 0xff) >> 8; // ceil(x)
                    int endx = er.x >> 8;      // floor(x)

                    scans[scansIndex] = new Scanline (startx, yscan2, endx - startx);
                    ++scansIndex;
                }

                ++yscan2;

                // Remove from the AET any edge where yscan == maxy
                int k = 0;
                while (k < activeCount && activeCount > 0) {
                    if (edgeTable[active[k]].maxy == yscan2) {
                        // remove by shifting everything down one
                        for (int j = k + 1; j < activeCount; ++j)
                            active[j - 1] = active[j];

                        --activeCount;
                    } else {
                        ++k;
                    }
                }

                // Update x for each entry in AET
                for (int i = 0; i < activeCount; ++i)
                    edgeTable[active[i]].x += edgeTable[active[i]].dxdy;
            }

            return scans;
        }
Ejemplo n.º 5
0
        public static Scanline[] GetScans(this Point[] points)
        {
            int ymax = 0;

            // Build edge table
            Edge[] edgeTable = new Edge[points.Length];
            int    edgeCount = 0;

            for (int i = 0; i < points.Length; ++i)
            {
                Point top    = points[i];
                Point bottom = points[(i + 1) % points.Length];
                int   dy;

                if (top.Y > bottom.Y)
                {
                    Point temp = top;
                    top    = bottom;
                    bottom = temp;
                }

                dy = bottom.Y - top.Y;

                if (dy != 0)
                {
                    edgeTable[edgeCount] = new Edge(top.Y, bottom.Y, top.X << 8, (((bottom.X - top.X) << 8) / dy));
                    ymax = Math.Max(ymax, bottom.Y);
                    ++edgeCount;
                }
            }

            // Sort edge table by miny
            for (int i = 0; i < edgeCount - 1; ++i)
            {
                int min = i;

                for (int j = i + 1; j < edgeCount; ++j)
                {
                    if (edgeTable[j].miny < edgeTable[min].miny)
                    {
                        min = j;
                    }
                }

                if (min != i)
                {
                    Edge temp = edgeTable[min];
                    edgeTable[min] = edgeTable[i];
                    edgeTable[i]   = temp;
                }
            }

            // Compute how many scanlines we will be emitting
            int scanCount  = 0;
            int activeLow  = 0;
            int activeHigh = 0;
            int yscan1     = edgeTable[0].miny;

            // we assume that edgeTable[0].miny == yscan
            while (activeHigh < edgeCount - 1 &&
                   edgeTable[activeHigh + 1].miny == yscan1)
            {
                ++activeHigh;
            }

            while (yscan1 <= ymax)
            {
                // Find new edges where yscan == miny
                while (activeHigh < edgeCount - 1 &&
                       edgeTable[activeHigh + 1].miny == yscan1)
                {
                    ++activeHigh;
                }

                int count = 0;
                for (int i = activeLow; i <= activeHigh; ++i)
                {
                    if (edgeTable[i].maxy > yscan1)
                    {
                        ++count;
                    }
                }

                scanCount += count / 2;
                ++yscan1;

                // Remove edges where yscan == maxy
                while (activeLow < edgeCount - 1 &&
                       edgeTable[activeLow].maxy <= yscan1)
                {
                    ++activeLow;
                }

                if (activeLow > activeHigh)
                {
                    activeHigh = activeLow;
                }
            }

            // Allocate scanlines that we'll return
            Scanline[] scans = new Scanline[scanCount];

            // Active Edge Table (AET): it is indices into the Edge Table (ET)
            int[] active      = new int[edgeCount];
            int   activeCount = 0;
            int   yscan2      = edgeTable[0].miny;
            int   scansIndex  = 0;

            // Repeat until both the ET and AET are empty
            while (yscan2 <= ymax)
            {
                // Move any edges from the ET to the AET where yscan == miny
                for (int i = 0; i < edgeCount; ++i)
                {
                    if (edgeTable[i].miny == yscan2)
                    {
                        active[activeCount] = i;
                        ++activeCount;
                    }
                }

                // Sort the AET on x
                for (int i = 0; i < activeCount - 1; ++i)
                {
                    int min = i;

                    for (int j = i + 1; j < activeCount; ++j)
                    {
                        if (edgeTable[active[j]].x < edgeTable[active[min]].x)
                        {
                            min = j;
                        }
                    }

                    if (min != i)
                    {
                        int temp = active[min];
                        active[min] = active[i];
                        active[i]   = temp;
                    }
                }

                // For each pair of entries in the AET, fill in pixels between their info
                for (int i = 0; i < activeCount; i += 2)
                {
                    Edge el     = edgeTable[active[i]];
                    Edge er     = edgeTable[active[i + 1]];
                    int  startx = (el.x + 0xff) >> 8;              // ceil(x)
                    int  endx   = er.x >> 8;                       // floor(x)

                    scans[scansIndex] = new Scanline(startx, yscan2, endx - startx);
                    ++scansIndex;
                }

                ++yscan2;

                // Remove from the AET any edge where yscan == maxy
                int k = 0;
                while (k < activeCount && activeCount > 0)
                {
                    if (edgeTable[active[k]].maxy == yscan2)
                    {
                        // remove by shifting everything down one
                        for (int j = k + 1; j < activeCount; ++j)
                        {
                            active[j - 1] = active[j];
                        }

                        --activeCount;
                    }
                    else
                    {
                        ++k;
                    }
                }

                // Update x for each entry in AET
                for (int i = 0; i < activeCount; ++i)
                {
                    edgeTable[active[i]].x += edgeTable[active[i]].dxdy;
                }
            }

            return(scans);
        }
Ejemplo n.º 6
0
        public void Set(Scanline scan, bool newValue)
        {
            int x = scan.X;

            while (x < scan.X + scan.Length)
            {
                Set(x, scan.Y, newValue);
                ++x;
            }
        }
Ejemplo n.º 7
0
        public void Invert(Scanline scan)
        {
            int x = scan.X;

            while (x < scan.X + scan.Length)
            {
                Invert(x, scan.Y);
                ++x;
            }
        }