Войти
ПрограммированиеФорумГрафика

Код для генерации плоскости

Страницы: 1 2 Следующая »
#0
21:13, 13 сен. 2013

Доброго времени суток. Выкладываю объемистый кусок кода, который делает плоскость m на n сегментов на плоскости XZ из четыреугольников. Кому интересно, поищите ошибки и просто выскажите мнение. Собирать проект пока не пробовал, не запускал. Старался делать хорошо.

void rPlane::MakePlane( float width, float length, int divW, int divL )
{
  vector<int> adjData(divW * divL);
  int t = 0;
  for (vector<int>::iterator iter = adjData.begin(); iter != adjData.end(); iter++)
  {
    (*iter) = t++;
  }
  float origX = -(width / 2);
  float origZ = -(length / 2);
  float sW = width / (float)divW;
  float sL = length / (float)divL;
  //задать список вершин
  //координата в массиве смежности
  int d = 0;//счетчик вершин
  for (int i = 0; i < divW; i++)//по вертикали
  {
    for (int j = 0; j < divL; j++)//по горизонтали
    {
      pVertices.at(d) = new rVertex();
      pVertices.at(d)->x = origX + (sW * j);
      pVertices.at(d)->y = 0;
      pVertices.at(d)->z = origZ + (sL * i);
      pVertices.at(d)->selWeight = 0;
      d = RightNeighbor(divW  + 1, divL + 1,d);
    }
    d -= divW;
    d = BottomNeighbor(divW + 1, divL + 1, d);
  }
  d = 0;
  int d1 = 0;//счетчик полигонов
  int v0 = 0, v1 = 0, v2 = 0;
  for (int i = 0; i < divW; i++)
  {
    for (int j = 0; j < divL; j++)
    {
      pFaces.at(d1) = new rFace();
      pFaces.at(d1)->verts.push_back(d);
      v0 = RightNeighbor(divW + 1, divL  + 1, d);
      v1 = BottomNeighbor(divW + 1, divL + 1, v0);
      v2 = BottomNeighbor(divW + 1, divL + 1, d);
      pFaces.at(d1)->verts.push_back(v0);
      pFaces.at(d1)->verts.push_back(v1);
      pFaces.at(d1)->verts.push_back(v2);

      d = RightNeighbor(divW + 1, divL + 1, d);
      d1 = RightNeighbor(divW, divL, d1);
    }
    d -= divW;
    d = BottomNeighbor(divW + 1, divL + 1, d);
    d1 -= divW - 1;
    d1 = BottomNeighbor(divW, divL,d1);
  }

  d = 0;
  d1 = 0;
  int d2a = 0;
  for (int i = 0; i < divW; i++)//эти два вложенных цикла задают полигонам левое и правое ребра
  {
    for (int j = 0; j < divL; j++)
    {
      pFaces.at(d1)->edges.resize(4,0);
      if (LeftNeighbor(divW,divL,d1) == -1)
      {
        pEdges.at(d2a) = new rEdge();
        pFaces.at(d1)->edges.at(0) = d2a;
        
        pEdges.at(d2a)->vertA = d;
        pEdges.at(d2a)->vertB = BottomNeighbor(divW + 1, divL + 1,d);
        d2a++;
        pEdges.at(d2a) = new rEdge();
        pFaces.at(d1)->edges.at(2) = d2a;

        int lvert = RightNeighbor(divW + 1, divL + 1, d);
        pEdges.at(d2a)->vertA = lvert;
        pEdges.at(d2a)->vertB = BottomNeighbor(divW + 1, divL + 1, lvert);
        d2a++;        
      }
      else if (RightNeighbor(divW,divL,d1) == -1)
      {
        pEdges.at(d2a) = new rEdge();
        pFaces.at(d1)->edges.at(2) = d2a;
        d2a++;
        int prevEdgeId = pFaces.at(LeftNeighbor(divW,divL,d1))->edges.at(0);
        pFaces.at(d1)->edges.at(0) = prevEdgeId;

        int lvert = RightNeighbor(divW + 1, divL + 1, d);
        pEdges.at(d2a)->vertA = lvert;
        pEdges.at(d2a)->vertB = BottomNeighbor(divW + 1, divL + 1, lvert);
      }
      else 
      {
        int prevEdgeId = pFaces.at(LeftNeighbor(divW,divL,d1))->edges.at(0);
        int nextEdgeId = pFaces.at(RightNeighbor(divW,divL,d1))->edges.at(2);
        pFaces.at(d1)->edges.at(0) = prevEdgeId;
        pFaces.at(d1)->edges.at(2) = nextEdgeId;

        int lvert = RightNeighbor(divW + 1, divL + 1, d);
        pEdges.at(nextEdgeId)->vertA = lvert;
        pEdges.at(nextEdgeId)->vertB = BottomNeighbor(divW + 1, divL + 1,d);
      }
      d = RightNeighbor(divW + 1, divL + 1,d);
      d1 = RightNeighbor(divW,divL,d1);
    }
    d -= divW;
    d = BottomNeighbor(divW + 1, divL + 1,d);
    d1 -= divW - 1;
    d1 = BottomNeighbor(divW,divL,d1);
  }
  d = 0;
  d1 = 0;
  d2a = 0;
  for (int i = 0; i < divW; i++)//эти циклы задают верхнее и нижнее ребра
  {
    for (int j = 0; j < divL; j++)
    {
      if (UpperNeighbor(divW,divL, d1) == -1)
      {
        pEdges.at(d2a) = new rEdge();
        pFaces.at(d1)->edges.at(1) = d2a;
        pEdges.at(d2a)->vertA = d;
        pEdges.at(d2a)->vertB = RightNeighbor(divW + 1, divL + 1,d);
        d2a++;
        pEdges.at(d2a) = new rEdge();
        pFaces.at(d1)->edges.at(3) = d2a;
        int bvert = BottomNeighbor(divW + 1,divL + 1,d);
        pEdges.at(d2a)->vertA = bvert;
        pEdges.at(d2a)->vertB = RightNeighbor(divW + 1, divL + 1, bvert);
        d2a++;
      }
      else if (BottomNeighbor(divW,divL,d1) == -1)
      {
        pEdges.at(d2a) = new rEdge();
        pFaces.at(d1)->edges.at(3) = d2a;
        int bvert = BottomNeighbor(divW + 1, divL + 1, d);
        pEdges.at(d2a)->vertA = bvert;
        pEdges.at(d2a)->vertB = RightNeighbor(divW + 1, divL + 1,bvert);
        d2a++;
        int prevEdgeId = pFaces.at(UpperNeighbor(divW,divL,d1))->edges.at(3);
        pFaces.at(d1)->edges.at(1) = prevEdgeId;
      }
      else
      {
        int prevEdgeId = pFaces.at(UpperNeighbor(divW,divL,d1))->edges.at(3);
        int nextEdgeId = pFaces.at(BottomNeighbor(divW,divL,d1))->edges.at(1);
        pFaces.at(d1)->edges.at(1) = prevEdgeId;
        pFaces.at(d1)->edges.at(3) = nextEdgeId;
        int bvert = BottomNeighbor(divW + 1, divL + 1,d);
        pEdges.at(nextEdgeId)->vertA = bvert;
        pEdges.at(nextEdgeId)->vertB = RightNeighbor(divW + 1, divL + 1, bvert);
      }
      d1 = BottomNeighbor(divW,divL,d1);
    }
    d1 -= divW * (divL - 1);
    d1 = RightNeighbor(divW,divL,d1);
  }
  d = 0;
  d1 = 0;
  d2a = 0;
  for (int i = 0; i < divW; i++)
  {
    for (int j = 0; j < divL; j++)
    {
      bool cond0 =  (LeftNeighbor(divW,divL,d1) == -1);
      bool cond1 = (UpperNeighbor(divW,divL,d1) == -1);
      bool cond2 = (RightNeighbor(divW,divL,d1) == -1);
      bool cond3 = (BottomNeighbor(divW,divL,d1) == -1);

      if (!cond0)//есть полигон слева
      {
        int e0 = pFaces.at(d1)->edges.at(0);
        int ae0 = pFaces.at(LeftNeighbor(divW,divL,d1))->edges.at(3);
        pEdges.at(e0)->adjEdgesA.push_back(ae0);
        int ae1 = pFaces.at(LeftNeighbor(divW,divL,d1))->edges.at(1);
        pEdges.at(e0)->adjEdgesB.push_back(ae1);

        int eprev = pFaces.at(d1)->edges.at(3);
        pEdges.at(eprev)->adjEdgesB.push_back(ae0);
        int enext = pFaces.at(d1)->edges.at(1);
        pEdges.at(enext)->adjEdgesA.push_back(ae1);
      }
      if (!cond1)//есть полигон сверху
      {
        int e0 = pFaces.at(d1)->edges.at(1);
        int ae0 = pFaces.at(UpperNeighbor(divW,divL,d1))->edges.at(0);
        pEdges.at(e0)->adjEdgesA.push_back(ae0);
        int ae1 = pFaces.at(UpperNeighbor(divW,divL,d1))->edges.at(2);
        pEdges.at(e0)->adjEdgesB.push_back(ae1);

        int eprev = pFaces.at(d1)->edges.at(0);
        pEdges.at(eprev)->adjEdgesB.push_back(ae0);
        int enext = pFaces.at(d1)->edges.at(2);
        pEdges.at(enext)->adjEdgesA.push_back(ae1);
      }
      if (!cond2)//есть полигон справа
      {
        int e0 = pFaces.at(d1)->edges.at(2);
        int ae0 = pFaces.at(RightNeighbor(divW,divL,d1))->edges.at(1);
        pEdges.at(e0)->adjEdgesA.push_back(ae0);
        int ae1 = pFaces.at(RightNeighbor(divW,divL,d1))->edges.at(3);
        pEdges.at(e0)->adjEdgesB.push_back(ae1);

        int eprev = pFaces.at(d1)->edges.at(1);
        pEdges.at(eprev)->adjEdgesB.push_back(ae0);
        int enext = pFaces.at(d1)->edges.at(3);
        pEdges.at(enext)->adjEdgesA.push_back(ae1);
      }
      if (!cond3)//есть полигон снизу
      {
        int e0 = pFaces.at(d1)->edges.at(3);
        int ae0 = pFaces.at(BottomNeighbor(divW,divL,d1))->edges.at(2);
        pEdges.at(e0)->adjEdgesA.push_back(ae0);
        int ae1 = pFaces.at(BottomNeighbor(divW,divL,d1))->edges.at(0);
        pEdges.at(e0)->adjEdgesB.push_back(ae1);

        int eprev = pFaces.at(d1)->edges.at(2);
        pEdges.at(eprev)->adjEdgesB.push_back(ae0);
        int enext = pFaces.at(d1)->edges.at(0);
        pEdges.at(enext)->adjEdgesA.push_back(ae1);
      }
      d1 = RightNeighbor(divW,divL,d1);
    }
    d1 -= divW - 1;
    d1 = BottomNeighbor(divW,divL,d1);
  }
}
В заголовочном файле:
struct rVertex
{
  int id;//постоянный номер
  float x,y,z;//позиция в пространстве
  float nx,ny,nz;//нормаль
  float selWeight;//интенсивность выделения
  list<int> adjEdgesId;//список сопряженных ребер
  list<int> UVW_Verts;//ссылка на UVW вершины
};
struct rEdge
{
  int id;//номер ребра
  int vertA, vertB;//номера вершин
  int faceA, faceB;//номера сопряженных полигонов
  list<int> adjEdgesA;//сопряженные ребра
  list<int> adjEdgesB;//сопряженные ребра с другой стороны
  float selWeight;//интенсивность выделения
  list<int> UVW_Edges;//ссылка на UVW ребра
};
struct rFace
{
  int id;//номер полигона
  list<int> verts;//номера вершин
  vector<int> edges;//номера ребер
  float selWeight;//интенсивность выделения
  list<Triangle*> tris;//треугольники для визуализации
};


