Как определить полигон треугольника в wpf - PullRequest
0 голосов
/ 30 августа 2018

У меня 'n' количество полигонов, как показано ниже.

    <Polygon Points="544,245,544,175,568,175,568,175" Stroke="Black" StrokeThickness="1" />
    <Polygon Points="2,223,96,223,96,153,96,153" Stroke="Black" StrokeThickness="1" />
    <Polygon Points="350,315,350,333,306,333,306,395,306,395" Stroke="Black" StrokeThickness="1" />
    <Polygon Points="164,53,160,53,160,51,160,55,160,55" Stroke="Black" StrokeThickness="1" />
    <Polygon Points="264,63,264,58,264,68,264,63,267,63,267,60,267,66,267,63,270,63,270,58,270,68,270,68" Stroke="Black" StrokeThickness="1" />
    <Polygon Points="8,63,444,63,444,168,444,168" Stroke="Black" StrokeThickness="1" />
    <Polygon Points="212,169,212,93,285,93,285,63,285,63" Stroke="Black" StrokeThickness="1" />
    <Polygon Points="26,93,127,93,127,148,29,148,29,148" Stroke="Black" StrokeThickness="1" />
    <Polygon Points="152,116,152,132,212,132,212,132" Stroke="Black" StrokeThickness="1" />
    <Polygon Points="121,316,121,333,70,333,70,366,70,366" Stroke="Black" StrokeThickness="1" />
    <Polygon Points="464,395,488,395,488,284,527,284,527,284" Stroke="Black" StrokeThickness="1" />
    <Polygon Points="168,63,168,67,180,59,180,67,168,59,168,59" Stroke="Black" StrokeThickness="1" />
    <Polygon Points="173,62,173,56,165,56,165,51,175,51,175,61,175,61" Stroke="Black" StrokeThickness="1" />
    <Polygon Points="3,285,121,285,121,316,211,316,211,304,211,304" Stroke="Black" StrokeThickness="1" />

Пожалуйста, помогите мне определить, какие треугольники в этих многоугольниках

Я попытался определить вершины, как показано ниже.

        Polygon polygon = new Polygon();
        polygon.Points = new System.Windows.Media.PointCollection()
        {
            new Point(446,134),
            new Point(442,134),
            new Point(444,140),
            new Point(444,140),
        }; 

        List<double> verticesPoints = new List<double>();
        for (int i = 0; i < polygon.Points.Count - 1; i++)
        {
            var point1 = polygon.Points[i];
            var point2 = polygon.Points[i + 1];

            //calculate delta x and delta y between the two points
            var deltaX = Math.Pow((point2.X - point1.X), 2);
            var deltaY = Math.Pow((point2.Y - point1.Y), 2);

            //pythagras theorem for distance
            var distance = Math.Sqrt(deltaY + deltaX);

            //distance is zero..then same point
            if (distance != 0)
            {
                verticesPoints.Add(distance);
            }
        }
       ///Here is the code to calculate angle and consider the triangle
       ///three vertices then it might be triangle.
        if (verticesPoints.Count == 3)
        {
            ///use The Law of Cosines
            ///cos(C) = a2 + b2 − c2 /2ab
            ///cos(A) = b2 + c2 − a2 /bc
            ///cos(B) = c2 + a2 − b2 /ca
            var a = ((Math.Pow(verticesPoints[1], 2)) + (Math.Pow(verticesPoints[2], 2)) - (Math.Pow(verticesPoints[0], 2)))
                      / (2 * verticesPoints[1] * verticesPoints[2]);

            var b = ((Math.Pow(verticesPoints[0], 2)) + (Math.Pow(verticesPoints[2], 2)) - (Math.Pow(verticesPoints[1], 2)))
                     / (2 * verticesPoints[0] * verticesPoints[2]);

            var c = ((Math.Pow(verticesPoints[0], 2)) + (Math.Pow(verticesPoints[1], 2)) - (Math.Pow(verticesPoints[2], 2)))
                     / (2 * verticesPoints[0] * verticesPoints[1]);

            ///Inverse of cos
            var radians1 = Math.Acos(a);
            ///Convert radian to degree
            double degrees1 = (radians1 * 180.0) / Math.PI;

            ///Inverse of cos
            var radians2 = Math.Acos(b);
            //Convert radian to degree
            double degrees2 = (radians2 * 180.0) / Math.PI;

            ///Inverse of cos
            var radians3 = Math.Acos(c);
            ///Convert radian to degree
            double degrees3 = (radians3 * 180.0) / Math.PI;

            var totalDegrees = degrees1 + degrees2 + degrees3;
            if (totalDegrees == 180)
            {
               // Consider triangle
            }
        }

