none
Создание сферы в WPF RRS feed

Ответы

Все ответы

  • Пример см. тут .
    • Помечено в качестве ответа O .Zhelestcov 1 июня 2010 г. 11:00
    1 июня 2010 г. 10:45
    Модератор
  • Ага, спасибо, я просто к этому моменту уже осилил это дело. Приведу альтернативу к вашему примеру для истории. Координаты текстуры мне совсем не пришлось вычислять, я воспользовался генератором координат текстур из 3DTools.

        /// <summary>
        /// Создает сферу, оттекстуривает её изображением и рисует на Viewport3D
        /// </summary>
        /// <param name="center">Координаты центра сферы</param>
        /// <param name="radius">Радиус сферы</param>
        /// <param name="u">Число строк в массиве точек</param>
        /// <param name="v">Число столбцов в массиве точек</param>
        /// <param name="textureImage">Имя файла изображения, который используется как текстура</param>
        /// <param name="myViewport">Объект Viewport3D, на котором происходит рисование</param>
        public void CreateSphereWithTexture(M3D.Point3D center, double radius, int u, int v, string textureImage, Viewport3D myViewport)
        {
          if (u < 2 || v < 2)
            return;
    
          //Массив, в котором хранятся точки сферы
          M3D.Point3D[,] pts = new M3D.Point3D[u, v];
    
          //Делегат, который вычисляет точки сферы 
          //x = r*sin(Theta)*cos(Phi)
          //y = r*cos(Theta)
          //z = -r*sin(Theta)*cos(Phi)
          Func<double, double, double, M3D.Point3D> GetPos = (CornerRadius, theta, phi) =>
            {
              M3D.Point3D pt = new M3D.Point3D();
              double snt = Math.Sin(theta * Math.PI / 180);
              double cnt = Math.Cos(theta * Math.PI / 180);
              double snp = Math.Sin(phi * Math.PI / 180);
              double cnp = Math.Cos(phi * Math.PI / 180);
              pt.X = radius * snt * cnp;
              pt.Y = radius * cnt;
              pt.Z = -radius * snt * snp;
              return pt;
            };
    
          //Заполняем массив точек сферы
          for (int i = 0; i < u; i++)
          {
            for (int j = 0; j < v; j++)
            {
              pts[i, j] = GetPos(radius, i * 180 / (u - 1), j * 360 / (v - 1));
              pts[i, j] += (M3D.Vector3D)center;
            }
          }
    
          int ncols = (pts.GetUpperBound(1) + 1);
          M3D.MeshGeometry3D mesh = new M3D.MeshGeometry3D();
    
          //Добавляем точки из массива в mesh
          for (int i = 0; i < u; i++)
          {
            for (int j = 0; j < v; j++)
            {
              mesh.Positions.Add(pts[i, j]);
            }
          }
    
          //Устанавливаем правильный!!! набор индексов треугольников в mesh
          for (int i = 0; i < u - 1; i++)
          {
            for (int j = 0; j < v - 1; j++)
            {
              mesh.TriangleIndices.Add(i * ncols + j);
              mesh.TriangleIndices.Add((i + 1) * ncols + j);
              mesh.TriangleIndices.Add((i + 1)* ncols + j + 1);
    
              mesh.TriangleIndices.Add((i + 1) * ncols + j + 1);
              mesh.TriangleIndices.Add(i * ncols + j + 1);
              mesh.TriangleIndices.Add(i * ncols + j);
            }
          }
    
          //!!Метод из библиотеки 3DTools, который автоматически может вычислять координаты текстур для mesh
          mesh.TextureCoordinates = MeshUtils.GenerateSphericalTextureCoordinates(mesh, new M3D.Vector3D(0, 0, 1));
    
          //Текстурируем меш 
          ImageBrush brush = new ImageBrush();
          brush.ImageSource = new BitmapImage(new Uri(textureImage, UriKind.RelativeOrAbsolute));
          M3D.Material material = new M3D.DiffuseMaterial(brush);
          M3D.GeometryModel3D geometry = new M3D.GeometryModel3D(mesh, material);
          M3D.ModelUIElement3D model = new M3D.ModelUIElement3D();
          model.Model = geometry;
    
          //Рисуем модель
          myViewport.Children.Add(model);
        }

    1 июня 2010 г. 11:00