コード例 #1
0
        private com.epl.geometry.SimpleRasterizer.Edge SortAET_(com.epl.geometry.SimpleRasterizer.Edge aet)
        {
            int num = 0;

            for (com.epl.geometry.SimpleRasterizer.Edge e = aet; e != null; e = e.next)
            {
                num++;
            }
            sortedNum_ = num;
            if (num == 1)
            {
                return(aet);
            }
            if (sortBuffer_ == null)
            {
                sortBuffer_ = new com.epl.geometry.SimpleRasterizer.Edge[System.Math.Max(num, 16)];
            }
            else
            {
                if (sortBuffer_.Length < num)
                {
                    sortBuffer_ = new com.epl.geometry.SimpleRasterizer.Edge[System.Math.Max(num, sortBuffer_.Length * 2)];
                }
            }
            {
                int i = 0;
                for (com.epl.geometry.SimpleRasterizer.Edge e_1 = aet; e_1 != null; e_1 = e_1.next)
                {
                    sortBuffer_[i++] = e_1;
                }
            }
            if (num == 2)
            {
                if (sortBuffer_[0].x > sortBuffer_[1].x)
                {
                    com.epl.geometry.SimpleRasterizer.Edge tmp = sortBuffer_[0];
                    sortBuffer_[0] = sortBuffer_[1];
                    sortBuffer_[1] = tmp;
                }
            }
            else
            {
                System.Array.Sort(sortBuffer_, 0, num, edgeCompare_);
            }
            aet            = sortBuffer_[0];
            sortBuffer_[0] = null;
            com.epl.geometry.SimpleRasterizer.Edge prev = aet;
            for (int i_1 = 1; i_1 < num; i_1++)
            {
                prev.next        = sortBuffer_[i_1];
                prev             = sortBuffer_[i_1];
                sortBuffer_[i_1] = null;
            }
            prev.next = null;
            return(aet);
        }
コード例 #2
0
 private void AddNewEdgesToAET_(int y)
 {
     if (y >= height_)
     {
         return;
     }
     com.epl.geometry.SimpleRasterizer.Edge edgesOnLine = ySortedEdges_[y];
     if (edgesOnLine != null)
     {
         ySortedEdges_[y] = null;
         edgesOnLine      = SortAET_(edgesOnLine);
         //sort new edges
         numEdges_ -= sortedNum_;
         //set in the sortAET
         // merge the edges with sorted AET - O(n) operation
         com.epl.geometry.SimpleRasterizer.Edge aet = activeEdgesTable_;
         bool first = true;
         com.epl.geometry.SimpleRasterizer.Edge newEdge  = edgesOnLine;
         com.epl.geometry.SimpleRasterizer.Edge prev_aet = null;
         while (aet != null && newEdge != null)
         {
             if (aet.x > newEdge.x)
             {
                 if (first)
                 {
                     activeEdgesTable_ = newEdge;
                 }
                 com.epl.geometry.SimpleRasterizer.Edge p = newEdge.next;
                 newEdge.next = aet;
                 if (prev_aet != null)
                 {
                     prev_aet.next = newEdge;
                 }
                 prev_aet = newEdge;
                 newEdge  = p;
             }
             else
             {
                 // aet.x <= newEdges.x
                 com.epl.geometry.SimpleRasterizer.Edge p = aet.next;
                 aet.next = newEdge;
                 if (prev_aet != null)
                 {
                     prev_aet.next = aet;
                 }
                 prev_aet = aet;
                 aet      = p;
             }
             first = false;
         }
         if (activeEdgesTable_ == null)
         {
             activeEdgesTable_ = edgesOnLine;
         }
     }
 }
コード例 #3
0
        private void EmitScans_()
        {
            if (activeEdgesTable_ == null)
            {
                return;
            }
            int w = 0;

            com.epl.geometry.SimpleRasterizer.Edge e0 = activeEdgesTable_;
            int x0 = (int)(e0.x >> 32);

            for (com.epl.geometry.SimpleRasterizer.Edge e = e0.next; e != null; e = e.next)
            {
                if (evenOdd_)
                {
                    w ^= 1;
                }
                else
                {
                    w += e.dir;
                }
                if (e.x > e0.x)
                {
                    int x = (int)(e.x >> 32);
                    if (w != 0)
                    {
                        int xx0 = Snap_(x0, 0, width_);
                        int xx  = Snap_(x, 0, width_);
                        if (xx > xx0 && xx0 < width_)
                        {
                            scanBuffer_[scanPtr_++] = xx0;
                            scanBuffer_[scanPtr_++] = xx;
                            scanBuffer_[scanPtr_++] = e.y;
                            if (scanPtr_ == scanBuffer_.Length)
                            {
                                callback_.DrawScan(scanBuffer_, scanPtr_);
                                scanPtr_ = 0;
                            }
                        }
                    }
                    e0 = e;
                    x0 = x;
                }
            }
        }