#1
21:14, 13 сен. 2013

TheOrca
Честно говоря, мне лень читать...

#2
22:17, 13 сен. 2013

TheOrca
> Старался делать хорошо.
Старайся лучше.

#3
22:33, 13 сен. 2013

Мне даже в первый момент почудилось, что код на делфи.

#4
22:51, 13 сен. 2013

Chipmunk,а чем делфи не нравится?

#5
22:51, 13 сен. 2013

> Выкладываю объемистый кусок кода
TheOrca, при таком объёме кода - он должен генерить картинку уровня CryEngine3 как минимум, а не плоскость вовсе )))

> Кому интересно
TheOrca, мне нет )

> поищите ошибки и просто выскажите мнение.
Чем больше код - тем больше ошибок. А код у тебя явно в разы превышает то, что необходимо для достижения результата.

З.Ы. Для чего это вообще?

#6
14:03, 14 сен. 2013

Код генерации плоскости с прямоугольниками (чаще квадратами или двумя треугольниками) содержит: функция генерации прямоугольников или треугольников, два вложенных цикла, вывод указателя на массив содеянного. Что делают в коде 12 (двенадцать) конструкций цикла и 8 (восемь) условных операторов?

#7
14:28, 14 сен. 2013

Должны искаться смежные вершины, ребра и грани. Я еще не все сделал.

