Беспокойная Рекурсивная Фрактальная Гора

Я пишу код OpenGl для создания фрактальной горы. Я использую рекурсию, и мне тяжело.

Проблема, которую я имею, состоит в разрыве и перекрытии треугольников:
http://imgur.com/DWSuUJH

Проблема в том, что я думал, что решил проблему, вот мой код.

Мой класс Треугольник, vec2 — это просто общий 2-мерный вектор

struct Triangle {
vec2 A, B, C;

Triangle(vec2 a, vec2 b, vec2 c) {
A = a;
B = b;
C = c;
};

Вот моя рекурсивная функция, которая первоначально вызывается с треугольниками вершин (-1, -1), (0, 1) и (1, -1) в объеме просмотра по умолчанию.

 void divide_triangle(const Triangle& baseTriangle, int count) {

if (count > 0) {
std::vector<Triangle> subTriangles = subdivideTriangle(baseTriangle);
for (int i = 0; i < subTriangles.size(); i++) {
divide_triangle(subTriangles[i], count - 1);
}
}

else {
triangle(baseTriangle); // Draw triangle at the end of recursion
}

Это моя функция subDivideTriangles, которая просто делит пройденный треугольник на четыре отдельных треугольника.

std::vector<Triangle> subdivideTriangle(const Triangle& triangle){

vec4 aPrime = getMidpoint(triangle.B, triangle.C);
vec4 bPrime = getMidpoint(triangle.C, triangle.A);
vec4 cPrime = getMidpoint(triangle.A, triangle.B);

return{
{ Triangle(triangle.A, cPrime, bPrime) }, // Top triangle
{ Triangle(cPrime, triangle.B, aPrime) }, // Bottom left triangle
{ Triangle(bPrime, aPrime, triangle.C) }, // Bottom right triangle
{ Triangle(cPrime, aPrime, bPrime) }      // Center triangle
};

И вот функция, которая, как я думал, остановит разрыв, я отслеживаю значения средней точки, соответствующие паре векторов, и, если я найду соответствующую пару векторов, я верну исходную среднюю точку, поэтому не сдвигая среднюю точку дважды.

Тем не менее, этот метод, кажется, не работает, как я думал.

vec4 getMidpoint(const vec4& a, const vec4& b) {

auto AB = std::make_pair(a, b), BA = std::make_pair(b, a);

auto foundResult1 = memo.find(AB);
auto foundResult2 = memo.find(BA);

if (foundResult1 != memo.end())
return memo[AB];

if (foundResult2 != memo.end())
return memo[BA];

auto result = (a + b) / 2;
result += randVector() * getLength(a, b) * randomness;

memo.insert(std::make_pair(AB, result));
memo.insert(std::make_pair(BA, result));

return result;

Ребята, вы понимаете, что-то не так в моей функции средней точки?

-2

Решение

Ваша проблема из соседних краев.

Скажем, у вас есть два треугольника ABC и DBC с общим ребром BC, и вы хотите изменить их, добавив некоторую шумную среднюю точку.

Вы используете две разные точки для середины BC в зависимости от треугольника.

  • Пусть E будет серединой BC, когда вы работаете над ABC, чтобы изменить его.
  • Пусть F будет серединой BC, когда вы работаете над DBC, чтобы изменить его.

E и F должны быть одинаковыми. В противном случае появляется большой разрыв. Это легко видно на вашей картинке.

На мой взгляд, вы должны работать с индексированной вершиной и иметь таблицу (или любой метод), чтобы найти уже существующую середину заданного ребра. то есть: когда дело доходит до вычисления F середины BC в DBC, мы проверяем и обнаруживаем, что оно уже существует как E.

0

Другие решения


По вопросам рекламы [email protected]