コード例 #4
0
 /// <summary>Call before starting the edges.</summary>
 /// <remarks>
 /// Call before starting the edges.
 /// For example to render two polygons that consist of a single ring:
 /// startAddingEdges();
 /// addRing(...);
 /// renderEdges(Rasterizer.EVEN_ODD);
 /// addRing(...);
 /// renderEdges(Rasterizer.EVEN_ODD);
 /// For example to render a polygon consisting of three rings:
 /// startAddingEdges();
 /// addRing(...);
 /// addRing(...);
 /// addRing(...);
 /// renderEdges(Rasterizer.EVEN_ODD);
 /// </remarks>
 public void StartAddingEdges()
 {
     if (numEdges_ > 0)
     {
         for (int i = 0; i < height_; i++)
         {
             for (com.epl.geometry.SimpleRasterizer.Edge e = ySortedEdges_[i]; e != null;)
             {
                 com.epl.geometry.SimpleRasterizer.Edge p = e;
                 e      = e.next;
                 p.next = null;
             }
             ySortedEdges_[i] = null;
         }
         activeEdgesTable_ = null;
     }
     minY_     = height_;
     maxY_     = -1;
     numEdges_ = 0;
 }
コード例 #5
0
        private void AdvanceAET_()
        {
            if (activeEdgesTable_ == null)
            {
                return;
            }
            bool needSort = false;

            com.epl.geometry.SimpleRasterizer.Edge prev = null;
            for (com.epl.geometry.SimpleRasterizer.Edge e = activeEdgesTable_; e != null;)
            {
                e.y++;
                if (e.y == e.ymax)
                {
                    com.epl.geometry.SimpleRasterizer.Edge p = e;
                    e = e.next;
                    if (prev != null)
                    {
                        prev.next = e;
                    }
                    else
                    {
                        activeEdgesTable_ = e;
                    }
                    p.next = null;
                    continue;
                }
                e.x += e.dxdy;
                if (prev != null && prev.x > e.x)
                {
                    needSort = true;
                }
                prev = e;
                e    = e.next;
            }
            if (needSort)
            {
                //resort to fix the order
                activeEdgesTable_ = SortAET_(activeEdgesTable_);
            }
        }
コード例 #6
0
        //reset for new edges
        /// <summary>Add a single edge.</summary>
        /// <param name="x1"/>
        /// <param name="y1"/>
        /// <param name="x2"/>
        /// <param name="y2"/>
        public void AddEdge(double x1, double y1, double x2, double y2)
        {
            if (y1 == y2)
            {
                return;
            }
            int dir = 1;

            if (y1 > y2)
            {
                double temp;
                temp = x1;
                x1   = x2;
                x2   = temp;
                temp = y1;
                y1   = y2;
                y2   = temp;
                dir  = -1;
            }
            if (y2 < 0 || y1 >= height_)
            {
                return;
            }
            if (x1 < 0 && x2 < 0)
            {
                x1 = -1;
                x2 = -1;
            }
            else
            {
                if (x1 >= width_ && x2 >= width_)
                {
                    x1 = width_;
                    x2 = width_;
                }
            }
            //clip to extent
            double dxdy = (x2 - x1) / (y2 - y1);

            if (y2 > height_)
            {
                y2 = height_;
                x2 = dxdy * (y2 - y1) + x1;
            }
            if (y1 < 0)
            {
                x1 = dxdy * (0 - y1) + x1;
                y1 = 0;
            }
            //do not clip x unless it is too small or too big
            int bigX = System.Math.Max(width_ + 1, unchecked ((int)(0x7fffff)));

            if (x1 < -unchecked ((int)(0x7fffff)))
            {
                //from earlier logic, x2 >= -1, therefore dxdy is not 0
                y1 = (0 - x1) / dxdy + y1;
                x1 = 0;
            }
            else
            {
                if (x1 > bigX)
                {
                    //from earlier logic, x2 <= width_, therefore dxdy is not 0
                    y1 = (width_ - x1) / dxdy + y1;
                    x1 = width_;
                }
            }
            if (x2 < -unchecked ((int)(0x7fffff)))
            {
                //from earlier logic, x1 >= -1, therefore dxdy is not 0
                y2 = (0 - x1) / dxdy + y1;
                x2 = 0;
            }
            else
            {
                if (x2 > bigX)
                {
                    //from earlier logic, x1 <= width_, therefore dxdy is not 0
                    y2 = (width_ - x1) / dxdy + y1;
                    x2 = width_;
                }
            }
            int ystart = (int)y1;
            int yend   = (int)y2;

            if (ystart == yend)
            {
                return;
            }
            com.epl.geometry.SimpleRasterizer.Edge e = new com.epl.geometry.SimpleRasterizer.Edge();
            e.x    = (long)(x1 * 4294967296.0);
            e.y    = ystart;
            e.ymax = yend;
            e.dxdy = (long)(dxdy * 4294967296.0);
            e.dir  = dir;
            if (ySortedEdges_ == null)
            {
                ySortedEdges_ = new com.epl.geometry.SimpleRasterizer.Edge[height_];
            }
            e.next             = ySortedEdges_[e.y];
            ySortedEdges_[e.y] = e;
            if (e.y < minY_)
            {
                minY_ = e.y;
            }
            if (e.ymax > maxY_)
            {
                maxY_ = e.ymax;
            }
            numEdges_++;
        }