Esempio n. 1
0
        private void VertexToEdge(ref List <AEL> Edges, List <Point> Vertex, out int ymin, out int ymax)
        {
            AEL temp;

            ymin = Vertex[0].Y;
            ymax = Vertex[0].Y;
            Vertex.Add(Vertex[0]);
            Vertex.Add(Vertex[1]);
            Vertex.Insert(0, Vertex[Vertex.Count - 3]);

            for (int i = 1; i <= Vertex.Count - 3; i++)
            {
                temp        = new AEL();
                temp.yUpper = Math.Max(Vertex[i].Y, Vertex[i + 1].Y);
                temp.yLower = Math.Min(Vertex[i].Y, Vertex[i + 1].Y);
                if (Vertex[i].Y > Vertex[i + 1].Y)
                {
                    temp.xIntersect = Vertex[i + 1].X;
                }
                else
                {
                    temp.xIntersect = Vertex[i].X;
                }

                if (temp.yLower == temp.yUpper)
                {
                    temp.reciSlope = 0;
                }
                else
                {
                    temp.reciSlope = (Vertex[i].X - Vertex[i + 1].X) * 1.0 / (Vertex[i].Y - Vertex[i + 1].Y) * 1.0;
                }


                //Trường hợp điểm giao nhau không phải là cực trị
                if (Vertex[i + 1].Y < Vertex[i].Y && Vertex[i].Y < Vertex[i - 1].Y)
                {
                    temp.yUpper--;
                }
                else
                if (Vertex[i + 2].Y > Vertex[i + 1].Y && Vertex[i + 1].Y > Vertex[i].Y)
                {
                    temp.yUpper--;
                }

                Edges.Add(temp);
                ymin = Math.Min(ymin, Vertex[i + 1].Y);
                ymax = Math.Max(ymax, Vertex[i + 1].Y);
            }
            Vertex.RemoveAt(0);
            Vertex.RemoveAt(Vertex.Count - 1);
            Vertex.RemoveAt(Vertex.Count - 1);
        }
Esempio n. 2
0
        public double ScanFill(Shape shape, Color fillColor)
        {
            Stopwatch stopWatch = new Stopwatch();

            stopWatch.Start();
            TimeSpan ts;

            shape.fillType = FillType.SCANLINE;
            int yMin, yMax;

            if (shape.type == ShapeType.CIRCLE || shape.type == ShapeType.ELLIPSE)
            {
                List <Point> fillVertex = new List <Point>();
                fillVertex.AddRange(shape.vertexs);

                yMin = fillVertex[0].Y;
                yMax = yMin;
                foreach (var v in fillVertex)
                {
                    if (v.Y > yMax)
                    {
                        yMax = v.Y;
                    }
                    if (v.Y < yMin)
                    {
                        yMin = v.Y;
                    }
                }

                for (int y = yMin; y <= yMax; y++)
                {
                    List <Point> line = new List <Point>();
                    line.AddRange(fillVertex.Where(v => v.Y == y));
                    line = line.OrderBy(v => v.X).ToList();

                    int xmin = -1, xmax = -1;
                    for (int i = 0; i < line.Count - 1; i++)
                    {
                        if (Math.Abs(line[i].X - line[i + 1].X) > 1)
                        {
                            xmin = line[i].X;
                            xmax = line[i + 1].X;
                            break;
                        }
                    }

                    if (xmax < 0)
                    {
                        continue;
                    }

                    gl.Color(fillColor.R / 255.0, fillColor.G / 255.0, fillColor.B / 255.0);
                    gl.Begin(OpenGL.GL_LINES);
                    gl.Vertex(xmin, y);
                    gl.Vertex(xmax, y);
                    gl.End();
                }
                gl.Flush();
                shape.Draw(gl);

                stopWatch.Stop();
                ts = stopWatch.Elapsed;

                return(ts.TotalMilliseconds);
            }
            List <List <AEL> > edgeTable = new List <List <AEL> >();
            List <AEL>         begList   = new List <AEL>();
            List <AEL>         edges     = new List <AEL>();


            VertexToEdge(ref edges, shape.vertexs, out yMin, out yMax);


            //Tạo Edge Table
            for (int y = yMin; y <= yMax; y++)
            {
                List <AEL> subList = new List <AEL>();
                edgeTable.Add(subList);
            }

            for (int i = 0; i < edges.Count; i++)
            {
                if (edges[i].yLower != edges[i].yUpper)
                {
                    int id = edges[i].yLower - yMin;
                    edgeTable[id].Add(edges[i]);
                }
            }

            for (int y = yMin; y <= yMax; y++)
            {
                begList.AddRange(edgeTable[y - yMin]);

                //Sắp xếp các giao điểm theo x
                begList = begList.OrderBy(v => v.xIntersect).ToList();

                //Tô màu cho dòng hiện tại
                if (y != yMin && y != yMax)
                {
                    gl.Color(fillColor.R / 255.0, fillColor.G / 255.0, fillColor.B / 255.0);
                    gl.Begin(OpenGL.GL_LINES);
                    for (int i = 0; i < begList.Count; i += 2)
                    {
                        if (i + 1 < begList.Count)
                        {
                            gl.Vertex(begList[i].xIntersect, y);
                            gl.Vertex(begList[i + 1].xIntersect, y);
                        }
                    }
                    gl.End();
                }
                gl.Flush();

                //Xoá các cạnh đã ở dưới scan line
                int j = 0;
                while (j < begList.Count)
                {
                    if (begList[j].yUpper == y)
                    {
                        begList.RemoveAt(j);
                    }
                    else
                    {
                        j++;
                    }
                }


                for (int i = 0; i < begList.Count; i++)
                {
                    AEL t = new AEL();
                    t.reciSlope  = begList[i].reciSlope;
                    t.yLower     = begList[i].yLower;
                    t.yUpper     = begList[i].yUpper;
                    t.xIntersect = begList[i].xIntersect + begList[i].reciSlope;
                    begList[i]   = t;
                }
            }
            shape.Draw(gl);

            stopWatch.Stop();
            ts = stopWatch.Elapsed;
            return(ts.TotalMilliseconds);
        }