private void QuickHull()
        {
            Engine.hull.Clear();
            int min_x = 0, max_x = 0;

            for (int i = 1; i < Engine.points.Count; i++)
            {
                if (Engine.points[i].X < Engine.points[min_x].X)
                {
                    min_x = i;
                }
                if (Engine.points[i].X > Engine.points[max_x].X)
                {
                    max_x = i;
                }
            }
            Engine.hull.Add(Engine.points[min_x]);
            Engine.hull.Add(Engine.points[max_x]);
            Point A = Engine.hull[0];
            Point B = Engine.hull[1];


            {
                myGraphics.gfx.DrawLine(new Pen(Color.Purple), A.X, A.Y, B.X, B.Y);
            }

            List <Point> S1 = new List <Point>();
            List <Point> S2 = new List <Point>();


            foreach (Point point in Engine.points)
            {
                float side = Matematics.FindSide(A, B, point);
                if (side == -1)
                {
                    S1.Add(point);
                }
                side = Matematics.FindSide(B, A, point);
                if (side == -1)
                {
                    S2.Add(point);
                }
            }

            foreach (Point point in S1)
            {
                //point.fillColor = Color.Blue;
                point.fillColor = Color.FromArgb(rnd.Next(255), rnd.Next(255), rnd.Next(255));
                point.draw(myGraphics.gfx);
            }

            foreach (Point point in S2)
            {
                //point.fillColor = Color.Green;
                point.fillColor = Color.FromArgb(rnd.Next(255), rnd.Next(255), rnd.Next(255));
                point.draw(myGraphics.gfx);
            }
            FindHull(S1, A, B);
            FindHull(S2, B, A);
        }
예제 #2
0
        private bool IsPointInTriangle(Point P, Point A, Point B, Point C)
        {
            float areaOfTriangle = Math.Abs(Matematics.Area(A, B, C));
            float area_APB       = Math.Abs(Matematics.Area(A, P, B));
            float area_APC       = Math.Abs(Matematics.Area(A, P, C));
            float area_BPC       = Math.Abs(Matematics.Area(B, P, C));

            return(areaOfTriangle == area_APB + area_APC + area_BPC);
        }
예제 #3
0
        private void FindHull(List <Point> sk, Point P, Point Q)
        {
            if (sk.Count == 0)
            {
                return;
            }
            int farthestPointIndex = 0;

            float max_dist = 0;

            for (int i = 0; i < sk.Count; i++)
            {
                float dist = Matematics.lineDist(P, Q, sk[i]);
                if (dist > max_dist)
                {
                    max_dist           = dist;
                    farthestPointIndex = i;
                }
            }

            Point C   = sk[farthestPointIndex];
            int   idx = Engine.hull.IndexOf(P);

            Engine.hull.Insert(idx, C);


            List <Point> S1 = new List <Point>();
            List <Point> S2 = new List <Point>();

            foreach (Point point in Engine.points)
            {
                float side = Matematics.FindSide(P, C, point);
                if (side == -1)
                {
                    S1.Add(point);
                }
                side = Matematics.FindSide(C, Q, point);
                if (side == -1)
                {
                    S2.Add(point);
                }
            }


            FindHull(S1, P, C);
            FindHull(S2, C, Q);
        }
예제 #4
0
        private void DivideEtConquer()
        {
            Engine.hull.Clear();
            int min_x = 0, max_x = 0;

            for (int i = 1; i < Engine.points.Count; i++)
            {
                if (Engine.points[i].X < Engine.points[min_x].X)
                {
                    min_x = i;
                }
                if (Engine.points[i].X > Engine.points[max_x].X)
                {
                    max_x = i;
                }
            }
            Engine.hull.Add(Engine.points[min_x]);
            Engine.hull.Add(Engine.points[max_x]);
            Point A = Engine.hull[0];
            Point B = Engine.hull[1];

            List <Point> S1 = new List <Point>();
            List <Point> S2 = new List <Point>();


            foreach (Point point in Engine.points)
            {
                float side = Matematics.FindSide(A, B, point);
                if (side == -1)
                {
                    S1.Add(point);
                }
                side = Matematics.FindSide(B, A, point);
                if (side == -1)
                {
                    S2.Add(point);
                }
            }

            FindHull(S1, A, B);
            FindHull(S2, B, A);
        }
예제 #5
0
        private void button_Triangulate_Click(object sender, EventArgs e)
        {
            double area  = 0;
            int    count = Engine.points.Count;

            if (count < 3)
            {
                return;
            }
            if (count == 3)
            {
                area = Matematics.Area(Engine.points[0], Engine.points[1], Engine.points[2]); return;
            }

            List <Point> points    = Engine.points;// lista temporara
            List <int>   indexList = new List <int>();

            for (int i = 0; i < points.Count; i++)
            {
                indexList.Add(i); //initializarea listei de indecsi de la 0 pana la nr de puncte
            }

            Point A;
            Point B;
            Point C;

            while (indexList.Count > 3)
            {
                for (int i = 0; i < indexList.Count; i++)
                {
                    int a = indexList[i];              // the index of current Item
                    int b = GetItem(indexList, i - 1); // the index of leftside neighbour
                    int c = GetItem(indexList, i + 1); // the index of righside neighbour

                    A = points[a];
                    B = points[b];
                    C = points[c];

                    int clockwise = GetTurnType(A, B, C);
                    if (clockwise != -1)
                    {
                        continue;       // make a salt to next index
                    }
                    bool isEar = true;  //presupunem ca este o ureche valida daca este
                    for (int j = 0; j < points.Count; j++)
                    {
                        if (j == a || j == b || j == c)
                        {
                            continue; //excluding the current index and the neighbours from test
                        }

                        if (IsPointInTriangle(points[j], A, B, C))
                        {
                            isEar = false;
                            break;
                        }
                    }


                    if (isEar)
                    {
                        Engine.triangles.Add(new Triangle(A, B, C)); //add the triangle in the list, if is a valid ear.

                        indexList.RemoveAt(i);                       //remove the current index from the indexlist

                        //drawing the line to make a triangle visualy
                        Pen pen = new Pen(Color.Green);
                        myGraphics.gfx.DrawLine(pen, C.X, C.Y, B.X, B.Y);
                        myGraphics.refreshGraph();
                        break;
                    }
                }
            }


            //adding last 3 points what makes a triangle
            A = points[indexList[0]];
            B = points[indexList[1]];
            C = points[indexList[2]];
            Engine.triangles.Add(new Triangle(A, B, C));

            // calculate the polygon area using triangle's area.
            foreach (Triangle triangle in Engine.triangles)
            {
                area += Math.Abs(Matematics.Area(triangle.A, triangle.B, triangle.C));
            }



            points.Clear();
            indexList.Clear();

            output.Text = "Area:" + Environment.NewLine + area;
            status      = "triangulation completed";
        }