Но приведенный выше код не работает для <Polygon Points="446,134,442,134,444,140,444,140" Stroke="Black" StrokeThickness="1" />, он дает только две вершины, но это треугольник, а в некоторых сценариях получается 3 вершины, но totalDegrees не равен 180

Ответы [ 2 ]

0 голосов
/ 04 декабря 2018

Я решил вышеупомянутую проблему, используя "AForge.NET"

        Polygon polygon = new Polygon();
        polygon.Points = new PointCollection()
        {
             new Point(446,134),
             new Point(442,134),
             new Point(444,140),
             new Point(444,140),
        };

        SimpleShapeChecker shapeChecker = new  SimpleShapeChecker();
        List<IntPoint> edgePoints = new List<IntPoint>();
        List<IntPoint> corners;
        for (int i = 0; i <= polygon.Points.Count - 1; i++)
        {
            edgePoints.Add(new IntPoint((int)polygon.Points[i].X, (int)polygon.Points[i].Y));
        }

        shapeChecker.MinAcceptableDistortion = 0.2f;
        shapeChecker.LengthError = 0;
        shapeChecker.AngleError = 5;
        shapeChecker.RelativeDistortionLimit = 0;

        if (shapeChecker.IsTriangle(edgePoints, out corners))
        {
            //shape is triangle
        }

Необходимо добавить ниже пространство имен

using AForge;
using AForge.Math.Geometry;

Ссылка: http://aforgenet.com/articles/shape_checker/

0 голосов
/ 30 августа 2018

Этот код здесь перебирает точки и вычисляет градиент между каждой из них. Если градиент одинаков для двух последовательных точек, они должны быть одной и той же линией, поэтому noOfPoints не увеличивается, иначе увеличивается.

Первый градиент сохраняется в firstGradient, чтобы проверить, совпадает ли градиент, соединяющий последнюю и первую точку, с градиентом между первой и второй точкой.

        Polygon polygon = new Polygon();
        polygon.Points = new System.Windows.Media.PointCollection()
    {
        new Point(446,134),
        new Point(442,134),
        new Point(444,140),
        new Point(444,140),
    };

        List<double> verticesPoints = new List<double>();
        double? firstGradient = null;
        double? gradient = null;
        double? newGradient = null;
        int noOfSides = 1;

        for (int i = 0; i < polygon.Points.Count - 1; i++)
        {
            var point1 = polygon.Points[i];
            var point2 = polygon.Points[i + 1];

            if(point1 == point2) { continue;}

            //calculate delta x and delta y between the two points
            var deltaX = point2.X - point1.X;
            var deltaY = point2.Y - point1.Y;

            //calculate gradient
            newGradient = (deltaY / deltaX);

            if (i == 0)
            {
                firstGradient = newGradient;
            }

            if ((gradient != newGradient) && (i != polygon.Points.Count - 2))
            {
                noOfSides++;
            }
            else if (i == polygon.Points.Count - 2)
            {
                if ((gradient != newGradient) && (firstGradient != newGradient)) //This now checks the gradient between the last and first point.
                {

                    point1 = polygon.Points[i+1];
                    point2 = polygon.Points[0];

                    if (point1 == point2) { continue; }

                    //calculate delta x and delta y between the two points
                    deltaX = point2.X - point1.X;
                    deltaY = point2.Y - point1.Y;

                    //calculate gradient
                    newGradient = (deltaY / deltaX);

                    if(newGradient != firstGradient)
                    {
                        noOfSides++;
                    }

                }


            gradient = newGradient;
        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...