#8
15:21, 14 сен. 2013

Стена говнокода

Зачем в данном случае итератор?

int t = 0;
  for (vector<int>::iterator iter = adjData.begin(); iter != adjData.end(); iter++)
  {
    (*iter) = t++;
  }

Аргументы конструктора для слабых?

      pVertices.at(d) = new rVertex();
      pVertices.at(d)->x = origX + (sW * j);
      pVertices.at(d)->y = 0;
      pVertices.at(d)->z = origZ + (sL * i);
      pVertices.at(d)->selWeight = 0;

Код просмотрел но не читал.

#9
15:26, 14 сен. 2013

Alexsan9999
> Chipmunk,а чем делфи не нравится?
А я не писал, о том, что мне нравится или не нравится. =)

#10
15:29, 14 сен. 2013

TheOrca
> Собирать проект пока не пробовал, не запускал.
Принеси ягненка в жертву Страуструпу перед компиляцией)

#11
15:33, 14 сен. 2013

А что так много буков? Понять эти вычисления сложнее, чем написать их

#12
15:42, 14 сен. 2013

Mr.TyanVary
> Зачем в данном случае итератор?
А что он плохого делает?
Лучше итератор, чем цикл. Все равно надо массив наполнить возрастающими значениями.

Mr.TyanVary
> Аргументы конструктора для слабых?
Я знаю, что есть конструктор. Он выходит слишком длинным. И это вопрос стиля.
Izaron
> Принеси ягненка в жертву Страуструпу перед компиляцией)
Увидел уже пару ошибок. Думаю, все соберется без особых проблем.
Izaron
> А что так много буков? Понять эти вычисления сложнее, чем написать их
Комментариев нет? Картинки нет? Мне при наличии картинки, где все вершины, ребра, грани пронумерованы, понять не очень сложно.

