В чем причина странного поведения метода meshbuilder AddPolygon()?

#c# #wpf #helix-3d-toolkit #helix

#c# #wpf #helix-3d-toolkit #спираль

Вопрос:

Для упорядоченного против часовой стрелки списка точек, подобного этому:

         var points = new[]
        {
            new Point3D(-2, -4, 8), //a
            new Point3D(6,  -1, 8), //b
            new Point3D(6,  5,  8), //c
            new Point3D(0,  8,  8), //d
            new Point3D(1,  3,  8), //e
        }.ToList();
  

Я хочу добавить многоугольник в свой вид HelixViewPort3D:

         var meshBuilder = new MeshBuilder(false, false, false);

        meshBuilder.AddPolygon(points);

        var geometryModel = new GeometryModel3D
        {
            Material = Materials.Red,
            BackMaterial = Materials.Blue,
            Geometry = meshBuilder.ToMesh()
        };
        var modelVisual = new ModelVisual3D { Content = geometryModel };
        view.Children.Add(modelVisual);

        int index = 0;
        foreach (var point in points)
        {
            view.Children.Add(new BillboardTextVisual3D
            {
                DepthOffset = 1e-3,
                Position = point,
                Text = string.Format("[{0}] : {1}, {2}", index  , point.X, point.Y)
            });
        }

        view.ZoomExtents();
  

показывая координаты x и y каждой точки рядом с ними, используя BillboardTextVisual3D, я получаю следующее:
список по умолчанию

что неправильно, каким-то образом d:(0, 8) подключается к a:(-2, -4). и материал обратной стороны (синий) отображается поверх материала лицевой стороны (красный).

однако изменение порядка списка устраняет проблему: упорядоченный список

 var points = new[]
    {
        new Point3D(1,  3,  8), //e
        new Point3D(-2, -4, 8), //a
        new Point3D(6,  -1, 8), //b
        new Point3D(6,  5,  8), //c
        new Point3D(0,  8,  8), //d
    }.ToList();
  

второй список по-прежнему упорядочен против часовой стрелки, единственное отличие — это начальная точка (которая теперь равна e:(1, 3)). есть ли какая-либо причина, по которой это должно повлиять на результат?

P.S. Я думаю, что это должно иметь какое-то отношение к расстоянию между точками до начала координат (0,0,0), начиная с ближайшей точки к началу координат, так или иначе выполняйте задание. это ошибка или я что-то здесь упускаю?

PS # 2 Эта проблема, похоже, возникает только в случае вогнутых многоугольников и не влияет на выпуклые многоугольники.

Ответ №1:

AddPolygon() используйте веер треугольников, когда количество позиций больше 4, поэтому ваш последний треугольник равен:

 -2, -4, 8
0, 8, 8
1, 3, 8
  

Он поворачивается по часовой стрелке, затем задний материал оказывается перед камерой. Это ожидаемое поведение.

Комментарии:

1. спасибо за ответ, я не знал о методе triangle fan, я должен это проверить. но как я должен передать список пользовательских точек в AddPolygon(), чтобы обеспечить правильный результат? это был всего лишь пример, но в реальном приложении я не выбираю точки, которые они импортируют откуда-то еще.

2. Вам нужно использовать AddPolygonByCuttingEars() или AddPolygonByTriangulation() . Используйте свои точки в качестве позиций и создайте список индексов, подобных этому : 0, 1, 2, 3, 4