#13
15:52, 14 сен. 2013

TheOrca
> Он выходит слишком длинным
То есть пять строк кода вместо одной - не длинно?

#14
16:01, 14 сен. 2013

Так, поясняю. Существует std::vector структур rVertex, rEdge, rFace. Полигоны обходятся слева направо, сверху вниз(или спереди назад, к экрану).
У каждого полигона ребра и вершины нумеруются от 0 до 3. Слева сверху(или слева сзади) первая вершина или ребро.
1. Строится список смежности - массив m на n. Заполняется возрастающими значениями. По нему потом буду ориентироваться функциями
LeftNeighbor и прочими. Neighbor по-русски - сосед.  Функция возвращает -1, если соседа нет.
2. Итерации по списку смежности для вершин слева направо сверху вниз. Назначаются координаты. В конце итерации ухожу в начало строки, потом на следующую.
3. Итерации по списку смежности для полигонов слева направо сверху вниз. Каждому полигону задаются вершины.
4. Итерируются полигоны по строкам. Каждому назначается левое и правое ребра. Ребра, вершины, полигоны задаются явно. Есть ситуации, когда имеется сосед слева, справа или такового нет. В зависимости от этого нужно или создать заново оба ребра, или взять одно из предыдущего полигона.
5. Аналогично итерируются полигоны по столбцам сверху вниз. Каждому полигону назначаются верхнее и нижнее ребра, плюс смежность. Смежные ребра указываются для начала и конца каждого ребра, с информацией из предыдущего и следующего полигона по часовой стрелке. Есть четыре условия, потому что может не существовать левый, правый, верхний и нижний полигоны на краях плоскости. Если существуют, то использовать их.
Все вкратце объяснил. Понятно? Нужно еще указать для ребер смежные полигоны, но это потом.

Страницы: 1 2 Следующая »
ПрограммированиеФорумГрафика

Тема в архиве.